From 9e555bc2bf618148929e52ccd0efdb1b752bdcac Mon Sep 17 00:00:00 2001 From: ubq323 Date: Tue, 1 Aug 2023 22:37:26 +0100 Subject: compilation of basic arithmetic exprs to bytecode --- .gitignore | 1 + Makefile | 4 ++-- com.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ grammar.peg | 1 - read.c | 6 ------ run.h | 10 --------- vm.c | 23 ++++++++++---------- vm.h | 1 + 8 files changed, 85 insertions(+), 31 deletions(-) create mode 100644 com.c delete mode 100644 run.h diff --git a/.gitignore b/.gitignore index a470cdb..08476bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ parser.c parser.h badthing +vm diff --git a/Makefile b/Makefile index 53062a0..0160897 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -CS=parser.c ast.c run.c read.c ht.c -HS=parser.h ast.h run.h read.h ht.h +CS=ast.c com.c dis.c parser.c read.c val.c vm.c +HS=ast.h dis.h parser.h read.h val.h vm.h CFLAGS=-O3 -Wall -Wpedantic -Werror=implicit-function-declaration badthing: $(CS) $(HS) diff --git a/com.c b/com.c new file mode 100644 index 0000000..f7c7f2d --- /dev/null +++ b/com.c @@ -0,0 +1,70 @@ +#include +#include + +#include "vm.h" +#include "ast.h" +#include "read.h" + +static void compile_node(Chunk *ch, AstNode a) { + switch (a.ty) { + case AST_SYMBOL: + printf("can't compile symbol\n"); + exit(1); + break; + case AST_NUM: + chunk_wbc(ch, OP_LOADK); + chunk_wbc(ch, chunk_wconst(ch, VAL_NUM(a.as.num))); + break; + case AST_LIST:; + AstVec l = a.as.list; + #define CK(cond, msg) if (!(cond)) { puts(msg); exit(1); } + CK(l.len == 3, "can only compile binary ops"); + CK(l.vals[0].ty == AST_SYMBOL, "can only call ops"); + #undef CK + char opchar = l.vals[0].as.str[0]; + Op op; + switch (opchar) { + #define OP(char, code) case char: op = code; break; + OP('+', OP_ADD) + OP('-', OP_SUB) + OP('*', OP_MUL) + OP('/', OP_DIV) + #undef OP + default: + printf("unkown op %s\n",l.vals[0].as.str); + exit(1); + break; + } + compile_node(ch, l.vals[1]); + compile_node(ch, l.vals[2]); + chunk_wbc(ch, op); + } +} + + + + + +int main() { + Chunk ch = chunk_new(); + AstNode an = read(); + compile_node(&ch, an); + + chunk_wbc(&ch, OP_PRINT); + chunk_wbc(&ch, OP_RET); + + + // chunk_wbc(&ch, OP_LOADK); + // chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(5.0))); + // chunk_wbc(&ch, OP_LOADK); + // chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(10.0))); + // chunk_wbc(&ch, OP_LOADK); + // chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(2.0))); + // chunk_wbc(&ch, OP_MUL); + // chunk_wbc(&ch, OP_ADD); + // chunk_wbc(&ch, OP_PRINT); + // chunk_wbc(&ch, OP_RET); + + runvm(&ch); +} + diff --git a/grammar.peg b/grammar.peg index c74c6f6..3c75ab9 100644 --- a/grammar.peg +++ b/grammar.peg @@ -16,7 +16,6 @@ static const char *dbg_str[] = { "Evaluating rule", "Matched rule", "Abandoning %common { #include "ast.h" -#include "run.h" } diff --git a/read.c b/read.c index 5620607..016ef62 100644 --- a/read.c +++ b/read.c @@ -2,7 +2,6 @@ #include #include "read.h" -#include "run.h" AstNode read() { AstNode ret; @@ -13,8 +12,3 @@ AstNode read() { return ret; } -int main() { - Ht e = ht_new(); - for (;;) printf("%d\n",eval(&e, read())); -} - diff --git a/run.h b/run.h deleted file mode 100644 index 291897c..0000000 --- a/run.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _run_h -#define _run_h - -#include "ast.h" -#include "ht.h" -#include "val.h" - - - -#endif diff --git a/vm.c b/vm.c index 72f69fa..70f065b 100644 --- a/vm.c +++ b/vm.c @@ -60,22 +60,22 @@ Vm vm_new(Chunk *ch) { } -static void runvm() { - Chunk ch = chunk_new(); +void runvm(Chunk *ch) { + // Chunk ch = chunk_new(); - chunk_wbc(&ch, OP_LOADK); - chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(10.0))); - chunk_wbc(&ch, OP_LOADK); - chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(3.0))); - chunk_wbc(&ch, OP_DIV); - chunk_wbc(&ch, OP_PRINT); + // chunk_wbc(&ch, OP_LOADK); + // chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(10.0))); + // chunk_wbc(&ch, OP_LOADK); + // chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(3.0))); + // chunk_wbc(&ch, OP_DIV); + // chunk_wbc(&ch, OP_PRINT); - chunk_wbc(&ch, OP_RET); + // chunk_wbc(&ch, OP_RET); - disasm_chunk(&ch); + disasm_chunk(ch); - Vm vm = vm_new(&ch); + Vm vm = vm_new(ch); #define RBYTE() (vm.ch->b[vm.ip++]) #define PUSH(v) vm.stack[vm.sp++] = v; @@ -126,6 +126,5 @@ static void runvm() { done:; } -int main() { runvm(); } diff --git a/vm.h b/vm.h index cfa3f6d..c710a4b 100644 --- a/vm.h +++ b/vm.h @@ -43,5 +43,6 @@ typedef enum { OP_DIV, } Op; +void runvm(Chunk *ch); #endif -- cgit v1.2.3