aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2021-04-20 16:09:00 +0200
committerMarvin Borner2021-04-20 16:09:00 +0200
commitfbf9cfee0d22a2750b894c2ddb19dff2a50810b4 (patch)
tree035f30ad32e4302c32b8c6a6641f017747e36f0b
parent2415600bb755885154072f28a86d784b32567920 (diff)
All right
-rw-r--r--Makefile2
-rw-r--r--src/inc/lexer.h25
-rw-r--r--src/inc/warnings.h7
-rw-r--r--src/lexer.c174
-rw-r--r--src/parser.c574
-rw-r--r--src/warnings.c9
6 files changed, 415 insertions, 376 deletions
diff --git a/Makefile b/Makefile
index b33f360..566465c 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ OBJS = $(patsubst $(SOURCEDIR)/%.c, $(BUILDDIR)/%.o, $(SOURCES))
CC = gcc
WARNINGS = -Wall -Wextra -Wshadow -Wpointer-arith -Wwrite-strings -Wredundant-decls -Wnested-externs -Wformat=2 -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wswitch-default -Wswitch-enum -Wlogical-op -Wunreachable-code -Wundef -Wold-style-definition -Wvla -pedantic
-CFLAGS = -Ofast $(WARNINGS) -I$(SOURCEDIR)/inc/ $(shell pkg-config --cflags --libs gtk+-3.0) -fsanitize=undefined
+CFLAGS = -Ofast $(WARNINGS) -I$(SOURCEDIR)/inc/ $(shell pkg-config --cflags --libs gtk+-3.0) -fsanitize=undefined #-fsanitize=address
all: $(OBJS)
@$(CC) -o ./$(BUILDDIR)/out $^ $(CFLAGS)
diff --git a/src/inc/lexer.h b/src/inc/lexer.h
index 82d533c..afc3a0a 100644
--- a/src/inc/lexer.h
+++ b/src/inc/lexer.h
@@ -6,6 +6,8 @@
enum token_type {
UNKNOWN,
NEWLINE,
+ SPACE,
+
NOP,
JBC,
JB,
@@ -57,6 +59,29 @@ enum token_type {
DB,
DW,
INCLUDE,
+
+ HASH,
+ DOLLAR,
+ SLASH,
+ PLUS,
+ COMMA,
+ DOT,
+ COLON,
+ SEMICOLON,
+
+ DEC_NUM,
+ HEX_NUM,
+ BIN_NUM,
+
+ ACCU,
+ R0,
+ R1,
+ R2,
+ R3,
+ R4,
+ R5,
+ R6,
+ R7,
};
struct token {
diff --git a/src/inc/warnings.h b/src/inc/warnings.h
index 495b2e2..f8c06bb 100644
--- a/src/inc/warnings.h
+++ b/src/inc/warnings.h
@@ -3,8 +3,13 @@
#include <def.h>
+struct context {
+ u32 line;
+ u32 column;
+};
+
void warnings_print(void);
-void warnings_add(u32 line, const char *fmt, ...);
+void warnings_add(struct context *ctx, const char *fmt, ...);
void warnings_clear(void);
u8 warnings_exist(void);
diff --git a/src/lexer.c b/src/lexer.c
index ecbc613..6e2cd94 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -3,7 +3,13 @@
#include <stdio.h>
#include <string.h>
-#define CMP(tok) (strncmp(tok " ", str, MIN(strlen(tok) + 1, size)) == 0)
+#define ALPHA(a) (((a) >= 'a' && (a) <= 'z') || ((a) >= 'A' && (a) <= 'Z'))
+#define NUMERIC(a) ((a) >= '0' && (a) <= '9')
+
+#define CMPSP(tok) (strncmp(tok " ", str, MIN(strlen(tok) + 1, size)) == 0) // CMP with space at end
+#define CMPNA(tok) \
+ (strncmp(tok, str, MIN(strlen(tok), size)) == 0 && \
+ !ALPHA(str[strlen(tok)])) // CMP with non alpha at end
void token_print(struct token *tok)
{
@@ -12,7 +18,7 @@ void token_print(struct token *tok)
char swp = tok->start[tok->length];
tok->start[tok->length] = 0;
- printf("%s\n", tok->start);
+ printf("%s (%d)\n", tok->start, tok->type);
tok->start[tok->length] = swp;
}
@@ -22,157 +28,219 @@ struct token token_resolve(char *str, u32 size)
u32 length = 0;
// "Beautiful" ~ Everyone. Probably.
- if (CMP("nop")) {
+ if (NUMERIC(str[0]) && !ALPHA(str[1])) {
+ while (NUMERIC(str[length++]))
+ ;
+ length--;
+ type = DEC_NUM;
+ } else if (str[0] == '\n') {
+ type = NEWLINE;
+ length = 1;
+ } else if (str[0] == ' ') {
+ type = SPACE;
+ length = 1;
+ } else if (str[0] == ',') {
+ type = COMMA;
+ length = 1;
+ } else if (str[0] == '$') {
+ type = DOLLAR;
+ length = 1;
+ } else if (str[0] == '/') {
+ type = SLASH;
+ length = 1;
+ } else if (str[0] == '+') {
+ type = PLUS;
+ length = 1;
+ } else if (str[0] == '.') {
+ type = DOT;
+ length = 1;
+ } else if (str[0] == ':') {
+ type = COLON;
+ length = 1;
+ } else if (str[0] == ';') {
+ type = SEMICOLON;
+ length = 1;
+ } else if (str[0] == '#') {
+ type = HASH;
+ length = 1;
+ } else if (str[0] == 'A' && !ALPHA(str[1])) {
+ type = ACCU;
+ length = 1;
+ } else if (CMPNA("R0")) {
+ type = R0;
+ length = 2;
+ } else if (CMPNA("R1")) {
+ type = R1;
+ length = 2;
+ } else if (CMPNA("R2")) {
+ type = R2;
+ length = 2;
+ } else if (CMPNA("R3")) {
+ type = R3;
+ length = 2;
+ } else if (CMPNA("R4")) {
+ type = R4;
+ length = 2;
+ } else if (CMPNA("R5")) {
+ type = R5;
+ length = 2;
+ } else if (CMPNA("R6")) {
+ type = R6;
+ length = 2;
+ } else if (CMPNA("R7")) {
+ type = R7;
+ length = 2;
+ } else if (CMPSP("nop")) {
type = NOP;
length = 3;
- } else if (CMP("jbc")) {
+ } else if (CMPSP("jbc")) {
type = JBC;
length = 3;
- } else if (CMP("jb")) {
+ } else if (CMPSP("jb")) {
type = JB;
length = 2;
- } else if (CMP("jnb")) {
+ } else if (CMPSP("jnb")) {
type = JNB;
length = 3;
- } else if (CMP("jc")) {
+ } else if (CMPSP("jc")) {
type = JC;
length = 2;
- } else if (CMP("jnc")) {
+ } else if (CMPSP("jnc")) {
type = JNC;
length = 3;
- } else if (CMP("jz")) {
+ } else if (CMPSP("jz")) {
type = JZ;
length = 2;
- } else if (CMP("jnz")) {
+ } else if (CMPSP("jnz")) {
type = JNZ;
length = 3;
- } else if (CMP("sjmp")) {
+ } else if (CMPSP("sjmp")) {
type = SJMP;
length = 4;
- } else if (CMP("mov")) {
+ } else if (CMPSP("mov")) {
type = MOV;
length = 3;
- } else if (CMP("orl")) {
+ } else if (CMPSP("orl")) {
type = ORL;
length = 3;
- } else if (CMP("anl")) {
+ } else if (CMPSP("anl")) {
type = ANL;
length = 3;
- } else if (CMP("push")) {
+ } else if (CMPSP("push")) {
type = PUSH;
length = 4;
- } else if (CMP("pop")) {
+ } else if (CMPSP("pop")) {
type = POP;
length = 3;
- } else if (CMP("movx")) {
+ } else if (CMPSP("movx")) {
type = MOVX;
length = 4;
- } else if (CMP("ajmp")) {
+ } else if (CMPSP("ajmp")) {
type = AJMP;
length = 4;
- } else if (CMP("acall")) {
+ } else if (CMPSP("acall")) {
type = ACALL;
length = 5;
- } else if (CMP("ljmp")) {
+ } else if (CMPSP("ljmp")) {
type = LJMP;
length = 4;
- } else if (CMP("lcall")) {
+ } else if (CMPSP("lcall")) {
type = LCALL;
length = 5;
- } else if (CMP("reti")) {
+ } else if (CMPSP("reti")) {
type = RETI;
length = 4;
- } else if (CMP("ret")) {
+ } else if (CMPSP("ret")) {
type = RET;
length = 3;
- } else if (CMP("xrl")) {
+ } else if (CMPSP("xrl")) {
type = XRL;
length = 3;
- } else if (CMP("cpl")) {
+ } else if (CMPSP("cpl")) {
type = CPL;
length = 3;
- } else if (CMP("clr")) {
+ } else if (CMPSP("clr")) {
type = CLR;
length = 3;
- } else if (CMP("setb")) {
+ } else if (CMPSP("setb")) {
type = SETB;
length = 4;
- } else if (CMP("rr")) {
+ } else if (CMPSP("rr")) {
type = RR;
length = 2;
- } else if (CMP("rrc")) {
+ } else if (CMPSP("rrc")) {
type = RRC;
length = 3;
- } else if (CMP("rl")) {
+ } else if (CMPSP("rl")) {
type = RL;
length = 2;
- } else if (CMP("rlc")) {
+ } else if (CMPSP("rlc")) {
type = RLC;
length = 3;
- } else if (CMP("xlr")) {
+ } else if (CMPSP("xlr")) {
type = XLR;
length = 3;
- } else if (CMP("jmp")) {
+ } else if (CMPSP("jmp")) {
type = JMP;
length = 3;
- } else if (CMP("movc")) {
+ } else if (CMPSP("movc")) {
type = MOVC;
length = 4;
- } else if (CMP("inc")) {
+ } else if (CMPSP("inc")) {
type = INC;
length = 3;
- } else if (CMP("dec")) {
+ } else if (CMPSP("dec")) {
type = DEC;
length = 3;
- } else if (CMP("add")) {
+ } else if (CMPSP("add")) {
type = ADD;
length = 3;
- } else if (CMP("addc")) {
+ } else if (CMPSP("addc")) {
type = ADDC;
length = 4;
- } else if (CMP("div")) {
+ } else if (CMPSP("div")) {
type = DIV;
length = 3;
- } else if (CMP("dubb")) {
+ } else if (CMPSP("dubb")) {
type = DUBB;
length = 4;
- } else if (CMP("mul")) {
+ } else if (CMPSP("mul")) {
type = MUL;
length = 3;
- } else if (CMP("cjne")) {
+ } else if (CMPSP("cjne")) {
type = CJNE;
length = 4;
- } else if (CMP("swap")) {
+ } else if (CMPSP("swap")) {
type = SWAP;
length = 4;
- } else if (CMP("da")) {
+ } else if (CMPSP("da")) {
type = DA;
length = 2;
- } else if (CMP("crl")) {
+ } else if (CMPSP("crl")) {
type = CRL;
length = 3;
- } else if (CMP("xch")) {
+ } else if (CMPSP("xch")) {
type = XCH;
length = 3;
- } else if (CMP("djnz")) {
+ } else if (CMPSP("djnz")) {
type = DJNZ;
length = 4;
- } else if (CMP("xchd")) {
+ } else if (CMPSP("xchd")) {
type = XCHD;
length = 4;
- } else if (CMP("call")) {
+ } else if (CMPSP("call")) {
type = CALL;
length = 4;
- } else if (CMP("org")) {
+ } else if (CMPSP("org")) {
type = ORG;
length = 3;
- } else if (CMP("db")) {
+ } else if (CMPSP("db")) {
type = DB;
length = 2;
- } else if (CMP("dw")) {
+ } else if (CMPSP("dw")) {
type = DW;
length = 2;
- } else if (CMP("include")) {
+ } else if (CMPSP("include")) {
type = INCLUDE;
length = 7;
}
diff --git a/src/parser.c b/src/parser.c
index 7cc23e5..1698638 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1,3 +1,4 @@
+#include <assert.h>
#include <def.h>
#include <lexer.h>
#include <parser.h>
@@ -27,587 +28,523 @@ static void rom_add(u8 byte)
* Main parsing
*/
-static u32 parse_nop(u32 line, char *str, u32 size)
+static inline u32 toks_count(struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
+ struct token *p = toks;
+ while (p && p->type)
+ p++;
+ return p - toks;
+}
+
+static void parse_nop(struct context *ctx, struct token *toks)
+{
+ UNUSED(ctx);
+ UNUSED(toks);
rom_add(0);
- return 0;
}
-static u32 parse_jbc(u32 line, char *str, u32 size)
+static void parse_jbc(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_jb(u32 line, char *str, u32 size)
+static void parse_jb(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_jnb(u32 line, char *str, u32 size)
+static void parse_jnb(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_jc(u32 line, char *str, u32 size)
+static void parse_jc(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_jnc(u32 line, char *str, u32 size)
+static void parse_jnc(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_jz(u32 line, char *str, u32 size)
+static void parse_jz(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_jnz(u32 line, char *str, u32 size)
+static void parse_jnz(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_sjmp(u32 line, char *str, u32 size)
+static void parse_sjmp(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_mov(u32 line, char *str, u32 size)
+static void parse_mov(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ printf("CNT: %d\n", toks_count(toks));
+ /* if (toks_count(toks) > 4) */
+ /* warnings_add(ctx, "Too many arguments"); */
}
-static u32 parse_orl(u32 line, char *str, u32 size)
+static void parse_orl(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_anl(u32 line, char *str, u32 size)
+static void parse_anl(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_push(u32 line, char *str, u32 size)
+static void parse_push(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_pop(u32 line, char *str, u32 size)
+static void parse_pop(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_movx(u32 line, char *str, u32 size)
+static void parse_movx(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_ajmp(u32 line, char *str, u32 size)
+static void parse_ajmp(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_acall(u32 line, char *str, u32 size)
+static void parse_acall(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_ljmp(u32 line, char *str, u32 size)
+static void parse_ljmp(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_lcall(u32 line, char *str, u32 size)
+static void parse_lcall(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_reti(u32 line, char *str, u32 size)
+static void parse_reti(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_ret(u32 line, char *str, u32 size)
+static void parse_ret(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_xrl(u32 line, char *str, u32 size)
+static void parse_xrl(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_cpl(u32 line, char *str, u32 size)
+static void parse_cpl(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_clr(u32 line, char *str, u32 size)
+static void parse_clr(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_setb(u32 line, char *str, u32 size)
+static void parse_setb(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_rr(u32 line, char *str, u32 size)
+static void parse_rr(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_rrc(u32 line, char *str, u32 size)
+static void parse_rrc(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_rl(u32 line, char *str, u32 size)
+static void parse_rl(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_rlc(u32 line, char *str, u32 size)
+static void parse_rlc(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_xlr(u32 line, char *str, u32 size)
+static void parse_xlr(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_jmp(u32 line, char *str, u32 size)
+static void parse_jmp(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_movc(u32 line, char *str, u32 size)
+static void parse_movc(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_inc(u32 line, char *str, u32 size)
+static void parse_inc(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_dec(u32 line, char *str, u32 size)
+static void parse_dec(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_add(u32 line, char *str, u32 size)
+static void parse_add(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_addc(u32 line, char *str, u32 size)
+static void parse_addc(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_div(u32 line, char *str, u32 size)
+static void parse_div(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_dubb(u32 line, char *str, u32 size)
+static void parse_dubb(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_mul(u32 line, char *str, u32 size)
+static void parse_mul(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_cjne(u32 line, char *str, u32 size)
+static void parse_cjne(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_swap(u32 line, char *str, u32 size)
+static void parse_swap(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_da(u32 line, char *str, u32 size)
+static void parse_da(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_crl(u32 line, char *str, u32 size)
+static void parse_crl(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_xch(u32 line, char *str, u32 size)
+static void parse_xch(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_djnz(u32 line, char *str, u32 size)
+static void parse_djnz(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_xchd(u32 line, char *str, u32 size)
+static void parse_xchd(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_call(u32 line, char *str, u32 size)
+static void parse_call(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_org(u32 line, char *str, u32 size)
+static void parse_org(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_db(u32 line, char *str, u32 size)
+static void parse_db(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_dw(u32 line, char *str, u32 size)
+static void parse_dw(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_include(u32 line, char *str, u32 size)
+static void parse_include(struct context *ctx, struct token *toks)
{
- UNUSED(line);
- UNUSED(str);
- UNUSED(size);
- return 0;
+ UNUSED(ctx);
+ UNUSED(toks);
}
-static u32 parse_instruction(u32 line, char *str, u32 size)
+static u32 parse_instruction(struct context *ctx, char *str, u32 size)
{
- struct token tok = token_resolve(str, size);
+ struct token toks[32] = { 0 };
+ u8 tok_ind = 0;
+ u8 str_ind = 0;
- token_print(&tok);
+ while (1) {
+ struct token tok = token_resolve(str + str_ind, size - str_ind);
+ if (tok.type == NEWLINE) {
+ ctx->line++;
+ break;
+ }
- u32 ret = tok.length;
+ if (tok.type == UNKNOWN) {
+ break;
+ }
+
+ if (tok.type == SPACE) {
+ str_ind += tok.length;
+ continue;
+ }
+
+ token_print(&tok);
+
+ assert(tok_ind + 1 < (u8)(sizeof(toks) / sizeof(toks[0])));
+ toks[tok_ind++] = tok;
+ str_ind += tok.length;
+ }
+
+ ctx->column = str_ind;
+
+ if (!tok_ind) {
+ warnings_add(ctx, "Parsing failed");
+ return 0;
+ }
- switch (tok.type) {
+ switch (toks[0].type) {
case UNKNOWN:
- warnings_add(line, "Unknown instruction");
+ warnings_add(ctx, "Unknown instruction");
return 0;
case NEWLINE:
break;
case NOP:
- ret += parse_nop(line, str, size);
+ parse_nop(ctx, toks);
break;
case JBC:
- ret += parse_jbc(line, str, size);
+ parse_jbc(ctx, toks);
break;
case JB:
- ret += parse_jb(line, str, size);
+ parse_jb(ctx, toks);
break;
case JNB:
- ret += parse_jnb(line, str, size);
+ parse_jnb(ctx, toks);
break;
case JC:
- ret += parse_jc(line, str, size);
+ parse_jc(ctx, toks);
break;
case JNC:
- ret += parse_jnc(line, str, size);
+ parse_jnc(ctx, toks);
break;
case JZ:
- ret += parse_jz(line, str, size);
+ parse_jz(ctx, toks);
break;
case JNZ:
- ret += parse_jnz(line, str, size);
+ parse_jnz(ctx, toks);
break;
case SJMP:
- ret += parse_sjmp(line, str, size);
+ parse_sjmp(ctx, toks);
break;
case MOV:
- ret += parse_mov(line, str, size);
+ parse_mov(ctx, toks);
break;
case ORL:
- ret += parse_orl(line, str, size);
+ parse_orl(ctx, toks);
break;
case ANL:
- ret += parse_anl(line, str, size);
+ parse_anl(ctx, toks);
break;
case PUSH:
- ret += parse_push(line, str, size);
+ parse_push(ctx, toks);
break;
case POP:
- ret += parse_pop(line, str, size);
+ parse_pop(ctx, toks);
break;
case MOVX:
- ret += parse_movx(line, str, size);
+ parse_movx(ctx, toks);
break;
case AJMP:
- ret += parse_ajmp(line, str, size);
+ parse_ajmp(ctx, toks);
break;
case ACALL:
- ret += parse_acall(line, str, size);
+ parse_acall(ctx, toks);
break;
case LJMP:
- ret += parse_ljmp(line, str, size);
+ parse_ljmp(ctx, toks);
break;
case LCALL:
- ret += parse_lcall(line, str, size);
+ parse_lcall(ctx, toks);
break;
case RETI:
- ret += parse_reti(line, str, size);
+ parse_reti(ctx, toks);
break;
case RET:
- ret += parse_ret(line, str, size);
+ parse_ret(ctx, toks);
break;
case XRL:
- ret += parse_xrl(line, str, size);
+ parse_xrl(ctx, toks);
break;
case CPL:
- ret += parse_cpl(line, str, size);
+ parse_cpl(ctx, toks);
break;
case CLR:
- ret += parse_clr(line, str, size);
+ parse_clr(ctx, toks);
break;
case SETB:
- ret += parse_setb(line, str, size);
+ parse_setb(ctx, toks);
break;
case RR:
- ret += parse_rr(line, str, size);
+ parse_rr(ctx, toks);
break;
case RRC:
- ret += parse_rrc(line, str, size);
+ parse_rrc(ctx, toks);
break;
case RL:
- ret += parse_rl(line, str, size);
+ parse_rl(ctx, toks);
break;
case RLC:
- ret += parse_rlc(line, str, size);
+ parse_rlc(ctx, toks);
break;
case XLR:
- ret += parse_xlr(line, str, size);
+ parse_xlr(ctx, toks);
break;
case JMP:
- ret += parse_jmp(line, str, size);
+ parse_jmp(ctx, toks);
break;
case MOVC:
- ret += parse_movc(line, str, size);
+ parse_movc(ctx, toks);
break;
case INC:
- ret += parse_inc(line, str, size);
+ parse_inc(ctx, toks);
break;
case DEC:
- ret += parse_dec(line, str, size);
+ parse_dec(ctx, toks);
break;
case ADD:
- ret += parse_add(line, str, size);
+ parse_add(ctx, toks);
break;
case ADDC:
- ret += parse_addc(line, str, size);
+ parse_addc(ctx, toks);
break;
case DIV:
- ret += parse_div(line, str, size);
+ parse_div(ctx, toks);
break;
case DUBB:
- ret += parse_dubb(line, str, size);
+ parse_dubb(ctx, toks);
break;
case MUL:
- ret += parse_mul(line, str, size);
+ parse_mul(ctx, toks);
break;
case CJNE:
- ret += parse_cjne(line, str, size);
+ parse_cjne(ctx, toks);
break;
case SWAP:
- ret += parse_swap(line, str, size);
+ parse_swap(ctx, toks);
break;
case DA:
- ret += parse_da(line, str, size);
+ parse_da(ctx, toks);
break;
case CRL:
- ret += parse_crl(line, str, size);
+ parse_crl(ctx, toks);
break;
case XCH:
- ret += parse_xch(line, str, size);
+ parse_xch(ctx, toks);
break;
case DJNZ:
- ret += parse_djnz(line, str, size);
+ parse_djnz(ctx, toks);
break;
case XCHD:
- ret += parse_xchd(line, str, size);
+ parse_xchd(ctx, toks);
break;
case CALL:
- ret += parse_call(line, str, size);
+ parse_call(ctx, toks);
break;
case ORG:
- ret += parse_org(line, str, size);
+ parse_org(ctx, toks);
break;
case DB:
- ret += parse_db(line, str, size);
+ parse_db(ctx, toks);
break;
case DW:
- ret += parse_dw(line, str, size);
+ parse_dw(ctx, toks);
break;
case INCLUDE:
- ret += parse_include(line, str, size);
+ parse_include(ctx, toks);
break;
default:
- warnings_add(line, "Super-unknown instruction");
+ warnings_add(ctx, "Super-unknown instruction");
}
- return ret;
+ return str_ind;
}
static void clean_buffers(void)
@@ -621,18 +558,21 @@ u8 parse(char *buf, u32 size)
{
clean_buffers();
- u32 line = 0;
+ struct context ctx = { .line = 0, .column = 0 };
for (u32 i = 0; i < size; i++) {
if (buf[i] == '\0')
break;
if (buf[i] == '\n') {
- line++;
+ ctx.line++;
+ ctx.column = 0;
continue;
}
- i += parse_instruction(line, buf + i, size - i);
+ u32 len = parse_instruction(&ctx, buf + i, size - i);
+ i += len;
+ ctx.column += len;
}
if (warnings_exist()) {
diff --git a/src/warnings.c b/src/warnings.c
index fd11264..d9c7be6 100644
--- a/src/warnings.c
+++ b/src/warnings.c
@@ -11,18 +11,18 @@
struct warning {
u8 exists;
- u32 line;
+ struct context *ctx;
char text[WARNING_LENGTH];
};
static struct warning warnings[WARNING_COUNT] = { 0 };
static u32 warning_index = 0;
-void warnings_add(u32 line, const char *fmt, ...)
+void warnings_add(struct context *ctx, const char *fmt, ...)
{
assert(warning_index + 1 < WARNING_COUNT);
warnings[warning_index].exists = 1;
- warnings[warning_index].line = line;
+ warnings[warning_index].ctx = ctx;
va_list ap;
va_start(ap, fmt);
@@ -40,7 +40,8 @@ void warnings_print(void)
continue;
/* gui_show_warning(warnings[i].text); */
- printf("Line %d: %s\n", warnings[i].line, warnings[i].text);
+ printf("Line %d:%d: %s\n", warnings[i].ctx->line, warnings[i].ctx->column,
+ warnings[i].text);
}
}