diff options
author | Marvin Borner | 2021-04-20 00:54:43 +0200 |
---|---|---|
committer | Marvin Borner | 2021-04-20 00:54:43 +0200 |
commit | aac2dae5cfcd360ad48f265910511c98decbf9e7 (patch) | |
tree | 45b7d421d2ff3d3db390f0c7fd969e4d8a58cd65 | |
parent | 3ecfdb1064f7c4f45f53c415a77803ce2153d04d (diff) |
Beautiful blub blabs
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/inc/def.h | 2 | ||||
-rw-r--r-- | src/inc/lexer.h | 20 | ||||
-rw-r--r-- | src/inc/parser.h | 4 | ||||
-rw-r--r-- | src/inc/warnings.h | 11 | ||||
-rw-r--r-- | src/lexer.c | 188 | ||||
-rw-r--r-- | src/parser.c | 624 | ||||
-rw-r--r-- | src/warnings.c | 56 |
8 files changed, 896 insertions, 11 deletions
@@ -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 = -O3 $(WARNINGS) -I$(SOURCEDIR)/inc/ $(shell pkg-config --cflags --libs gtk+-3.0) +CFLAGS = -Ofast $(WARNINGS) -I$(SOURCEDIR)/inc/ $(shell pkg-config --cflags --libs gtk+-3.0) -fsanitize=undefined all: $(OBJS) @$(CC) -o ./$(BUILDDIR)/out $^ $(CFLAGS) diff --git a/src/inc/def.h b/src/inc/def.h index bd06eb9..22e1bda 100644 --- a/src/inc/def.h +++ b/src/inc/def.h @@ -10,5 +10,7 @@ typedef signed short s16; typedef signed char s8; #define UNUSED(bla) ((void)(bla)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif diff --git a/src/inc/lexer.h b/src/inc/lexer.h index 833e522..82d533c 100644 --- a/src/inc/lexer.h +++ b/src/inc/lexer.h @@ -1,7 +1,9 @@ #ifndef LEXER_H #define LEXER_H -enum token { +#include <def.h> + +enum token_type { UNKNOWN, NEWLINE, NOP, @@ -44,7 +46,7 @@ enum token { DUBB, MUL, CJNE, - SWP, + SWAP, DA, CRL, XCH, @@ -55,10 +57,16 @@ enum token { DB, DW, INCLUDE, - BRACE_OPEN, - BRACE_CLOSE, - DATA, - BIT, }; +struct token { + enum token_type type; + char *start; + u32 length; + void *data; +}; + +void token_print(struct token *tok); +struct token token_resolve(char *token, u32 size); + #endif diff --git a/src/inc/parser.h b/src/inc/parser.h index c46ead1..0c59681 100644 --- a/src/inc/parser.h +++ b/src/inc/parser.h @@ -1,5 +1,5 @@ -#ifndef LEXER_H -#define LEXER_H +#ifndef PARSER_H +#define PARSER_H #include <def.h> diff --git a/src/inc/warnings.h b/src/inc/warnings.h new file mode 100644 index 0000000..495b2e2 --- /dev/null +++ b/src/inc/warnings.h @@ -0,0 +1,11 @@ +#ifndef WARNINGS_H +#define WARNINGS_H + +#include <def.h> + +void warnings_print(void); +void warnings_add(u32 line, const char *fmt, ...); +void warnings_clear(void); +u8 warnings_exist(void); + +#endif diff --git a/src/lexer.c b/src/lexer.c new file mode 100644 index 0000000..ecbc613 --- /dev/null +++ b/src/lexer.c @@ -0,0 +1,188 @@ +#include <def.h> +#include <lexer.h> +#include <stdio.h> +#include <string.h> + +#define CMP(tok) (strncmp(tok " ", str, MIN(strlen(tok) + 1, size)) == 0) + +void token_print(struct token *tok) +{ + if (!tok->length) + return; + + char swp = tok->start[tok->length]; + tok->start[tok->length] = 0; + printf("%s\n", tok->start); + tok->start[tok->length] = swp; +} + +struct token token_resolve(char *str, u32 size) +{ + enum token_type type = UNKNOWN; + u32 length = 0; + + // "Beautiful" ~ Everyone. Probably. + if (CMP("nop")) { + type = NOP; + length = 3; + } else if (CMP("jbc")) { + type = JBC; + length = 3; + } else if (CMP("jb")) { + type = JB; + length = 2; + } else if (CMP("jnb")) { + type = JNB; + length = 3; + } else if (CMP("jc")) { + type = JC; + length = 2; + } else if (CMP("jnc")) { + type = JNC; + length = 3; + } else if (CMP("jz")) { + type = JZ; + length = 2; + } else if (CMP("jnz")) { + type = JNZ; + length = 3; + } else if (CMP("sjmp")) { + type = SJMP; + length = 4; + } else if (CMP("mov")) { + type = MOV; + length = 3; + } else if (CMP("orl")) { + type = ORL; + length = 3; + } else if (CMP("anl")) { + type = ANL; + length = 3; + } else if (CMP("push")) { + type = PUSH; + length = 4; + } else if (CMP("pop")) { + type = POP; + length = 3; + } else if (CMP("movx")) { + type = MOVX; + length = 4; + } else if (CMP("ajmp")) { + type = AJMP; + length = 4; + } else if (CMP("acall")) { + type = ACALL; + length = 5; + } else if (CMP("ljmp")) { + type = LJMP; + length = 4; + } else if (CMP("lcall")) { + type = LCALL; + length = 5; + } else if (CMP("reti")) { + type = RETI; + length = 4; + } else if (CMP("ret")) { + type = RET; + length = 3; + } else if (CMP("xrl")) { + type = XRL; + length = 3; + } else if (CMP("cpl")) { + type = CPL; + length = 3; + } else if (CMP("clr")) { + type = CLR; + length = 3; + } else if (CMP("setb")) { + type = SETB; + length = 4; + } else if (CMP("rr")) { + type = RR; + length = 2; + } else if (CMP("rrc")) { + type = RRC; + length = 3; + } else if (CMP("rl")) { + type = RL; + length = 2; + } else if (CMP("rlc")) { + type = RLC; + length = 3; + } else if (CMP("xlr")) { + type = XLR; + length = 3; + } else if (CMP("jmp")) { + type = JMP; + length = 3; + } else if (CMP("movc")) { + type = MOVC; + length = 4; + } else if (CMP("inc")) { + type = INC; + length = 3; + } else if (CMP("dec")) { + type = DEC; + length = 3; + } else if (CMP("add")) { + type = ADD; + length = 3; + } else if (CMP("addc")) { + type = ADDC; + length = 4; + } else if (CMP("div")) { + type = DIV; + length = 3; + } else if (CMP("dubb")) { + type = DUBB; + length = 4; + } else if (CMP("mul")) { + type = MUL; + length = 3; + } else if (CMP("cjne")) { + type = CJNE; + length = 4; + } else if (CMP("swap")) { + type = SWAP; + length = 4; + } else if (CMP("da")) { + type = DA; + length = 2; + } else if (CMP("crl")) { + type = CRL; + length = 3; + } else if (CMP("xch")) { + type = XCH; + length = 3; + } else if (CMP("djnz")) { + type = DJNZ; + length = 4; + } else if (CMP("xchd")) { + type = XCHD; + length = 4; + } else if (CMP("call")) { + type = CALL; + length = 4; + } else if (CMP("org")) { + type = ORG; + length = 3; + } else if (CMP("db")) { + type = DB; + length = 2; + } else if (CMP("dw")) { + type = DW; + length = 2; + } else if (CMP("include")) { + type = INCLUDE; + length = 7; + } + + struct token tok = { + .type = type, + .start = str, + .length = length, + .data = 0, + }; + + return tok; +} diff --git a/src/parser.c b/src/parser.c index e4d0251..7cc23e5 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,16 +1,629 @@ #include <def.h> +#include <lexer.h> #include <parser.h> #include <stdio.h> #include <string.h> +#include <warnings.h> -#define PEEK(hay, needle) (strcmp(hay, needle) == 0) +/** + * Definitions + */ + +#define ROM_SIZE 4096 // TODO: Actual ROM size? + +/** + * ROM blub blabs + */ + +static u8 rom[ROM_SIZE] = { 0 }; +static u32 rom_index = 0; +static void rom_add(u8 byte) +{ + rom[rom_index] = byte; + rom_index++; +} + +/** + * Main parsing + */ + +static u32 parse_nop(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + rom_add(0); + return 0; +} + +static u32 parse_jbc(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_jb(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_jnb(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_jc(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_jnc(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_jz(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_jnz(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_sjmp(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_mov(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_orl(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_anl(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_push(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_pop(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_movx(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_ajmp(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_acall(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_ljmp(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_lcall(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_reti(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_ret(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_xrl(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_cpl(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_clr(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_setb(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_rr(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_rrc(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_rl(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_rlc(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_xlr(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_jmp(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_movc(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_inc(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_dec(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_add(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_addc(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_div(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_dubb(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_mul(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_cjne(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_swap(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_da(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_crl(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_xch(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_djnz(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_xchd(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_call(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_org(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_db(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_dw(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_include(u32 line, char *str, u32 size) +{ + UNUSED(line); + UNUSED(str); + UNUSED(size); + return 0; +} + +static u32 parse_instruction(u32 line, char *str, u32 size) +{ + struct token tok = token_resolve(str, size); + + token_print(&tok); + + u32 ret = tok.length; + + switch (tok.type) { + case UNKNOWN: + warnings_add(line, "Unknown instruction"); + return 0; + case NEWLINE: + break; + case NOP: + ret += parse_nop(line, str, size); + break; + case JBC: + ret += parse_jbc(line, str, size); + break; + case JB: + ret += parse_jb(line, str, size); + break; + case JNB: + ret += parse_jnb(line, str, size); + break; + case JC: + ret += parse_jc(line, str, size); + break; + case JNC: + ret += parse_jnc(line, str, size); + break; + case JZ: + ret += parse_jz(line, str, size); + break; + case JNZ: + ret += parse_jnz(line, str, size); + break; + case SJMP: + ret += parse_sjmp(line, str, size); + break; + case MOV: + ret += parse_mov(line, str, size); + break; + case ORL: + ret += parse_orl(line, str, size); + break; + case ANL: + ret += parse_anl(line, str, size); + break; + case PUSH: + ret += parse_push(line, str, size); + break; + case POP: + ret += parse_pop(line, str, size); + break; + case MOVX: + ret += parse_movx(line, str, size); + break; + case AJMP: + ret += parse_ajmp(line, str, size); + break; + case ACALL: + ret += parse_acall(line, str, size); + break; + case LJMP: + ret += parse_ljmp(line, str, size); + break; + case LCALL: + ret += parse_lcall(line, str, size); + break; + case RETI: + ret += parse_reti(line, str, size); + break; + case RET: + ret += parse_ret(line, str, size); + break; + case XRL: + ret += parse_xrl(line, str, size); + break; + case CPL: + ret += parse_cpl(line, str, size); + break; + case CLR: + ret += parse_clr(line, str, size); + break; + case SETB: + ret += parse_setb(line, str, size); + break; + case RR: + ret += parse_rr(line, str, size); + break; + case RRC: + ret += parse_rrc(line, str, size); + break; + case RL: + ret += parse_rl(line, str, size); + break; + case RLC: + ret += parse_rlc(line, str, size); + break; + case XLR: + ret += parse_xlr(line, str, size); + break; + case JMP: + ret += parse_jmp(line, str, size); + break; + case MOVC: + ret += parse_movc(line, str, size); + break; + case INC: + ret += parse_inc(line, str, size); + break; + case DEC: + ret += parse_dec(line, str, size); + break; + case ADD: + ret += parse_add(line, str, size); + break; + case ADDC: + ret += parse_addc(line, str, size); + break; + case DIV: + ret += parse_div(line, str, size); + break; + case DUBB: + ret += parse_dubb(line, str, size); + break; + case MUL: + ret += parse_mul(line, str, size); + break; + case CJNE: + ret += parse_cjne(line, str, size); + break; + case SWAP: + ret += parse_swap(line, str, size); + break; + case DA: + ret += parse_da(line, str, size); + break; + case CRL: + ret += parse_crl(line, str, size); + break; + case XCH: + ret += parse_xch(line, str, size); + break; + case DJNZ: + ret += parse_djnz(line, str, size); + break; + case XCHD: + ret += parse_xchd(line, str, size); + break; + case CALL: + ret += parse_call(line, str, size); + break; + case ORG: + ret += parse_org(line, str, size); + break; + case DB: + ret += parse_db(line, str, size); + break; + case DW: + ret += parse_dw(line, str, size); + break; + case INCLUDE: + ret += parse_include(line, str, size); + break; + default: + warnings_add(line, "Super-unknown instruction"); + } + + return ret; +} + +static void clean_buffers(void) +{ + if (rom_index) + memset(rom, 0, sizeof(rom)); + warnings_clear(); +} u8 parse(char *buf, u32 size) { + clean_buffers(); + u32 line = 0; for (u32 i = 0; i < size; i++) { - /* printf("'%c'\n", buf[i]); */ if (buf[i] == '\0') break; @@ -18,6 +631,13 @@ u8 parse(char *buf, u32 size) line++; continue; } + + i += parse_instruction(line, buf + i, size - i); + } + + if (warnings_exist()) { + warnings_print(); + return 0; } return 1; diff --git a/src/warnings.c b/src/warnings.c new file mode 100644 index 0000000..fd11264 --- /dev/null +++ b/src/warnings.c @@ -0,0 +1,56 @@ +#include <assert.h> +#include <def.h> +#include <gui.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <warnings.h> + +#define WARNING_COUNT 1024 // Well, something went horribly wrong I guess +#define WARNING_LENGTH 64 + +struct warning { + u8 exists; + u32 line; + char text[WARNING_LENGTH]; +}; + +static struct warning warnings[WARNING_COUNT] = { 0 }; +static u32 warning_index = 0; +void warnings_add(u32 line, const char *fmt, ...) +{ + assert(warning_index + 1 < WARNING_COUNT); + + warnings[warning_index].exists = 1; + warnings[warning_index].line = line; + + va_list ap; + va_start(ap, fmt); + vsnprintf(warnings[warning_index].text, WARNING_LENGTH, fmt, ap); + va_end(ap); + + warning_index++; +} + +// TODO: Print somewhere else (e.g. next to line) +void warnings_print(void) +{ + for (u32 i = 0; i < WARNING_COUNT; i++) { + if (!warnings[i].exists) + continue; + + /* gui_show_warning(warnings[i].text); */ + printf("Line %d: %s\n", warnings[i].line, warnings[i].text); + } +} + +u8 warnings_exist(void) +{ + return warning_index > 0; +} + +void warnings_clear(void) +{ + if (warning_index) + memset(warnings, 0, sizeof(warnings)); +} |