From 9244eacb5ab0b9a11480d1ad40d4720575676877 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Tue, 17 Jan 2017 20:14:45 -0600 Subject: nqasm: parse labels --- lexer.l | 5 +++++ nqasm.c | 43 +++++++++++++++++++++++++++++++++++++++++++ nqasm.h | 1 + parser.y | 13 +++++++++++-- vector.c | 37 +++++++++++++++++++++++++++++++++++++ vector.h | 13 +++++++++++++ 6 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 vector.c create mode 100644 vector.h diff --git a/lexer.l b/lexer.l index 85021c5..28aa7fe 100644 --- a/lexer.l +++ b/lexer.l @@ -2,10 +2,12 @@ #include #include +#include #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] %% {SP}+ { BEGIN(inst); return T_SPACE; } +{LABEL} { SETSTR(yytext); return T_LABEL; } +:{SP}* { BEGIN(inst); return T_COLON; } add/{EOI} { BEGIN(args); return T_ADD; } sub/{EOI} { BEGIN(args); return T_SUB; } diff --git a/nqasm.c b/nqasm.c index ed49a48..138407e 100644 --- a/nqasm.c +++ b/nqasm.c @@ -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; } diff --git a/nqasm.h b/nqasm.h index d25911b..232c41b 100644 --- a/nqasm.h +++ b/nqasm.h @@ -17,6 +17,7 @@ struct instruction { }; void add_instruction(const struct instruction *); +void add_label(const char *); #endif diff --git a/parser.y b/parser.y index 76748de..1f4f5bd 100644 --- a/parser.y +++ b/parser.y @@ -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 T_LABEL %token T_INT %token T_BADINT %token T_REG %token T_REGPTR + %token T_COMMA "," +%token T_COLON ":" %type inst %type 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 +#include +#include + +#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 + +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 -- cgit v1.2.3