| @@ -0,0 +1,23 @@ | |||
| #ifndef L2_BYTECODE_H | |||
| #define L2_BYTECODE_H | |||
| #include <stdint.h> | |||
| typedef uint32_t l2_word; | |||
| enum l2_opcode { | |||
| L2_OP_PUSH, | |||
| L2_OP_ADD, | |||
| L2_OP_JUMP, | |||
| L2_OP_CALL, | |||
| L2_OP_ALLOC_STRING, | |||
| L2_OP_ALLOC_ARRAY, | |||
| L2_OP_HALT, | |||
| }; | |||
| struct l2_op { | |||
| enum l2_opcode code; | |||
| l2_word val; | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,8 @@ | |||
| #ifndef L2_PARSE_H | |||
| #define L2_PARSE_H | |||
| #include "lex.h" | |||
| void l2_parse(); | |||
| #endif | |||
| @@ -0,0 +1,45 @@ | |||
| #ifndef L2_VM_H | |||
| #define L2_VM_H | |||
| #include <stdlib.h> | |||
| #include "../bytecode.h" | |||
| enum { | |||
| L2_VAL_TYPE_STRING = (1 << 30) + 0, | |||
| L2_VAL_TYPE_ARRAY = (1 << 30) + 1, | |||
| L2_VAL_MARKED = 1 << 29, | |||
| }; | |||
| struct l2_vm_value { | |||
| l2_word flags; | |||
| }; | |||
| struct l2_vm_string { | |||
| struct l2_vm_value val; | |||
| char *mem; | |||
| size_t len; | |||
| }; | |||
| struct l2_vm_array { | |||
| struct l2_vm_value val; | |||
| l2_word *data; | |||
| size_t len; | |||
| size_t size; | |||
| }; | |||
| struct l2_vm { | |||
| struct l2_op *ops; | |||
| size_t opcount; | |||
| struct l2_vm_value *allocs[1024]; | |||
| size_t allocslen; | |||
| l2_word stack[1024]; | |||
| l2_word iptr; | |||
| l2_word sptr; | |||
| }; | |||
| void l2_vm_init(struct l2_vm *vm, struct l2_op *ops, size_t opcount); | |||
| void l2_vm_step(struct l2_vm *vm); | |||
| #endif | |||
| @@ -1,19 +1,53 @@ | |||
| #include "io.h" | |||
| #include "parse/lex.h" | |||
| #include "vm/vm.h" | |||
| #include "bitmap.h" | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| int main() { | |||
| struct l2_io_mem_reader r = { l2_io_mem_read }; | |||
| r.mem = " \"Hello\", [], {}."; | |||
| r.len = strlen(r.mem); | |||
| struct l2_lexer lexer; | |||
| l2_lexer_init(&lexer, &r.r); | |||
| while (1) { | |||
| struct l2_token *tok = l2_lexer_get(&lexer); | |||
| printf("%s\n", l2_token_kind_name(tok->kind)); | |||
| if (tok->kind == L2_TOK_EOF) { | |||
| break; | |||
| struct l2_bitmap bm; | |||
| l2_bitmap_init(&bm); | |||
| for (size_t i = 0; i < 8191; ++i) { | |||
| size_t id = l2_bitmap_set_next(&bm); | |||
| assert(id == i); | |||
| assert(l2_bitmap_get(&bm, i)); | |||
| } | |||
| for (size_t i = 0; i < 10000; ++i) { | |||
| if (i < 8191) { | |||
| assert(l2_bitmap_get(&bm, i)); | |||
| } else { | |||
| assert(!l2_bitmap_get(&bm, i)); | |||
| } | |||
| } | |||
| l2_bitmap_unset(&bm, 100); | |||
| assert(l2_bitmap_set_next(&bm) == 8191); | |||
| assert(l2_bitmap_set_next(&bm) == 100); | |||
| l2_bitmap_free(&bm); | |||
| } | |||
| /* | |||
| int main() { | |||
| struct l2_op ops[] = { | |||
| { L2_OP_PUSH, 100 }, | |||
| { L2_OP_PUSH, 100 }, | |||
| { L2_OP_ADD }, | |||
| { L2_OP_HALT }, | |||
| }; | |||
| struct l2_vm vm; | |||
| l2_vm_init(&vm, ops, sizeof(ops) / sizeof(*ops)); | |||
| while (vm.ops[vm.iptr].code != L2_OP_HALT) { | |||
| printf("Exec %i\n", vm.ops[vm.iptr].code); | |||
| l2_vm_step(&vm); | |||
| } | |||
| printf("Done. Stack:\n"); | |||
| for (l2_word i = 0; i < vm.sptr; ++i) { | |||
| printf(" %i: %i\n", i, vm.stack[i]); | |||
| } | |||
| } | |||
| */ | |||
| @@ -0,0 +1,36 @@ | |||
| #include "vm/vm.h" | |||
| void l2_vm_init(struct l2_vm *vm, struct l2_op *ops, size_t opcount) { | |||
| vm->ops = ops; | |||
| vm->opcount = opcount; | |||
| vm->iptr = 0; | |||
| vm->sptr = 0; | |||
| } | |||
| static l2_word alloc(struct l2_vm *vm, size_t size) { | |||
| l2_word id = vm->allocslen++; | |||
| vm->allocs[id] = malloc(size); | |||
| return id | 1 << 31; | |||
| } | |||
| void l2_vm_step(struct l2_vm *vm) { | |||
| struct l2_op op = vm->ops[vm->iptr++]; | |||
| switch (op.code) { | |||
| case L2_OP_PUSH: | |||
| vm->stack[vm->sptr++] = op.val; | |||
| break; | |||
| case L2_OP_ADD: | |||
| vm->sptr -= 1; | |||
| vm->stack[vm->sptr - 1] += vm->stack[vm->sptr]; | |||
| break; | |||
| case L2_OP_JUMP: | |||
| vm->iptr = vm->stack[--vm->sptr]; | |||
| break; | |||
| case L2_OP_HALT: | |||
| break; | |||
| } | |||
| } | |||