From 8e9ab93151757bb8a1bbfcab9c09598247d63f06 Mon Sep 17 00:00:00 2001 From: zongor Date: Sun, 1 Feb 2026 23:47:34 -0800 Subject: [PATCH] hardcoded string implementation --- arch/linux/tui/main.c | 10 ++++-- tools/compiler/compiler.c | 76 +++++++++++++++++++++++++++++++-------- vm/vm.c | 13 +++---- vm/vm.h | 1 + 4 files changed, 76 insertions(+), 24 deletions(-) diff --git a/arch/linux/tui/main.c b/arch/linux/tui/main.c index 06df4d2..ac6d2e4 100644 --- a/arch/linux/tui/main.c +++ b/arch/linux/tui/main.c @@ -2,16 +2,18 @@ #include "../../../tools/compiler/compiler.h" #include -#define CODE_SIZE 8192 #define MEMORY_SIZE 65536 +#define CODE_SIZE 8192 +#define STACK_SIZE 1024 + u8 lmem[MEMORY_SIZE] = {0}; u8 lcode[CODE_SIZE] = {0}; -u32 lstack[CODE_SIZE] = {0}; +u32 lstack[STACK_SIZE] = {0}; void reset() { pc = 0; cp = 0; - mp = 0; + mp = 255; // hardcoded for now, 255 locals fp = 0; sp = 0; interrupt = 0; @@ -84,6 +86,8 @@ static void repl() { while(step_vm()) {} + syscall(SYSCALL_CONSOLE_WRITE, 255); + printf("Result at top of stack: %d\n", stack[0]); } } diff --git a/tools/compiler/compiler.c b/tools/compiler/compiler.c index d916875..738763a 100644 --- a/tools/compiler/compiler.c +++ b/tools/compiler/compiler.c @@ -242,7 +242,7 @@ static void unary() { case TOKEN_MINUS: { code[cp++] = OP_PUSH_8; code[cp++] = 0; - code[cp++] = OP_EXCH; + code[cp++] = OP_EXCH; code[cp++] = OP_SUB_INT; // kinda cheating, should work break; } @@ -277,26 +277,26 @@ static void binary() { code[cp++] = OP_DIV_INT; break; } - case TOKEN_EQ_EQ:{ + case TOKEN_EQ_EQ: { code[cp++] = OP_EQ; break; } - case TOKEN_GT: { + case TOKEN_GT: { code[cp++] = OP_GT; break; } - case TOKEN_GTE: { + case TOKEN_GTE: { code[cp++] = OP_GE; break; } - case TOKEN_LT: { + case TOKEN_LT: { code[cp++] = OP_LT; break; } - case TOKEN_LTE: { + case TOKEN_LTE: { code[cp++] = OP_LE; break; - } + } default: return; // Unreachable. } @@ -324,6 +324,49 @@ static void literal() { } } +static void string() { + u32 addr = mp; + const char *src = parser.previous.start + 1; + i32 len = 0; + i32 i = 0; + + while (i < parser.previous.length - 2) { + char c = src[i++]; + if (c == '\\' && i < parser.previous.length - 2) { + switch (src[i++]) { + case 'n': + c = '\n'; + break; + case 't': + c = '\t'; + break; + case 'r': + c = '\r'; + break; + case '\\': + case '"': + case '\'': + break; + default: + i--; /* Rewind for unknown escapes */ + } + } + WRITE_U8(addr + 4 + len, c); + len++; + } + + u32 size = len + 5; /* 4 (len) + dst_len + 1 (null) */ + mp += size; + + WRITE_U32(addr, len); + WRITE_U8(addr + 4 + len, '\0'); + + // TODO: this really should always be tied to a global or local variable + // we can fake it for now + WRITE_U32(fp + lp, addr); + lp++; +} + ParseRule rules[] = { [TOKEN_LPAREN] = {grouping, NULL, PREC_NONE}, [TOKEN_RPAREN] = {NULL, NULL, PREC_NONE}, @@ -337,15 +380,15 @@ ParseRule rules[] = { [TOKEN_SLASH] = {NULL, binary, PREC_FACTOR}, [TOKEN_STAR] = {NULL, binary, PREC_FACTOR}, [TOKEN_BANG] = {unary, NULL, PREC_NONE}, - [TOKEN_BANG_EQ] = {NULL, binary, PREC_EQUALITY}, + [TOKEN_BANG_EQ] = {NULL, binary, PREC_EQUALITY}, [TOKEN_EQ] = {NULL, NULL, PREC_NONE}, - [TOKEN_EQ_EQ] = {NULL, binary, PREC_EQUALITY}, - [TOKEN_GT] = {NULL, binary, PREC_COMPARISON}, - [TOKEN_GTE] = {NULL, binary, PREC_COMPARISON}, - [TOKEN_LT] = {NULL, binary, PREC_COMPARISON}, - [TOKEN_LTE] = {NULL, binary, PREC_COMPARISON}, + [TOKEN_EQ_EQ] = {NULL, binary, PREC_EQUALITY}, + [TOKEN_GT] = {NULL, binary, PREC_COMPARISON}, + [TOKEN_GTE] = {NULL, binary, PREC_COMPARISON}, + [TOKEN_LT] = {NULL, binary, PREC_COMPARISON}, + [TOKEN_LTE] = {NULL, binary, PREC_COMPARISON}, [TOKEN_IDENTIFIER] = {NULL, NULL, PREC_NONE}, - [TOKEN_LITERAL_STR] = {NULL, NULL, PREC_NONE}, + [TOKEN_LITERAL_STR] = {string, NULL, PREC_NONE}, [TOKEN_LITERAL_INT] = {number, NULL, PREC_NONE}, [TOKEN_LITERAL_NAT] = {number, NULL, PREC_NONE}, [TOKEN_LITERAL_REAL] = {number, NULL, PREC_NONE}, @@ -395,5 +438,8 @@ bool compile(ScopeTable *st, char *source) { expression(); consume(TOKEN_EOF, "Cannot find end of expression."); - return false; + // technically should not need, but just in case + code[cp++] = OP_HALT; + + return true; } diff --git a/vm/vm.c b/vm/vm.c index 7167e4b..cda8997 100644 --- a/vm/vm.c +++ b/vm/vm.c @@ -5,7 +5,8 @@ u32 pc; /* program counter */ u32 cp; /* code pointer */ u32 mp; /* memory pointer */ u32 fp; /* frame pointer */ -u32 sp; /* frame pointer */ +u32 sp; /* stack pointer */ +u8 lp; /* locals pointer */ u8 status; /* status flag */ u8 interrupt; /* device interrupt */ u32 *stack; /* stack */ @@ -388,6 +389,11 @@ bool step_vm() { stack[sp++] = result; return true; } + case OP_NOT: { + u32 a = !stack[--sp]; + stack[sp++] = a; + return true; + } case OP_BIT_SHIFT_LEFT: { MATH_OP_NO_CAST(<<); } @@ -406,11 +412,6 @@ bool step_vm() { case OP_BIT_XOR: { MATH_OP_NO_CAST(^); } - case OP_NOT: { - u32 a = !stack[--sp]; - stack[sp++] = a; - return true; - } case OP_EQ: { MATH_OP_NO_CAST(==); } diff --git a/vm/vm.h b/vm/vm.h index ea5abf6..7656e88 100644 --- a/vm/vm.h +++ b/vm/vm.h @@ -96,6 +96,7 @@ extern u32 cp; /* code pointer */ extern u32 mp; /* memory pointer */ extern u32 fp; /* frame pointer */ extern u32 sp; /* stack pointer */ +extern u8 lp; /* locals pointer */ extern u8 status; /* status flag */ extern u8 interrupt; /* device interrupt */ extern u32 *stack; /* stack */