diff --git a/src/' b/src/' new file mode 100644 index 0000000..2c69bce --- /dev/null +++ b/src/' @@ -0,0 +1,11 @@ +#ifndef ZRE_COMPILER_H +#define ZRE_COMPILER_H + +#include "opcodes.h" + +uint32_t demo_add_compile (Value *memory); +uint32_t demo_loop_compile (Value *memory); +uint32_t demo_function_call_compile(Value *memory); +uint32_t compile (Value* memory, char *buffer); + +#endif diff --git a/src/compiler.c b/src/compiler.c index 15465a4..4c77639 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -1,57 +1,80 @@ #include "compiler.h" #include "parser.h" -uint32_t demo_add_compile(Value *memory) { +uint32_t test_add_compile(Value *memory) { uint32_t i = 0; memory[i++].u = OP(OP_LOADU, 0, 0, 0); - memory[i++].u = 0; - memory[i++].u = OP(OP_LOADU, 1, 0, 0); - memory[i++].u = 5; - memory[i++].u = OP(OP_LOADU, 2, 0, 0); memory[i++].u = 1; - memory[i++].u = OP(OP_LOADF, 3, 0, 0); - memory[i++].f = 5.0f; - memory[i++].u = OP(OP_LOADF, 4, 0, 0); - memory[i++].f = 5.0f; - memory[i++].u = OP(OP_LOADU, 5, 0, 0); - uint32_t jmp = i + 1; - memory[i++].u = jmp; - memory[i++].u = OP(OP_ADD_REAL, 4, 4, 3); - memory[i++].u = OP(OP_SUB_UINT, 1, 1, 2); - memory[i++].u = OP(OP_JGT_UINT, 5, 1, 0); - memory[i++].u = OP(OP_REAL_TO_STRING, 6, 4, 0); - memory[i++].u = OP(OP_REAL_TO_UINT, 1, 4, 4); - memory[i++].u = OP(OP_UINT_TO_STRING, 7, 1, 0); - memory[i++].u = OP(OP_READ_STRING, 8, 0, 0); - memory[i++].u = OP(OP_PRINT_STRING, 0, 6, 0); - memory[i++].u = OP(OP_PRINT_STRING, 0, 7, 0); - memory[i++].u = OP(OP_PRINT_STRING, 0, 8, 0); + memory[i++].u = OP(OP_LOADU, 1, 0, 0); + memory[i++].u = 2; + memory[i++].u = OP(OP_ADD_UINT, 2, 1, 0); /* let sum = 1 + 2; */ + memory[i++].u = OP(OP_UINT_TO_STRING, 3, 2, 0); + memory[i++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(sum.toS()); */ memory[i++].u = OP(OP_HALT, 0, 0, 0); /* explicit halt */ return i; } - -uint32_t demo_function_call_compile(Value *memory) { +uint32_t test_loop_compile(Value *memory) { uint32_t i = 0; + memory[i++].u = OP(OP_LOADF, 0, 0, 0); /* let a = 5.0 */ + memory[i++].f = 5.0f; + memory[i++].u = OP(OP_LOADI, 1, 0, 0); /* do (i = 5, 0, -1) { */ + memory[i++].i = 5; + memory[i++].u = OP(OP_LOADI, 2, 0, 0); /* loop check value */ + memory[i++].i = 0; + memory[i++].u = OP(OP_LOADI, 3, 0, 0); /* loop incriment value */ + memory[i++].i = -1; + memory[i++].u = OP(OP_LOADU, 4, 0, 0); /* loop start */ + uint32_t jmp = i + 1; + memory[i++].u = jmp; + memory[i++].u = OP(OP_LOADF, 5, 0, 0); + memory[i++].f = 5.0f; + memory[i++].u = OP(OP_ADD_REAL, 0, 0, 5); /* a += 5.0; */ + memory[i++].u = OP(OP_ADD_INT, 1, 1, 3); /* (implied by loop) i = i + (-1) */ + memory[i++].u = OP(OP_JGT_INT, 4, 1, 2); /* } */ + memory[i++].u = OP(OP_REAL_TO_UINT, 1, 0, 0); /* let b = a as nat; */ + memory[i++].u = OP(OP_READ_STRING, 2, 0, 0); /* let user_string = gets(); */ + memory[i++].u = OP(OP_UINT_TO_STRING, 3, 1, 0); + memory[i++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(a.toS()); */ + memory[i++].u = OP(OP_REAL_TO_STRING, 3, 0, 0); + memory[i++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(b.toS()); */ + memory[i++].u = OP(OP_PRINT_STRING, 0, 2, 0); /* print(user_string); */ + memory[i++].u = OP(OP_HALT, 0, 0, 0); /* program done */ + return i; +} + +uint32_t test_add_function_compile(Value *memory) { + uint32_t i = 0; + memory[i++].u = OP(OP_POP_ARGS, 0, 0, 0); + memory[i++].u = OP(OP_ADD_INT, 2, 1, 0); + memory[i++].u = OP(OP_RETURN, 0, 0, 0); + memory[i++].u = OP(OP_HALT, 0, 0, 0); + return i; +} + +uint32_t test_recursive_function_compile(Value *memory) { + uint32_t i = 0; + memory[i++].u = OP(OP_POP_ARGS, 0, 0, 0); + memory[i++].u = OP(OP_ADD_INT, 2, 1, 0); + memory[i++].u = OP(OP_RETURN, 0, 0, 0); memory[i++].u = OP(OP_HALT, 0, 0, 0); return i; } static void letDeclaration() { -/* uint8_t global = parseVariable("Expect variable name."); */ + /* uint8_t global = parseVariable("Expect variable name."); */ -/* if (match(TOKEN_EQUAL)) { */ -/* expression(); */ -/* } else { */ -/* emitByte(OP_NIL); */ -/* } */ -/* consume(TOKEN_SEMICOLON, */ -/* "Expect ';' after variable declaration."); */ + /* if (match(TOKEN_EQUAL)) { */ + /* expression(); */ + /* } else { */ + /* emitByte(OP_NIL); */ + /* } */ + /* consume(TOKEN_SEMICOLON, */ + /* "Expect ';' after variable declaration."); */ -/* defineVariable(global); */ + /* defineVariable(global); */ } - static void declaration(Token t) { if (t.type == TOKEN_LET) { letDeclaration(); @@ -67,7 +90,7 @@ uint32_t compile(Value *memory, char *buffer) { uint32_t i = 0; initTokenizer(buffer); Token t = nextToken(); - while (t.type != TOKEN_EOF) { + while (t.type != TOKEN_EOF) { printToken(t); declaration(t); t = nextToken(); diff --git a/src/compiler.h b/src/compiler.h index de04409..fa171a5 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -3,8 +3,10 @@ #include "opcodes.h" -uint32_t demo_add_compile (Value *memory); -uint32_t demo_function_call_compile(Value *memory); +uint32_t test_add_compile (Value *memory); +uint32_t test_loop_compile (Value *memory); +uint32_t test_add_function_compile(Value *memory); +uint32_t test_recursive_function_compile(Value *memory); uint32_t compile (Value* memory, char *buffer); #endif diff --git a/src/main.c b/src/main.c index d401d2d..bad2cfb 100644 --- a/src/main.c +++ b/src/main.c @@ -54,7 +54,7 @@ int main(int argc, char **argv) { vm.frames_size = FRAMES_SIZE; vm.stack_size = STACK_SIZE; vm.memory_size = MEMORY_SIZE; - vm.frames[vm.fp].allocated.end = demo_add_compile(vm.memory); + vm.frames[vm.fp].allocated.end = test_loop_compile(vm.memory); #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(mainloop, 0, 1); diff --git a/src/opcodes.h b/src/opcodes.h index 197134b..4eb6fc9 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -18,12 +18,12 @@ typedef struct { #define MAX_REGS 256 typedef struct { Value registers[MAX_REGS]; /* R0-R[MAX_REGS-1] */ - uint32_t rp; /* register pointer (last unused) */ - Slice allocated; /* start and end of global allocated block */ + uint32_t rp; /* register pointer (last unused) */ + Slice allocated; /* start and end of global allocated block */ } Frame; #define MEMORY_SIZE 65536 -#define FRAMES_SIZE 32 +#define FRAMES_SIZE 32 #define STACK_SIZE 256 typedef struct { uint32_t pc; /* Program counter */ @@ -46,8 +46,14 @@ typedef enum { OP_STOREI, /* stri : next memory location = src1 as int */ OP_STOREU, /* stru : next memory location = src1 as uint */ OP_STOREF, /* strf : next memory location = src1 as float */ - OP_PUSH_ARGS, /* */ - OP_POP_ARGS, /* */ + OP_PUSHI, /* pshi : push int from register onto the stack */ + OP_PUSHU, /* pshu : push uint from register onto the stack */ + OP_PUSHF, /* pshf : push float from register onto the stack */ + OP_PUSHS, /* pshs : push str ref from register onto the stack and copy str */ + OP_POPI, /* popi : pop int from stack onto the register */ + OP_POPU, /* popu : pop uint from stack onto the register */ + OP_POPF, /* popf : pop float from stack onto the register */ + OP_POPS, /* pops : pop str ref from stack and move/copy to register */ OP_ADD_INT, /* addi : dest = src1 + src2 */ OP_SUB_INT, /* subs : dest = src1 - src2 */ OP_MUL_INT, /* mulm : dest = src1 * src2 */ @@ -81,8 +87,8 @@ typedef enum { OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */ OP_MOV, /* move : dest = src1 */ OP_JMP, /* jump : jump to address src1 unconditionally */ - OP_CALL, /* creates a new frame */ - OP_RETURN, /* returns from a frame to the parent frame */ + OP_CALL, /* call : creates a new frame */ + OP_RETURN, /* retn : returns from a frame to the parent frame */ OP_INT_TO_STRING, /* itos : dest = src1 as str */ OP_UINT_TO_STRING, /* utos : dest = src1 as str */ OP_REAL_TO_STRING, /* rtos : dest = src1 as str */ diff --git a/test/func-simple.zre b/test/add-func.zre similarity index 100% rename from test/func-simple.zre rename to test/add-func.zre diff --git a/test/funcs.zre b/test/funcs.zre deleted file mode 100644 index 0f2fd45..0000000 --- a/test/funcs.zre +++ /dev/null @@ -1,14 +0,0 @@ -fn first() { - int a = 1; - second(a, -1); - int b = 2; - second(a, b); -} - -fn second(int c, int d) { - str numbers = c.toS() + " " + d.toS(); - print(numbers); - ! implied return because return type is null -} - -first(); diff --git a/test/loop.zre b/test/loop.zre index 782fe71..9c08ca2 100644 --- a/test/loop.zre +++ b/test/loop.zre @@ -1,12 +1,9 @@ -for (let i = 0; i < 10; i = i + 1) { - print(i); +let a = 5.0; +do (i = 5, 0, -1) { + a += 5.0; } - -let val = true; -let j = 0; -while (val) { - j = j + 1; - if (j > 9) val = false; - print(j); -} -print("done"); +let b = a as nat; +let user_string = gets(); +print(a.toS()); +print(b.toS()); +print(user_string);