Browse Source

Support parsing labels; add checks for label length.

master
Ben Kurtovic 9 years ago
parent
commit
145322071d
8 changed files with 43 additions and 17 deletions
  1. +1
    -0
      src/assembler/errors.c
  2. +1
    -0
      src/assembler/errors.h
  3. +5
    -1
      src/assembler/inst_args.h
  4. +11
    -16
      src/assembler/instructions.c
  5. +20
    -0
      src/assembler/parse_util.c
  6. +1
    -0
      src/assembler/parse_util.h
  7. +1
    -0
      src/assembler/state.h
  8. +3
    -0
      src/assembler/tokenizer.c

+ 1
- 0
src/assembler/errors.c View File

@@ -42,6 +42,7 @@ static const char *error_descs[] = {

[ED_SYM_DUPE_LABELS] = "duplicate definitions for label",
[ED_SYM_NO_LABEL] = "undefined reference to label",
[ED_SYM_TOO_LONG] = "label name is too long",
[ED_SYM_IS_REGISTER] = "labels cannot share names with registers",
[ED_SYM_IS_CONDITION] = "labels cannot share names with condition codes",



+ 1
- 0
src/assembler/errors.h View File

@@ -41,6 +41,7 @@ typedef enum {

ED_SYM_DUPE_LABELS,
ED_SYM_NO_LABEL,
ED_SYM_TOO_LONG,
ED_SYM_IS_REGISTER,
ED_SYM_IS_CONDITION,



+ 5
- 1
src/assembler/inst_args.h View File

@@ -5,6 +5,8 @@

#include <stdint.h>

#include "state.h"

typedef enum {
AT_REGISTER,
AT_IMMEDIATE,
@@ -50,7 +52,9 @@ typedef struct {
int8_t offset;
} ASMArgIndexed;

typedef char* ASMArgLabel;
typedef struct {
char text[MAX_SYMBOL_SIZE];
} ASMArgLabel;

typedef enum {
COND_NZ, COND_N, COND_NC, COND_C, COND_PO, COND_PE, COND_P, COND_M


+ 11
- 16
src/assembler/instructions.c View File

@@ -143,28 +143,24 @@ static uint8_t fill_bytes_variadic(uint8_t *bytes, size_t len, ...)

Return ED_NONE (0) on success or an error code on failure.
*/
static ASMErrorDesc parse_arg(
ASMInstArg *arg, const char *str, size_t size, char **symbol)
static ASMErrorDesc parse_arg(ASMInstArg *arg, const char *str, size_t size)
{
#define USE_PARSER(func, argtype, field) \
#define TRY_PARSER(func, argtype, field) \
if (argparse_##func(&arg->data.field, str, size)) { \
arg->type = argtype; \
return ED_NONE; \
}

DEBUG("parse_arg(): -->%.*s<-- %zu", (int) size, str, size)
USE_PARSER(register, AT_REGISTER, reg)
USE_PARSER(immediate, AT_IMMEDIATE, imm)
USE_PARSER(indirect, AT_INDIRECT, indirect)
USE_PARSER(indexed, AT_INDEXED, index)
USE_PARSER(condition, AT_CONDITION, cond)

// AT_LABEL
// ASMArgLabel label;

TRY_PARSER(register, AT_REGISTER, reg)
TRY_PARSER(immediate, AT_IMMEDIATE, imm)
TRY_PARSER(indirect, AT_INDIRECT, indirect)
TRY_PARSER(indexed, AT_INDEXED, index)
TRY_PARSER(condition, AT_CONDITION, cond)
TRY_PARSER(label, AT_LABEL, label)
return ED_PS_ARG_SYNTAX;

#undef USE_PARSER
#undef TRY_PARSER
}

/*
@@ -176,7 +172,6 @@ static ASMErrorDesc parse_args(
ASMInstArg args[3], size_t *nargs, const char *str, size_t size)
{
ASMErrorDesc err;
static char *symbol = NULL;
size_t start = 0, i = 0;

while (i < size) {
@@ -184,7 +179,7 @@ static ASMErrorDesc parse_args(
if (c == ',') {
if (i == start)
return ED_PS_ARG_SYNTAX;
if ((err = parse_arg(&args[*nargs], str + start, i - start, &symbol)))
if ((err = parse_arg(&args[*nargs], str + start, i - start)))
return err;
(*nargs)++;

@@ -207,7 +202,7 @@ static ASMErrorDesc parse_args(
}

if (i > start) {
if ((err = parse_arg(&args[*nargs], str + start, i - start, &symbol)))
if ((err = parse_arg(&args[*nargs], str + start, i - start)))
return err;
(*nargs)++;
}


+ 20
- 0
src/assembler/parse_util.c View File

@@ -412,6 +412,26 @@ bool argparse_indexed(ASMArgIndexed *result, const char *arg, ssize_t size)
}

/*
Read in a label argument and store it in *result.
*/
bool argparse_label(ASMArgLabel *result, const char *arg, ssize_t size)
{
if (size >= MAX_SYMBOL_SIZE)
return false;

for (const char *i = arg; i < arg + size; i++) {
char c = *i;
if (!((c >= 'a' && c <= 'z') || (i != arg && c >= '0' && c <= '9') ||
c == '_' || c == '.'))
return false;
}

strncpy(result->text, arg, size);
result->text[size] = '\0';
return true;
}

/*
Read in a boolean argument from the given line and store it in *result.
*/
DIRECTIVE_PARSE_FUNC(bool, bool)


+ 1
- 0
src/assembler/parse_util.h View File

@@ -25,6 +25,7 @@ bool argparse_condition(ASMArgCondition*, const char*, ssize_t);
bool argparse_immediate(ASMArgImmediate*, const char*, ssize_t);
bool argparse_indirect(ASMArgIndirect*, const char*, ssize_t);
bool argparse_indexed(ASMArgIndexed*, const char*, ssize_t);
bool argparse_label(ASMArgLabel*, const char*, ssize_t);

/* Preprocessor directive parsers */
bool dparse_bool(bool*, const ASMLine*, const char*);


+ 1
- 0
src/assembler/state.h View File

@@ -13,6 +13,7 @@
#define DEFAULT_REGION 6 // GG Export
#define DEFAULT_DECLSIZE 0xC // 32 KB

#define MAX_SYMBOL_SIZE 256
#define SYMBOL_TABLE_BUCKETS 128

/* Structs */


+ 3
- 0
src/assembler/tokenizer.c View File

@@ -62,6 +62,9 @@ static inline int8_t default_bank_slot(uint8_t bank)
static ErrorInfo* add_label_to_table(
ASMSymbolTable *symtable, const ASMLine *line, size_t offset, int8_t slot)
{
if (line->length - 1 >= MAX_SYMBOL_SIZE)
return error_info_create(line, ET_SYMBOL, ED_SYM_TOO_LONG);

ASMArgRegister reg;
if (argparse_register(&reg, line->data, line->length - 1))
return error_info_create(line, ET_SYMBOL, ED_SYM_IS_REGISTER);


Loading…
Cancel
Save