diff options
author | Bobby Bingham <koorogi@koorogi.info> | 2017-01-17 20:14:45 -0600 |
---|---|---|
committer | Bobby Bingham <koorogi@koorogi.info> | 2017-01-17 23:00:52 -0600 |
commit | 9244eacb5ab0b9a11480d1ad40d4720575676877 (patch) | |
tree | c49c20b4c693c6676d49f35b6c1217131dd4c0da | |
parent | bb7ae08ee638cf9b88a69ca89c5b6b12401c37f5 (diff) |
nqasm: parse labels
-rw-r--r-- | lexer.l | 5 | ||||
-rw-r--r-- | nqasm.c | 43 | ||||
-rw-r--r-- | nqasm.h | 1 | ||||
-rw-r--r-- | parser.y | 13 | ||||
-rw-r--r-- | vector.c | 37 | ||||
-rw-r--r-- | vector.h | 13 |
6 files changed, 110 insertions, 2 deletions
@@ -2,10 +2,12 @@ #include <errno.h> #include <stdlib.h> +#include <string.h> #include "parser.h" #define SETVALUE(v) yylval.arg = (struct argument) { .value = (v) } +#define SETSTR(s) yylval.str = strdup(s) static int intlit(const char *s, int base, long *out) { @@ -22,6 +24,7 @@ static int intlit(const char *s, int base, long *out) %s inst %s args +LABEL [_a-zA-Z][_a-zA-Z0-9]* COMMENT #[^\n]* SP [ \t] EOI [ \t\n#] @@ -32,6 +35,8 @@ HEX [0-9a-f] %% <INITIAL>{SP}+ { BEGIN(inst); return T_SPACE; } +<INITIAL>{LABEL} { SETSTR(yytext); return T_LABEL; } +<INITIAL>:{SP}* { BEGIN(inst); return T_COLON; } <inst>add/{EOI} { BEGIN(args); return T_ADD; } <inst>sub/{EOI} { BEGIN(args); return T_SUB; } @@ -6,6 +6,32 @@ #include "lexer.h" #include "parser.h" +#include "vector.h" + +struct label { + const char *name; + uint16_t addr; +}; + +static struct labels { + struct vector v; + struct label l[]; +} *labels; + +uint16_t addr; + +static int labels_init(void) +{ + return !(labels = vector_init(8, sizeof labels->l[0], sizeof *labels)); +} + +static struct label *labels_append(void) +{ + struct vector *v = &labels->v; + struct label *l = vector_append(&v); + labels = (struct labels *)v; + return l; +} void add_instruction(const struct instruction *inst) { @@ -19,10 +45,27 @@ void add_instruction(const struct instruction *inst) } printf("%04x\n", bits); + addr += 2; +} + +void add_label(const char *name) +{ + struct label *l = labels_append(); + if (!l) { + fprintf(stderr, "unable to allocate label\n"); + exit(1); + } + + *l = (struct label) { + .name = name, + .addr = addr + }; } int main(int argc, char **argv) { + labels_init(); + yyparse(); return 0; } @@ -17,6 +17,7 @@ struct instruction { }; void add_instruction(const struct instruction *); +void add_label(const char *); #endif @@ -29,6 +29,7 @@ void yyerror(const char *msg) struct arguments args; struct argument arg; long lval; + char *str; } %token END 0 "end of file" @@ -72,12 +73,15 @@ void yyerror(const char *msg) %token T_ADDPC %token T_NOP +%token <str> T_LABEL %token <lval> T_INT %token T_BADINT %token <arg> T_REG %token <arg> T_REGPTR + %token T_COMMA "," +%token T_COLON ":" %type <inst> inst %type <arg> imm @@ -98,11 +102,16 @@ input: line | input line ; -line: T_SPACE inst eol - { add_instruction(&$2); } +line: + bol inst eol { add_instruction(&$2); } | eol ; +bol: + T_SPACE + | T_LABEL ":" { add_label($1); } + ; + inst: T_ADD a_reg3 { $$ = INSTRUCTION_ARGS(ADD, $2); } | T_SUB a_reg3 { $$ = INSTRUCTION_ARGS(SUB, $2); } diff --git a/vector.c b/vector.c new file mode 100644 index 0000000..57f62d7 --- /dev/null +++ b/vector.c @@ -0,0 +1,37 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#include "vector.h" + +#define VECTOR_TOOBIG(alloc,elemsize,arrayoff) ((SIZE_MAX - (arrayoff)) / (alloc) < (elemsize)) +#define VECTOR_ALLOCSIZE(alloc,elemsize,arrayoff) ((arrayoff) + (alloc) * (elemsize)) + +void *vector_init(size_t alloc, size_t elemsize, size_t arrayoff) +{ + if (VECTOR_TOOBIG(alloc, elemsize, arrayoff)) return NULL; + struct vector *v = malloc(VECTOR_ALLOCSIZE(alloc, elemsize, arrayoff)); + if (!v) return NULL; + + *v = (struct vector) { + .alloc = alloc, + .elemsize = elemsize, + .arrayoff = arrayoff, + }; + return v; +} + +void *vector_append(struct vector **vp) +{ + struct vector *v = *vp; + if (v->count >= v->alloc) { + size_t alloc = 2 * v->alloc; + if (VECTOR_TOOBIG(alloc, v->elemsize, v->arrayoff)) return NULL; + v = realloc(v, VECTOR_ALLOCSIZE(alloc, v->elemsize, v->arrayoff)); + if (!v) return NULL; + v->alloc = alloc; + *vp = v; + } + return (char*)v + v->arrayoff + v->count++ * v->elemsize; +} + diff --git a/vector.h b/vector.h new file mode 100644 index 0000000..fb32da7 --- /dev/null +++ b/vector.h @@ -0,0 +1,13 @@ +#ifndef NQ_VECTOR_H +#define NQ_VECTOR_H + +#include <stddef.h> + +struct vector { + size_t alloc, count, elemsize, arrayoff; +}; + +void *vector_init(size_t alloc, size_t elemsize, size_t arrayoff); +void *vector_append(struct vector **vp); + +#endif |