aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-23 13:01:10 +0200
committerBad Diode <bd@badd10de.dev>2021-10-23 13:01:10 +0200
commit928a58ad7977c0e2e445fd9c16db5726cda789e0 (patch)
treecfa97b293213550253b268c59100e37f9246b4f1 /src/bytecode
parent9bb350e99370009a18df3c3b8f512d2c11168978 (diff)
downloadbdl-928a58ad7977c0e2e445fd9c16db5726cda789e0.tar.gz
bdl-928a58ad7977c0e2e445fd9c16db5726cda789e0.zip
Add (buggy) initial compilation of arithmetic ops
Diffstat (limited to 'src/bytecode')
-rwxr-xr-x[-rw-r--r--]src/bytecode/chunk.h5
-rwxr-xr-x[-rw-r--r--]src/bytecode/compiler.h204
-rwxr-xr-x[-rw-r--r--]src/bytecode/darray.h0
-rwxr-xr-x[-rw-r--r--]src/bytecode/debug.h0
-rwxr-xr-x[-rw-r--r--]src/bytecode/errors.c0
-rwxr-xr-x[-rw-r--r--]src/bytecode/errors.h0
-rwxr-xr-x[-rw-r--r--]src/bytecode/lexer.c4
-rwxr-xr-x[-rw-r--r--]src/bytecode/lexer.h2
-rwxr-xr-x[-rw-r--r--]src/bytecode/main.c0
-rwxr-xr-x[-rw-r--r--]src/bytecode/objects.h0
-rwxr-xr-x[-rw-r--r--]src/bytecode/ops.h0
-rwxr-xr-x[-rw-r--r--]src/bytecode/read_line.c0
-rwxr-xr-x[-rw-r--r--]src/bytecode/read_line.h0
-rwxr-xr-x[-rw-r--r--]src/bytecode/string_view.c0
-rwxr-xr-x[-rw-r--r--]src/bytecode/string_view.h0
-rwxr-xr-x[-rw-r--r--]src/bytecode/types.h0
-rwxr-xr-x[-rw-r--r--]src/bytecode/vm.h4
17 files changed, 207 insertions, 12 deletions
diff --git a/src/bytecode/chunk.h b/src/bytecode/chunk.h
index e3c7383..81fc4cc 100644..100755
--- a/src/bytecode/chunk.h
+++ b/src/bytecode/chunk.h
@@ -46,6 +46,11 @@ add_code(Chunk *chunk, u8 byte, size_t line, size_t col) {
46 46
47size_t 47size_t
48add_constant(Chunk *chunk, Object obj) { 48add_constant(Chunk *chunk, Object obj) {
49 // FIXME?: Since we are using a single byte to store constant indices, we
50 // can only have 256 stored constants. If we need more we may need to add
51 // another instruction OP_CONSTANT_16 to have at least two bytes for
52 // constants. Alternatively, we could make that the default. Either way, for
53 // now it's fine.
49 size_t pos = array_size(chunk->constants); 54 size_t pos = array_size(chunk->constants);
50 array_push(chunk->constants, obj); 55 array_push(chunk->constants, obj);
51 return pos; 56 return pos;
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h
index 6991a86..7ec1ca9 100644..100755
--- a/src/bytecode/compiler.h
+++ b/src/bytecode/compiler.h
@@ -31,21 +31,211 @@ has_next_token(const Visitor *visitor) {
31 return visitor->current < array_size(visitor->tokens); 31 return visitor->current < array_size(visitor->tokens);
32} 32}
33 33
34void
35emit_constant(Chunk *chunk, Token tok, Object obj) {
36 // TODO: Should we deduplicate constants? For example why store a number
37 // more than once instead of reusing the existing index?
38 size_t num_idx = add_constant(chunk, obj);
39 add_code(chunk, OP_CONSTANT, tok.line, tok.column);
40 add_code(chunk, num_idx, tok.line, tok.column);
41}
42
43void
44parse_fixnum(Chunk *chunk, Token tok) {
45 ssize_t num = 0;
46 int sign = 1;
47 for (size_t i = 0; i < tok.value.n; i++) {
48 char c = tok.value.start[i];
49 if (c == '-') {
50 sign = -1;
51 continue;
52 }
53 num = num * 10 + (c - '0');
54 }
55 emit_constant(chunk, tok, num);
56}
57
58void parse_tree(Chunk *chunk, Visitor *vs);
59
60void
61compile_list_primitive(Chunk *chunk, Visitor *vs, Token op_tok) {
62 Ops op;
63 switch (op_tok.type) {
64 case TOKEN_ADD: {
65 emit_constant(chunk, op_tok, 0);
66 op = OP_SUM;
67 } break;
68 case TOKEN_SUB: {
69 // TODO: fetch first element.
70 emit_constant(chunk, op_tok, 0);
71 op = OP_SUB;
72 } break;
73 case TOKEN_MUL: {
74 emit_constant(chunk, op_tok, 1);
75 op = OP_MUL;
76 } break;
77 case TOKEN_DIV: {
78 // TODO: fetch first element.
79 emit_constant(chunk, op_tok, 1);
80 op = OP_DIV;
81 } break;
82 case TOKEN_MOD: {
83 // TODO: fetch first element.
84 emit_constant(chunk, op_tok, 1);
85 op = OP_MOD;
86 } break;
87 default: {
88 } break;
89 }
90 while (has_next_token(vs)) {
91 Token tok = peek_token(vs);
92 if (tok.type == TOKEN_EOF) {
93 error_push((Error){
94 .type = ERR_TYPE_PARSER,
95 .value = ERR_UNBALANCED_PAREN,
96 .line = op_tok.line,
97 .col = op_tok.column,
98 });
99 return;
100 }
101 if (tok.type == TOKEN_RPAREN) {
102 next_token(vs);
103 break;
104 }
105 parse_tree(chunk, vs);
106 add_code(chunk, op, tok.line, tok.column);
107 }
108}
109
110void
111parse_list(Chunk *chunk, Visitor *vs) {
112 if (has_next_token(vs)) {
113 Token tok = next_token(vs);
114 print_token(tok);
115 // TODO: check if is function call.
116 switch (tok.type) {
117 case TOKEN_ADD:
118 case TOKEN_SUB:
119 case TOKEN_MUL:
120 case TOKEN_DIV:
121 case TOKEN_MOD:{
122 compile_list_primitive(chunk, vs, tok);
123 } break;
124 default: {
125 error_push((Error){
126 .type = ERR_TYPE_COMPILER,
127 .value = ERR_OBJ_NOT_CALLABLE,
128 .line = tok.line,
129 .line = tok.column,
130 });
131 } break;
132 }
133 }
134}
135
136void
137parse_tree(Chunk *chunk, Visitor *vs) {
138 Token tok = next_token(vs);
139 switch (tok.type) {
140 case TOKEN_FIXNUM: {
141 parse_fixnum(chunk, tok);
142 return ;
143 } break;
144 case TOKEN_TRUE: {
145 // return obj_true;
146 return;
147 } break;
148 case TOKEN_FALSE: {
149 // return obj_false;
150 return;
151 } break;
152 case TOKEN_RPAREN: {
153 error_push((Error){
154 .type = ERR_TYPE_PARSER,
155 .value = ERR_UNBALANCED_PAREN,
156 .line = tok.line,
157 .col = tok.column,
158 });
159 return;
160 } break;
161 case TOKEN_QUOTE: {
162 // Object *base = make_pair(obj_quote, obj_nil);
163 // base->cdr = make_pair(obj_nil, obj_nil);
164 // push_root(base);
165 // Object *next_obj = parse_tree(vs);
166 // if (next_obj == obj_err) {
167 // return obj_err;
168 // }
169 // base->cdr->car = next_obj;
170 // return base;
171 return;
172 } break;
173 case TOKEN_LPAREN: {
174 parse_list(chunk, vs);
175 // Object *obj = parse_list(vs);
176 // if (obj == obj_err) {
177 // error_push((Error){
178 // .type = ERR_TYPE_PARSER,
179 // .value = ERR_UNBALANCED_PAREN,
180 // .line = tok.line,
181 // .col = tok.column,
182 // });
183 // }
184 // return obj;
185 return;
186 } break;
187 case TOKEN_STRING: {
188 // Object *obj = make_string();
189 // push_root(obj);
190 // append_string(obj, tok.value);
191 // return obj;
192 return;
193 } break;
194 case TOKEN_SYMBOL: {
195 // Object *obj = make_symbol(tok.value);
196 // push_root(obj);
197 // return obj;
198 return;
199 } break;
200 case TOKEN_NIL: {
201 // return obj_nil;
202 return;
203 } break;
204 default: {
205 break;
206 } break;
207 }
208 error_push((Error){
209 .type = ERR_TYPE_PARSER,
210 .value = ERR_EOF_REACHED,
211 .line = tok.line,
212 .col = tok.column,
213 });
214 return;
215}
216
34Chunk * 217Chunk *
35compile(Token *tokens) { 218compile(Token *tokens) {
36 Chunk *chunk = NULL; 219 Chunk *chunk = NULL;
37 chunk = chunk_init(); 220 chunk = chunk_init();
221 Visitor visitor = (Visitor){
222 .tokens = tokens,
223 .current = 0,
224 };
225 while (has_next_token(&visitor) && peek_token(&visitor).type != TOKEN_EOF) {
226 parse_tree(chunk, &visitor);
227 }
38 // error_push((Error){ 228 // error_push((Error){
39 // .type = ERR_TYPE_COMPILER, 229 // .type = ERR_TYPE_COMPILER,
40 // .value = ERR_UNKNOWN, 230 // .value = ERR_UNKNOWN,
41 // }); 231 // });
42 size_t const_a = add_constant(chunk, 7); 232 // size_t const_a = add_constant(chunk, 7);
43 add_code(chunk, OP_CONSTANT, 1, 1); 233 // add_code(chunk, OP_CONSTANT, 1, 1);
44 add_code(chunk, const_a, 1, 1); 234 // add_code(chunk, const_a, 1, 1);
45 size_t const_b = add_constant(chunk, 2); 235 // size_t const_b = add_constant(chunk, 2);
46 add_code(chunk, OP_CONSTANT, 1, 2); 236 // add_code(chunk, OP_CONSTANT, 1, 2);
47 add_code(chunk, const_b, 1, 2); 237 // add_code(chunk, const_b, 1, 2);
48 add_code(chunk, OP_MOD, 1, 3); 238 // add_code(chunk, OP_MOD, 1, 3);
49 add_code(chunk, OP_RETURN, 1, 1); 239 add_code(chunk, OP_RETURN, 1, 1);
50 return chunk; 240 return chunk;
51} 241}
diff --git a/src/bytecode/darray.h b/src/bytecode/darray.h
index db6234d..db6234d 100644..100755
--- a/src/bytecode/darray.h
+++ b/src/bytecode/darray.h
diff --git a/src/bytecode/debug.h b/src/bytecode/debug.h
index 05f9d8e..05f9d8e 100644..100755
--- a/src/bytecode/debug.h
+++ b/src/bytecode/debug.h
diff --git a/src/bytecode/errors.c b/src/bytecode/errors.c
index c2ab77f..c2ab77f 100644..100755
--- a/src/bytecode/errors.c
+++ b/src/bytecode/errors.c
diff --git a/src/bytecode/errors.h b/src/bytecode/errors.h
index 7b3446e..7b3446e 100644..100755
--- a/src/bytecode/errors.h
+++ b/src/bytecode/errors.h
diff --git a/src/bytecode/lexer.c b/src/bytecode/lexer.c
index 82cdf22..bc2dd9d 100644..100755
--- a/src/bytecode/lexer.c
+++ b/src/bytecode/lexer.c
@@ -17,7 +17,7 @@ static const char* token_str[] = {
17 [TOKEN_FUN] = "TOKEN_FUN", 17 [TOKEN_FUN] = "TOKEN_FUN",
18 [TOKEN_LAMBDA] = "TOKEN_LAMBDA", 18 [TOKEN_LAMBDA] = "TOKEN_LAMBDA",
19 [TOKEN_ADD] = "TOKEN_ADD", 19 [TOKEN_ADD] = "TOKEN_ADD",
20 [TOKEN_MIN] = "TOKEN_MIN", 20 [TOKEN_SUB] = "TOKEN_SUB",
21 [TOKEN_MUL] = "TOKEN_MUL", 21 [TOKEN_MUL] = "TOKEN_MUL",
22 [TOKEN_DIV] = "TOKEN_DIV", 22 [TOKEN_DIV] = "TOKEN_DIV",
23 [TOKEN_MOD] = "TOKEN_MOD", 23 [TOKEN_MOD] = "TOKEN_MOD",
@@ -147,7 +147,7 @@ find_primitive_type(const StringView value) {
147 if (TOKEN_IS_KEYWORD(value, "fun")) { return TOKEN_FUN; } 147 if (TOKEN_IS_KEYWORD(value, "fun")) { return TOKEN_FUN; }
148 if (TOKEN_IS_KEYWORD(value, "lambda")) { return TOKEN_LAMBDA; } 148 if (TOKEN_IS_KEYWORD(value, "lambda")) { return TOKEN_LAMBDA; }
149 if (TOKEN_IS_KEYWORD(value, "+")) { return TOKEN_ADD; } 149 if (TOKEN_IS_KEYWORD(value, "+")) { return TOKEN_ADD; }
150 if (TOKEN_IS_KEYWORD(value, "-")) { return TOKEN_MIN; } 150 if (TOKEN_IS_KEYWORD(value, "-")) { return TOKEN_SUB; }
151 if (TOKEN_IS_KEYWORD(value, "*")) { return TOKEN_MUL; } 151 if (TOKEN_IS_KEYWORD(value, "*")) { return TOKEN_MUL; }
152 if (TOKEN_IS_KEYWORD(value, "/")) { return TOKEN_DIV; } 152 if (TOKEN_IS_KEYWORD(value, "/")) { return TOKEN_DIV; }
153 if (TOKEN_IS_KEYWORD(value, "%")) { return TOKEN_MOD; } 153 if (TOKEN_IS_KEYWORD(value, "%")) { return TOKEN_MOD; }
diff --git a/src/bytecode/lexer.h b/src/bytecode/lexer.h
index a19ac11..47fd384 100644..100755
--- a/src/bytecode/lexer.h
+++ b/src/bytecode/lexer.h
@@ -28,7 +28,7 @@ typedef enum TokenType {
28 28
29 // Arithmetic. 29 // Arithmetic.
30 TOKEN_ADD, 30 TOKEN_ADD,
31 TOKEN_MIN, 31 TOKEN_SUB,
32 TOKEN_MUL, 32 TOKEN_MUL,
33 TOKEN_DIV, 33 TOKEN_DIV,
34 TOKEN_MOD, 34 TOKEN_MOD,
diff --git a/src/bytecode/main.c b/src/bytecode/main.c
index d6cb5d3..d6cb5d3 100644..100755
--- a/src/bytecode/main.c
+++ b/src/bytecode/main.c
diff --git a/src/bytecode/objects.h b/src/bytecode/objects.h
index 9bfa2cf..9bfa2cf 100644..100755
--- a/src/bytecode/objects.h
+++ b/src/bytecode/objects.h
diff --git a/src/bytecode/ops.h b/src/bytecode/ops.h
index b58631f..b58631f 100644..100755
--- a/src/bytecode/ops.h
+++ b/src/bytecode/ops.h
diff --git a/src/bytecode/read_line.c b/src/bytecode/read_line.c
index 03146ad..03146ad 100644..100755
--- a/src/bytecode/read_line.c
+++ b/src/bytecode/read_line.c
diff --git a/src/bytecode/read_line.h b/src/bytecode/read_line.h
index 160bce0..160bce0 100644..100755
--- a/src/bytecode/read_line.h
+++ b/src/bytecode/read_line.h
diff --git a/src/bytecode/string_view.c b/src/bytecode/string_view.c
index 39fabe9..39fabe9 100644..100755
--- a/src/bytecode/string_view.c
+++ b/src/bytecode/string_view.c
diff --git a/src/bytecode/string_view.h b/src/bytecode/string_view.h
index 42273ab..42273ab 100644..100755
--- a/src/bytecode/string_view.h
+++ b/src/bytecode/string_view.h
diff --git a/src/bytecode/types.h b/src/bytecode/types.h
index dc21756..dc21756 100644..100755
--- a/src/bytecode/types.h
+++ b/src/bytecode/types.h
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h
index f9e64d1..3a9b5af 100644..100755
--- a/src/bytecode/vm.h
+++ b/src/bytecode/vm.h
@@ -81,7 +81,7 @@ vm_interpret(VM vm, Chunk *chunk) {
81 case OP_SUB: { 81 case OP_SUB: {
82 Object a = array_pop(vm.stack); 82 Object a = array_pop(vm.stack);
83 Object b = array_pop(vm.stack); 83 Object b = array_pop(vm.stack);
84 array_push(vm.stack, a - b); 84 array_push(vm.stack, b - a);
85 } break; 85 } break;
86 case OP_MUL: { 86 case OP_MUL: {
87 Object a = array_pop(vm.stack); 87 Object a = array_pop(vm.stack);
@@ -91,7 +91,7 @@ vm_interpret(VM vm, Chunk *chunk) {
91 case OP_DIV: { 91 case OP_DIV: {
92 Object a = array_pop(vm.stack); 92 Object a = array_pop(vm.stack);
93 Object b = array_pop(vm.stack); 93 Object b = array_pop(vm.stack);
94 array_push(vm.stack, a / b); 94 array_push(vm.stack, b / a);
95 } break; 95 } break;
96 case OP_MOD: { 96 case OP_MOD: {
97 Object a = array_pop(vm.stack); 97 Object a = array_pop(vm.stack);