summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lexer.l5
-rw-r--r--nqasm.c43
-rw-r--r--nqasm.h1
-rw-r--r--parser.y13
-rw-r--r--vector.c37
-rw-r--r--vector.h13
6 files changed, 110 insertions, 2 deletions
diff --git a/lexer.l b/lexer.l
index 85021c5..28aa7fe 100644
--- a/lexer.l
+++ b/lexer.l
@@ -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; }
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 <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