Browse Source

Support string arguments to .rom_size, .rom_declsize.

master
Ben Kurtovic 9 years ago
parent
commit
0fe98bd048
3 changed files with 68 additions and 47 deletions
  1. +57
    -39
      src/assembler/parse_util.c
  2. +5
    -5
      src/assembler/parse_util.h
  3. +6
    -3
      src/assembler/preprocessor.c

+ 57
- 39
src/assembler/parse_util.c View File

@@ -10,13 +10,20 @@

#define MAX_REGION_SIZE 32

#define PARSE_FUNC_HEADER(name, type) \
bool parse_##name(type *result, const ASMLine *line, const char *directive)

/*
Read in a boolean argument from the given line and store it in *result.
All public functions in this file follow the same return conventions:

- Return true on success and false on failure.
- *result is only modified on success.
*/

Return true on success and false on failure; in the latter case, *result is
not modified.
/*
Read in a boolean argument from the given line and store it in *result.
*/
bool parse_bool(bool *result, const ASMLine *line, const char *directive)
PARSE_FUNC_HEADER(bool, bool)
{
size_t offset = DIRECTIVE_OFFSET(line, directive) + 1;
const char *arg = line->data + offset;
@@ -52,15 +59,11 @@ bool parse_bool(bool *result, const ASMLine *line, const char *directive)

/*
Read in a 32-bit int argument from the given line and store it in *result.

Return true on success and false on failure; in the latter case, *result is
not modified.
*/
bool parse_uint32_t(uint32_t *result, const ASMLine *line, const char *directive)
PARSE_FUNC_HEADER(uint32_t, uint32_t)
{
size_t offset = DIRECTIVE_OFFSET(line, directive) + 1;
const char *str = line->data + offset;
const char *end = str + line->length - offset;
const char *str = line->data + DIRECTIVE_OFFSET(line, directive) + 1;
const char *end = line->data + line->length;

if (end - str <= 0)
return false;
@@ -100,11 +103,8 @@ bool parse_uint32_t(uint32_t *result, const ASMLine *line, const char *directive

/*
Read in a 16-bit int argument from the given line and store it in *result.

Return true on success and false on failure; in the latter case, *result is
not modified.
*/
bool parse_uint16_t(uint16_t *result, const ASMLine *line, const char *directive)
PARSE_FUNC_HEADER(uint16_t, uint16_t)
{
uint32_t value;
if (parse_uint32_t(&value, line, directive) && value <= UINT16_MAX)
@@ -114,11 +114,8 @@ bool parse_uint16_t(uint16_t *result, const ASMLine *line, const char *directive

/*
Read in an 8-bit int argument from the given line and store it in *result.

Return true on success and false on failure; in the latter case, *result is
not modified.
*/
bool parse_uint8_t(uint8_t *result, const ASMLine *line, const char *directive)
PARSE_FUNC_HEADER(uint8_t, uint8_t)
{
uint32_t value;
if (parse_uint32_t(&value, line, directive) && value <= UINT8_MAX)
@@ -128,32 +125,54 @@ bool parse_uint8_t(uint8_t *result, const ASMLine *line, const char *directive)

/*
Parse a ROM size string in an ASMLine and store it in *result.

Return true on success and false on failure; in the latter case, *result is
not modified.
*/
bool parse_rom_size(uint32_t *result, const ASMLine *line)
PARSE_FUNC_HEADER(rom_size, uint32_t)
{
uint32_t bytes;
if (!parse_uint32_t(&bytes, line, DIR_ROM_SIZE))
const char *arg = line->data + DIRECTIVE_OFFSET(line, directive) + 1;
const char *end = line->data + line->length - 1;

if (end - arg < 5)
return false;
if (*(arg++) != '"' || *(end--) != '"')
return false;
if (*end != 'B' && *end != 'b')
return false;
end--;

uint32_t factor;
if (*end == 'K' || *end == 'k')
factor = 1 << 10;
else if (*end == 'M' || *end == 'm')
factor = 1 << 20;
else
return false;
end--;

if (size_bytes_to_code(bytes))
return (*result = bytes), true;
return false;
if (*end != ' ')
return false;

uint32_t value = 0;
while (arg < end) {
if (*arg < '0' || *arg > '9')
return false;
value = (value * 10) + (*arg - '0');
if (value > UINT16_MAX)
return false;
arg++;
}

*result = value * factor;
return true;
}

/*
Parse a region code string in an ASMLine and store it in *result.

Return true on success and false on failure; in the latter case, *result is
not modified.
*/
bool parse_region_string(uint8_t *result, const ASMLine *line)
PARSE_FUNC_HEADER(region_string, uint8_t)
{
char buffer[MAX_REGION_SIZE];

size_t offset = DIRECTIVE_OFFSET(line, DIR_ROM_REGION) + 1;
size_t offset = DIRECTIVE_OFFSET(line, directive) + 1;
const char *arg = line->data + offset;
ssize_t len = line->length - offset;

@@ -173,15 +192,14 @@ bool parse_region_string(uint8_t *result, const ASMLine *line)

/*
Parse a size code in an ASMLine and store it in *result.

Return true on success and false on failure; in the latter case, *result is
not modified.
*/
bool parse_size_code(uint8_t *result, const ASMLine *line)
PARSE_FUNC_HEADER(size_code, uint8_t)
{
uint32_t bytes;
if (!parse_uint32_t(&bytes, line, DIR_ROM_DECLSIZE))
return false;
if (!parse_uint32_t(&bytes, line, directive)) {
if (!parse_rom_size(&bytes, line, directive))
return false;
}

uint8_t code = size_bytes_to_code(bytes);
if (code)


+ 5
- 5
src/assembler/parse_util.h View File

@@ -8,15 +8,15 @@

#include "state.h"

#define parse__Bool parse_bool
#define parse_bool parse__Bool

/* Functions */

bool parse_bool(bool*, const ASMLine*, const char*);
bool parse__Bool(bool*, const ASMLine*, const char*);
bool parse_uint32_t(uint32_t*, const ASMLine*, const char*);
bool parse_uint16_t(uint16_t*, const ASMLine*, const char*);
bool parse_uint8_t(uint8_t*, const ASMLine*, const char*);

bool parse_rom_size(uint32_t*, const ASMLine*);
bool parse_region_string(uint8_t*, const ASMLine*);
bool parse_size_code(uint8_t*, const ASMLine*);
bool parse_rom_size(uint32_t*, const ASMLine*, const char*);
bool parse_region_string(uint8_t*, const ASMLine*, const char*);
bool parse_size_code(uint8_t*, const ASMLine*, const char*);

+ 6
- 3
src/assembler/preprocessor.c View File

@@ -29,7 +29,7 @@
parse_##arg_type((arg_type*) &arg, line, directive)

#define CALL_SPECIFIC_PARSER_(arg_type, parser) \
parse_##parser((arg_type*) &arg, line)
parse_##parser((arg_type*) &arg, line, directive)

#define DISPATCH_(first, second, target, ...) target

@@ -57,7 +57,7 @@
else if (first_ctr++, IS_DIRECTIVE(line, d)) { \
directive = d; \
FAIL_ON_COND_(!DIRECTIVE_HAS_ARG(line, directive), ED_PP_NO_ARG) \
arg_type arg; \
arg_type arg = 0; \
arg_type* dest = &(dest_loc); \
if (DIRECTIVE_IS_AUTO(line, directive)) { \
arg = auto_val; \
@@ -360,7 +360,10 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
END_DIRECTIVE

BEGIN_DIRECTIVE(DIR_ROM_SIZE, size_t, state->rom_size, 0)
USE_PARSER(uint32_t, rom_size)
PARSER_BRANCH(uint32_t, {}, {
USE_PARSER(uint32_t, rom_size)
})
VALIDATE(size_bytes_to_code)
END_DIRECTIVE

BEGIN_DIRECTIVE(DIR_ROM_HEADER, size_t, state->header.offset, DEFAULT_HEADER_OFFSET)


Loading…
Cancel
Save