diff --git a/alu.c b/alu.c index e2e443b..0de1f3f 100644 --- a/alu.c +++ b/alu.c @@ -60,7 +60,7 @@ typedef uint8_t alu_Byte; typedef double alu_Number; typedef char *alu_String; -typedef unsigned int alu_Size; +typedef uint32_t alu_Size; typedef enum { @@ -74,6 +74,7 @@ typedef enum { // General OP_HALT = 0x00, + OP_RET, // Jumps OP_JMP, // Jump @@ -788,8 +789,8 @@ size_t __Alu_readop(alu_Opcode op, const char *ptr) case 2: return sizeof(alu_Number); case 3: - while (*ptr != '\0') - ++ptr, ++size; + while (ptr[size] != '\0') + ++size; return size; case 4: return sizeof(alu_Byte); @@ -804,16 +805,22 @@ void Alu_feed(alu_State *A, const alu_String ptr) alu_Byte op = 0x00; char *str = null; size_t n = 0, readlen = 0; + printf("=== Begin of instructions ===\n"); do { op = (alu_Byte)ptr[n]; if ((op == OP_HALT) or (op > OP_END)) break; - readlen = __Alu_readop(op, ptr); + readlen = __Alu_readop(op, &ptr[n]); str = strcut(ptr, n, n + readlen + 1); n += readlen + 1; + printf("Get: "); + for (size_t i = 0; i <= readlen; ++i) + printf("%02x ", str[i]); + printf("\n"); Stack2_push(&A->instructions, str); } while (true); + printf("Get: 00\n=== End of instructions ===\n\n"); } // Execute the opcode instruction. @@ -871,14 +878,16 @@ void Alu_jump(alu_State *A, alu_Opcode op, alu_Stack2 **iptr) { if (not __Alu_needtojump(A, op)) { - printf("> Skip\n"); - (*iptr) = (*iptr)->next; + printf("Dont jump\n"); + *iptr = (*iptr)->next; + Alu_popk(A); return; } int jumps = bytesint(((alu_Byte *)(*iptr)->data) + 1) + 1; - printf("> %d\n", jumps); + printf("Jump %d instructions\n", jumps); while (jumps-- and (*iptr != null)) - (*iptr) = (*iptr)->next; + *iptr = (*iptr)->next; + Alu_popk(A); } // Executes the instruction set. @@ -889,6 +898,8 @@ void Alu_execute(alu_State *A) while (instruction != null) { op = ((alu_Byte *)instruction->data)[0]; + if (op == OP_RET) + return; printf("Executes %02x\n", op); if (op >= OP_JMP and op <= OP_JNEM) { @@ -903,6 +914,14 @@ void Alu_execute(alu_State *A) void Alu_start(alu_State *A, const alu_String input) { Alu_feed(A, input); + alu_Stack2 *inst = A->instructions; + unsigned int n = 0; + while (inst != null) + { + inst = inst->next; + ++n; + } + printf("There is %d instructions\n", n); Alu_execute(A); } @@ -928,70 +947,34 @@ void Alu_startfile(alu_State *A, const alu_String filename) remove(buffer); } +void Alu_stackview(alu_State *A) +{ + alu_Stack *ptr = A->stack; + printf("[ "); + while (ptr != null) + { + printf("%d", *(alu_Size *)((alu_Variable *)ptr->data)->data); + printf("%s", ptr->next ? ", " : ""); + ptr = ptr->next; + } + printf(" ]\n"); +} + /* Main */ int main(void) { alu_State *A = Alu_newstate(); - char input[] = { - OP_PUSHSTR, // 1 - 'F', - 'o', - 'o', - '\0', - - OP_PUSHSTR, // 2 - 'F', - 'o', - 'o', - '\0', - - OP_EVAL, // 3 - EVAL_EQUALS, - - OP_JFA, // 4 - 0, - 0, - 0, - 2, - - OP_STACKCLOSE, // 5 - - OP_PUSHSTR, // 6 - 'S', - 'a', - 'm', - 'e', - '!', - '\0', - - OP_JMP, // 7 - 0, - 0, - 0, - 2, - - OP_STACKCLOSE, // 8 - - OP_PUSHSTR, // 9 - 'D', - 'i', - 'f', - 'f', - 'e', - 'r', - 'e', - 'n', - 't', - '!', - '\0', - - OP_HALT, // 10 + OP_PUSHBOOL, true, + OP_JTR, 0, 0, 0, 2, + OP_PUSHSTR, 'H', 'e', 'l', 'l', 'o', '\0', + OP_RET, + OP_PUSHSTR, 'F', 'o', 'o', '\0', + OP_RET, + OP_HALT, }; - Alu_start(A, input); printf("%s\n", Alu_getstring(A, 0)); - return Alu_close(A); } diff --git a/input.txt b/input.txt deleted file mode 100644 index cbe71c9..0000000 --- a/input.txt +++ /dev/null @@ -1,10 +0,0 @@ - [1] PUSHSTR "Foo" - [2] PUSHSTR "Foo" - [3] EVAL eq - [4] JFA 3 // To 8 - [5] STACKCLOSE - [6] PUSHSTR "Same!" - [7] JMP 2 // To 10 - [8] STACKCLOSE - [9] PUSHSTR "Different!" - [10] HALT diff --git a/spec/class.spec.txt b/spec/class.spec.txt new file mode 100644 index 0000000..2b2ebaa --- /dev/null +++ b/spec/class.spec.txt @@ -0,0 +1,48 @@ +class Object is + let foo + constructor toto = 3 + + constructor func new(idk) + self.foo = idk + end + func bar() + end +end +let a = Object.new(42) +a.bar() +print(a.foo) + + + +[0] + ret +[1] + unload 1 // [ 42, {...} ] line 5 + super // [ {...}, 42 ] + impl "foo" // [ {...} ] + ret +[2] + pushtable // [ {} ] __constructor + pushinst 1 // [ {}, function ] + pushnumber 3 // [ {}, function, 3 ] + impl "new" // [ {...}, 3] + impl "toto" // [ {...} ] + load 0 // [ ] + pushtable // [ {} ] __emptyself + pushinst 2 // [ {}, function ] + impl "bar" // [ {...} ] + load 1 // [ ] + unload 0 // [ {...} ] line 12 + querry "new" // [ function ] + pushnumber 42 // [ function, 42 ] + call // [ {...} ] + load 2 // [ ] + unload 2 // [ {...} ] line 13 + querry "bar" // [ function ] + unloadref 2 // [ function, abstract ] + call // [ ] + unload 2 // [ {...} ] line 14 + querry "foo" // [ any ] + pushdef "print" // [ any, function ] + supercall // [ ] + halt diff --git a/spec/function.spec.txt b/spec/function.spec.txt new file mode 100644 index 0000000..0907b57 --- /dev/null +++ b/spec/function.spec.txt @@ -0,0 +1,25 @@ +func Max(a, b) + if a < b then return b else return a end +end + +let a = Max(42, 69) +print(a) + + + +[0] + evalnice sm // [ false, 42, 69 ] + jtr 2 // [ false, 42, 69 ] + popkr 2 // [ 69 ] + ret + popk // [ 42, 69 ] + popkn 1 // [ 42 ] + ret +[1] + pushnumber 42 // [ 42 ] + pushnumber 69 // [ 42, 69 ] + pushinst 0 // [ 42, 69, function ] + supercall // [ 69 ] + pushdef "print" // [ 69, function ] + supercall // [ ] + halt diff --git a/spec/helloworld.spec.txt b/spec/helloworld.spec.txt new file mode 100644 index 0000000..89e6946 --- /dev/null +++ b/spec/helloworld.spec.txt @@ -0,0 +1,10 @@ +print("Hello", "world") + + + +[0] + pushstr "Hello" // [ "Hello" ] + pushstr "world" // [ "Hello", "world" ] + pushdef "print" // [ "Hello", "world", function ] + supercall // [ ] + halt diff --git a/spec/if.spec.txt b/spec/if.spec.txt new file mode 100644 index 0000000..3382e1a --- /dev/null +++ b/spec/if.spec.txt @@ -0,0 +1,23 @@ +if "Foo" == "Foo" then + print("Same") +else + print("Different") +end + + + +[0] + pushstr "Foo" // [ "Foo" ] line 1 + pushstr "Foo" // [ "Foo", "Foo" ] + eval eq // [ true ] + jfa 3 // [ true ] -> line 3 + stackclose // [ ] + pushstr "Same" // [ "Same" ] line 2 + pushdef "print" // [ "Same", function ] + supercall // [ ] + jmp 5 // [ ] -> line 5 + stackclose // [ ] line 3 + pushstr "Different" // [ "Different" ] line 4 + pushdef "print" // [ "Different", function ] + supercall // [ ] + halt line 5 diff --git a/spec/problem.spec.txt b/spec/problem.spec.txt new file mode 100644 index 0000000..06eea92 --- /dev/null +++ b/spec/problem.spec.txt @@ -0,0 +1,41 @@ +func Inc(a) + return a + 1 +end + +func Sum(a, b) + return a + b +end + +print(1, Sum(2, Inc(0)), 2, Inc(1), 3) + + + +[0] + pushnumber 1 // [ any, 1 ] + sumstack // [ any ] + ret +[1] + sumstack // [ any ] + ret +[2] + pushnumber 0 // [ 0 ] + pushinst 1 // [ 0, function ] + supercall // [ 1 ] + tpush // [ ] + pushnumber 2 // [ 2 ] + tpop // [ 2, 1 ] + pushinst 2 // [ 2, 1, function ] + supercall // [ 3 ] + tpush // [ ] + pushnumber 1 // [ 1 ] + pushinst 1 // [ 1, function ] + supercall // [ 2 ] + tpush // [ ] + pushnumber 1 // [ 1 ] + tpop // [ 1, 3 ] + pushnumber 2 // [ 1, 3, 2 ] + tpop // [ 1, 3, 2, 2 ] + pushnumber 3 // [ 1, 3, 2, 2, 3 ] + pushdef "print" // [ 1, 3, 2, 2, 3, function ] + supercall // [ ] + halt diff --git a/spec/table.spec.txt b/spec/table.spec.txt new file mode 100644 index 0000000..8996b71 --- /dev/null +++ b/spec/table.spec.txt @@ -0,0 +1,23 @@ +let a = { bar = "foo" } +a.toto = 42 +print(a.bar, 69, a.toto) + + + +[0] + pushtable // [ {} ] line 1 + pushstr "foo" // [ {}, "foo" ] + impl "bar" // [ {...} ] + load 0 // [ ] + unload 0 // [ {...} ] line 2 + pushnumber 42 // [ {...}, 42 ] + impl "toto" // [ {...} ] + load 0 // [ ] + unload 0 // [ {...} ] line 3 + querry "bar" // [ "foo" ] + pushnumber 69 // [ "foo", 69 ] + unload 0 // [ "foo", 69, {...} ] + super // [ {...}, "foo", 69 ] + querry "toto" // [ "foo", 69, 42 ] + pushdef "print" // [ "foo", 69, 42, function ] + supercall // [ ]