diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-23 15:32:40 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-23 15:32:40 +0200 |
commit | 13f795f8f8aa302ee36ca3974fb80dba29240240 (patch) | |
tree | 4ede9989acd1a4cb54f8232c11d249e5f0187256 | |
parent | bd1480fd2cb80680933b80900c5fb13b5f88ca42 (diff) | |
download | bdl-13f795f8f8aa302ee36ca3974fb80dba29240240.tar.gz bdl-13f795f8f8aa302ee36ca3974fb80dba29240240.zip |
Add more types and access macros
-rwxr-xr-x | src/bytecode/compiler.h | 2 | ||||
-rwxr-xr-x | src/bytecode/debug.h | 2 | ||||
-rwxr-xr-x | src/bytecode/main.c | 4 | ||||
-rwxr-xr-x | src/bytecode/objects.h | 81 | ||||
-rwxr-xr-x | src/bytecode/vm.h | 70 |
5 files changed, 115 insertions, 44 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index ae8fac1..e48a173 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h | |||
@@ -52,7 +52,7 @@ parse_fixnum(Chunk *chunk, Token tok) { | |||
52 | } | 52 | } |
53 | num = num * 10 + (c - '0'); | 53 | num = num * 10 + (c - '0'); |
54 | } | 54 | } |
55 | emit_constant(chunk, tok, num * sign); | 55 | emit_constant(chunk, tok, FIXNUM_VAL(num * sign)); |
56 | } | 56 | } |
57 | 57 | ||
58 | void parse_tree(Chunk *chunk, Visitor *vs); | 58 | void parse_tree(Chunk *chunk, Visitor *vs); |
diff --git a/src/bytecode/debug.h b/src/bytecode/debug.h index 25ac693..42b5b93 100755 --- a/src/bytecode/debug.h +++ b/src/bytecode/debug.h | |||
@@ -17,7 +17,7 @@ disassemble_chunk(Chunk *chunk, const char *name) { | |||
17 | printf("\nconstants:\n"); | 17 | printf("\nconstants:\n"); |
18 | offset = 0; | 18 | offset = 0; |
19 | while (offset < array_size(chunk->constants)) { | 19 | while (offset < array_size(chunk->constants)) { |
20 | printf("\t%04ld -> ", offset); | 20 | printf("\t%03ld -> ", offset); |
21 | display(chunk->constants[offset]); | 21 | display(chunk->constants[offset]); |
22 | printf("\n"); | 22 | printf("\n"); |
23 | offset++; | 23 | offset++; |
diff --git a/src/bytecode/main.c b/src/bytecode/main.c index d6cb5d3..bad150c 100755 --- a/src/bytecode/main.c +++ b/src/bytecode/main.c | |||
@@ -49,9 +49,9 @@ process_source(const StringView *source) { | |||
49 | } | 49 | } |
50 | 50 | ||
51 | // Interpret chunk. | 51 | // Interpret chunk. |
52 | vm_interpret(vm, chunk); | 52 | vm_interpret(&vm, chunk); |
53 | if (errors_n != 0) { | 53 | if (errors_n != 0) { |
54 | disassemble_chunk(vm.chunk, "test chunk"); | 54 | disassemble_chunk(vm.chunk, "current chunk"); |
55 | } | 55 | } |
56 | 56 | ||
57 | chunk_free(chunk); | 57 | chunk_free(chunk); |
diff --git a/src/bytecode/objects.h b/src/bytecode/objects.h index 9bfa2cf..a25b0b1 100755 --- a/src/bytecode/objects.h +++ b/src/bytecode/objects.h | |||
@@ -2,26 +2,97 @@ | |||
2 | #define BDL_OBJECTS_H | 2 | #define BDL_OBJECTS_H |
3 | 3 | ||
4 | typedef enum ObjectType { | 4 | typedef enum ObjectType { |
5 | OBJ_TYPE_FIXNUM, | ||
6 | OBJ_TYPE_BOOL, | ||
7 | OBJ_TYPE_NIL, | 5 | OBJ_TYPE_NIL, |
6 | OBJ_TYPE_TRUE, | ||
7 | OBJ_TYPE_FALSE, | ||
8 | OBJ_TYPE_FIXNUM, | ||
8 | OBJ_TYPE_SYMBOL, | 9 | OBJ_TYPE_SYMBOL, |
9 | OBJ_TYPE_STRING, | 10 | OBJ_TYPE_STRING, |
10 | OBJ_TYPE_PAIR, | 11 | OBJ_TYPE_PAIR, |
11 | OBJ_TYPE_PROCEDURE, | ||
12 | OBJ_TYPE_LAMBDA, | 12 | OBJ_TYPE_LAMBDA, |
13 | OBJ_TYPE_ERR, | 13 | OBJ_TYPE_ERR, |
14 | } ObjectType; | 14 | } ObjectType; |
15 | 15 | ||
16 | struct Environment; | 16 | struct Environment; |
17 | 17 | ||
18 | typedef s64 Object; | 18 | typedef struct Object { |
19 | ObjectType type; | ||
20 | bool marked; | ||
21 | union { | ||
22 | // OBJ_TYPE_FIXNUM | ||
23 | ssize_t fixnum; | ||
24 | |||
25 | // OBJ_TYPE_STRING | ||
26 | // OBJ_TYPE_SYMBOL | ||
27 | // struct { | ||
28 | // char *text; | ||
29 | // }; | ||
30 | |||
31 | // OBJ_TYPE_PAIR | ||
32 | // struct { | ||
33 | // struct Object *car; | ||
34 | // struct Object *cdr; | ||
35 | // }; | ||
36 | |||
37 | // OBJ_TYPE_LAMBDA | ||
38 | // struct { | ||
39 | // struct Object *params; | ||
40 | // struct Object *body; | ||
41 | // struct Environment *env; | ||
42 | // }; | ||
43 | }; | ||
44 | } Object; | ||
19 | 45 | ||
20 | void display(Object obj); | 46 | void display(Object obj); |
21 | 47 | ||
48 | // Value initialization. | ||
49 | #define NIL_VAL ((Object){.type = OBJ_TYPE_NIL}) | ||
50 | #define TRUE_VAL ((Object){.type = OBJ_TYPE_TRUE}) | ||
51 | #define FALSE_VAL ((Object){.type = OBJ_TYPE_FALSE}) | ||
52 | #define FIXNUM_VAL(VAL) ((Object){.type = OBJ_TYPE_FIXNUM, .fixnum = VAL}) | ||
53 | |||
54 | // Value extraction. | ||
55 | #define AS_FIXNUM(VAL) ((VAL).fixnum) | ||
56 | |||
57 | // Type checking. | ||
58 | #define IS_TRUE(VAL) ((VAL).type != OBJ_TYPE_FALSE) | ||
59 | #define IS_FALSE(VAL) ((VAL).type == OBJ_TYPE_FALSE) | ||
60 | #define IS_FIXNUM(VAL) ((VAL).type == OBJ_TYPE_FIXNUM) | ||
61 | |||
22 | void | 62 | void |
23 | display(Object obj) { | 63 | display(Object obj) { |
24 | printf("%ld", obj); | 64 | switch (obj.type) { |
65 | case OBJ_TYPE_FIXNUM: { | ||
66 | printf("%zd", obj.fixnum); | ||
67 | } break; | ||
68 | case OBJ_TYPE_TRUE: { | ||
69 | printf("true"); | ||
70 | } break; | ||
71 | case OBJ_TYPE_FALSE: { | ||
72 | printf("false"); | ||
73 | } break; | ||
74 | case OBJ_TYPE_NIL: { | ||
75 | printf("()"); | ||
76 | } break; | ||
77 | case OBJ_TYPE_STRING: { | ||
78 | // printf("\"%.*s\"", (int)array_size(obj.string), obj.string); | ||
79 | } break; | ||
80 | case OBJ_TYPE_SYMBOL: { | ||
81 | // printf(":%.*s", (int)array_size(obj.symbol), obj.symbol); | ||
82 | } break; | ||
83 | case OBJ_TYPE_PAIR: { | ||
84 | // printf("("); | ||
85 | // display_pair(obj); | ||
86 | // printf(")"); | ||
87 | } break; | ||
88 | case OBJ_TYPE_LAMBDA: { | ||
89 | printf("#{procedure}"); | ||
90 | } break; | ||
91 | case OBJ_TYPE_ERR: { | ||
92 | printf("#{error}"); | ||
93 | } break; | ||
94 | } | ||
95 | return; | ||
25 | } | 96 | } |
26 | 97 | ||
27 | #endif // BDL_OBJECTS_H | 98 | #endif // BDL_OBJECTS_H |
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index 3a9b5af..581f093 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h | |||
@@ -21,7 +21,7 @@ typedef struct VM { | |||
21 | void vm_init(VM *vm); | 21 | void vm_init(VM *vm); |
22 | void vm_free(VM *vm); | 22 | void vm_free(VM *vm); |
23 | void vm_reset(VM *vm); | 23 | void vm_reset(VM *vm); |
24 | void vm_interpret(VM vm, Chunk *chunk); | 24 | void vm_interpret(VM *vm, Chunk *chunk); |
25 | 25 | ||
26 | void | 26 | void |
27 | vm_init(VM *vm) { | 27 | vm_init(VM *vm) { |
@@ -41,11 +41,11 @@ vm_reset(VM *vm) { | |||
41 | } | 41 | } |
42 | 42 | ||
43 | void | 43 | void |
44 | vm_interpret(VM vm, Chunk *chunk) { | 44 | vm_interpret(VM *vm, Chunk *chunk) { |
45 | vm.chunk = chunk; | 45 | vm->chunk = chunk; |
46 | vm.pc = vm.chunk->code; | 46 | vm->pc = vm->chunk->code; |
47 | 47 | ||
48 | if (vm.chunk->code == NULL || array_size(vm.chunk->code) == 0) { | 48 | if (vm->chunk->code == NULL || array_size(vm->chunk->code) == 0) { |
49 | error_push((Error){ | 49 | error_push((Error){ |
50 | .type = ERR_TYPE_RUNTIME, | 50 | .type = ERR_TYPE_RUNTIME, |
51 | .value = ERR_EMPTY_CHUNK, | 51 | .value = ERR_EMPTY_CHUNK, |
@@ -53,53 +53,53 @@ vm_interpret(VM vm, Chunk *chunk) { | |||
53 | return; | 53 | return; |
54 | } | 54 | } |
55 | 55 | ||
56 | u8 *last = vm.chunk->code + array_size(vm.chunk->code); | 56 | u8 *last = vm->chunk->code + array_size(vm->chunk->code); |
57 | while (vm.pc < last) { | 57 | while (vm->pc < last) { |
58 | #ifdef DEBUG_TRACE_EXECUTION | 58 | #ifdef DEBUG_TRACE_EXECUTION |
59 | printf("stack: [ "); | 59 | printf("stack: [ "); |
60 | for (size_t i = 0; i < array_size(vm.stack); i++) { | 60 | for (size_t i = 0; i < array_size(vm->stack); i++) { |
61 | display(vm.stack[i]); | 61 | display(vm->stack[i]); |
62 | if (i < array_size(vm.stack) - 1) { | 62 | if (i < array_size(vm->stack) - 1) { |
63 | printf(" | "); | 63 | printf(" | "); |
64 | } | 64 | } |
65 | } | 65 | } |
66 | printf(" ]\nop: "); | 66 | printf(" ]\nop: "); |
67 | disassemble_instruction(vm.chunk, (vm.pc - vm.chunk->code)); | 67 | disassemble_instruction(vm->chunk, (vm->pc - vm->chunk->code)); |
68 | #endif | 68 | #endif |
69 | u8 instruction = *vm.pc++; | 69 | u8 instruction = *vm->pc++; |
70 | switch (instruction) { | 70 | switch (instruction) { |
71 | case OP_CONSTANT: { | 71 | case OP_CONSTANT: { |
72 | u8 constant = *vm.pc++; | 72 | u8 constant = *vm->pc++; |
73 | Object obj = vm.chunk->constants[constant]; | 73 | Object obj = vm->chunk->constants[constant]; |
74 | array_push(vm.stack, obj); | 74 | array_push(vm->stack, obj); |
75 | } break; | 75 | } break; |
76 | case OP_SUM: { | 76 | case OP_SUM: { |
77 | Object a = array_pop(vm.stack); | 77 | ssize_t a = AS_FIXNUM(array_pop(vm->stack)); |
78 | Object b = array_pop(vm.stack); | 78 | ssize_t b = AS_FIXNUM(array_pop(vm->stack)); |
79 | array_push(vm.stack, a + b); | 79 | array_push(vm->stack, FIXNUM_VAL(a + b)); |
80 | } break; | 80 | } break; |
81 | case OP_SUB: { | 81 | case OP_SUB: { |
82 | Object a = array_pop(vm.stack); | 82 | ssize_t a = AS_FIXNUM(array_pop(vm->stack)); |
83 | Object b = array_pop(vm.stack); | 83 | ssize_t b = AS_FIXNUM(array_pop(vm->stack)); |
84 | array_push(vm.stack, b - a); | 84 | array_push(vm->stack, FIXNUM_VAL(b - a)); |
85 | } break; | 85 | } break; |
86 | case OP_MUL: { | 86 | case OP_MUL: { |
87 | Object a = array_pop(vm.stack); | 87 | ssize_t a = AS_FIXNUM(array_pop(vm->stack)); |
88 | Object b = array_pop(vm.stack); | 88 | ssize_t b = AS_FIXNUM(array_pop(vm->stack)); |
89 | array_push(vm.stack, a * b); | 89 | array_push(vm->stack, FIXNUM_VAL(a * b)); |
90 | } break; | 90 | } break; |
91 | case OP_DIV: { | 91 | case OP_DIV: { |
92 | Object a = array_pop(vm.stack); | 92 | ssize_t a = AS_FIXNUM(array_pop(vm->stack)); |
93 | Object b = array_pop(vm.stack); | 93 | ssize_t b = AS_FIXNUM(array_pop(vm->stack)); |
94 | array_push(vm.stack, b / a); | 94 | array_push(vm->stack, FIXNUM_VAL(b / a)); |
95 | } break; | 95 | } break; |
96 | case OP_MOD: { | 96 | case OP_MOD: { |
97 | Object a = array_pop(vm.stack); | 97 | ssize_t a = AS_FIXNUM(array_pop(vm->stack)); |
98 | Object b = array_pop(vm.stack); | 98 | ssize_t b = AS_FIXNUM(array_pop(vm->stack)); |
99 | array_push(vm.stack, a % b); | 99 | array_push(vm->stack, FIXNUM_VAL(a % b)); |
100 | } break; | 100 | } break; |
101 | case OP_RETURN: { | 101 | case OP_RETURN: { |
102 | display(array_pop(vm.stack)); | 102 | display(array_pop(vm->stack)); |
103 | printf("\n"); | 103 | printf("\n"); |
104 | return; | 104 | return; |
105 | } break; | 105 | } break; |
@@ -107,8 +107,8 @@ vm_interpret(VM vm, Chunk *chunk) { | |||
107 | error_push((Error){ | 107 | error_push((Error){ |
108 | .type = ERR_TYPE_RUNTIME, | 108 | .type = ERR_TYPE_RUNTIME, |
109 | .value = ERR_NOT_IMPLEMENTED, | 109 | .value = ERR_NOT_IMPLEMENTED, |
110 | .line = vm.chunk->lines[(vm.pc - vm.chunk->code) - 1].line, | 110 | .line = vm->chunk->lines[(vm->pc - vm->chunk->code) - 1].line, |
111 | .col = vm.chunk->lines[(vm.pc - vm.chunk->code) - 1].col, | 111 | .col = vm->chunk->lines[(vm->pc - vm->chunk->code) - 1].col, |
112 | }); | 112 | }); |
113 | return; | 113 | return; |
114 | } break; | 114 | } break; |
@@ -118,8 +118,8 @@ vm_interpret(VM vm, Chunk *chunk) { | |||
118 | error_push((Error){ | 118 | error_push((Error){ |
119 | .type = ERR_TYPE_RUNTIME, | 119 | .type = ERR_TYPE_RUNTIME, |
120 | .value = ERR_PC_OOB, | 120 | .value = ERR_PC_OOB, |
121 | .line = vm.chunk->lines[0].line, | 121 | .line = vm->chunk->lines[0].line, |
122 | .col = vm.chunk->lines[0].col, | 122 | .col = vm->chunk->lines[0].col, |
123 | }); | 123 | }); |
124 | } | 124 | } |
125 | 125 | ||