diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-26 13:34:44 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-26 13:34:44 +0200 |
commit | 583e0b431a6581206368968d56287a858d53b10a (patch) | |
tree | 1259b57f9890184f2a0ffbd76471d0f4f65372ac /src/bytecode/compiler.h | |
parent | 19fb6b2d97a970f94854cd17a58639b72d35c052 (diff) | |
download | bdl-583e0b431a6581206368968d56287a858d53b10a.tar.gz bdl-583e0b431a6581206368968d56287a858d53b10a.zip |
Add initial parameter support for function calls
Diffstat (limited to 'src/bytecode/compiler.h')
-rwxr-xr-x | src/bytecode/compiler.h | 83 |
1 files changed, 65 insertions, 18 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index e20b4f1..9389ab4 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h | |||
@@ -106,9 +106,6 @@ compile_list_binary_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { | |||
106 | break; | 106 | break; |
107 | } | 107 | } |
108 | parse_tree(chunk, compiler); | 108 | parse_tree(chunk, compiler); |
109 | if (tok.type == TOKEN_SYMBOL) { | ||
110 | add_code(chunk, OP_GET, tok.line, tok.column); | ||
111 | } | ||
112 | n++; | 109 | n++; |
113 | } | 110 | } |
114 | emit_constant(chunk, start, FIXNUM_VAL(n)); | 111 | emit_constant(chunk, start, FIXNUM_VAL(n)); |
@@ -142,9 +139,6 @@ compile_list_unary_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { | |||
142 | return; | 139 | return; |
143 | } | 140 | } |
144 | parse_tree(chunk, compiler); | 141 | parse_tree(chunk, compiler); |
145 | if (tok.type == TOKEN_SYMBOL) { | ||
146 | add_code(chunk, OP_GET, tok.line, tok.column); | ||
147 | } | ||
148 | add_code(chunk, op, start.line, start.column); | 142 | add_code(chunk, op, start.line, start.column); |
149 | n++; | 143 | n++; |
150 | if (n > 1) { | 144 | if (n > 1) { |
@@ -231,9 +225,6 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { | |||
231 | return; | 225 | return; |
232 | } | 226 | } |
233 | parse_tree(chunk, compiler); | 227 | parse_tree(chunk, compiler); |
234 | if (expr.type == TOKEN_SYMBOL) { | ||
235 | add_code(chunk, OP_GET, expr.line, expr.column); | ||
236 | } | ||
237 | if (peek_token(compiler).type != TOKEN_RPAREN) { | 228 | if (peek_token(compiler).type != TOKEN_RPAREN) { |
238 | error_push((Error){ | 229 | error_push((Error){ |
239 | .type = ERR_TYPE_COMPILER, | 230 | .type = ERR_TYPE_COMPILER, |
@@ -250,8 +241,44 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { | |||
250 | void | 241 | void |
251 | compile_lambda(Chunk *chunk, Compiler *compiler, Token start, StringView name) { | 242 | compile_lambda(Chunk *chunk, Compiler *compiler, Token start, StringView name) { |
252 | Object fun = make_lambda(name); | 243 | Object fun = make_lambda(name); |
253 | // FIXME: skipping arguments for now. Assuming nil. | 244 | |
254 | next_token(compiler); | 245 | // Prepeare parameters. |
246 | Token tok = next_token(compiler); | ||
247 | if (tok.type == TOKEN_LPAREN){ | ||
248 | while (has_next_token(compiler)) { | ||
249 | Token tok = next_token(compiler); | ||
250 | if (tok.type == TOKEN_EOF) { | ||
251 | error_push((Error){ | ||
252 | .type = ERR_TYPE_COMPILER, | ||
253 | .value = ERR_UNBALANCED_PAREN, | ||
254 | .line = start.line, | ||
255 | .col = start.column, | ||
256 | }); | ||
257 | return; | ||
258 | } | ||
259 | if (tok.type == TOKEN_RPAREN) { | ||
260 | break; | ||
261 | } | ||
262 | if (tok.type != TOKEN_SYMBOL) { | ||
263 | error_push((Error){ | ||
264 | .type = ERR_TYPE_COMPILER, | ||
265 | .value = ERR_WRONG_ARG_TYPE, | ||
266 | .line = tok.line, | ||
267 | .col = tok.column, | ||
268 | }); | ||
269 | return; | ||
270 | } | ||
271 | array_push(fun.chunk->params, tok.value); | ||
272 | } | ||
273 | } else if (tok.type != TOKEN_NIL) { | ||
274 | error_push((Error){ | ||
275 | .type = ERR_TYPE_COMPILER, | ||
276 | .value = ERR_WRONG_ARG_TYPE, | ||
277 | .line = tok.line, | ||
278 | .col = tok.column, | ||
279 | }); | ||
280 | return; | ||
281 | } | ||
255 | 282 | ||
256 | // Compile body. | 283 | // Compile body. |
257 | while (has_next_token(compiler)) { | 284 | while (has_next_token(compiler)) { |
@@ -297,6 +324,7 @@ compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) { | |||
297 | // FIXME: skipping arguments for now. Assuming nil. | 324 | // FIXME: skipping arguments for now. Assuming nil. |
298 | 325 | ||
299 | // Compile body. | 326 | // Compile body. |
327 | size_t n = 0; | ||
300 | while (has_next_token(compiler)) { | 328 | while (has_next_token(compiler)) { |
301 | Token tok = peek_token(compiler); | 329 | Token tok = peek_token(compiler); |
302 | if (tok.type == TOKEN_EOF) { | 330 | if (tok.type == TOKEN_EOF) { |
@@ -312,6 +340,7 @@ compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) { | |||
312 | next_token(compiler); | 340 | next_token(compiler); |
313 | break; | 341 | break; |
314 | } | 342 | } |
343 | parse_tree(chunk, compiler); | ||
315 | } | 344 | } |
316 | if (name.type == TOKEN_SYMBOL) { | 345 | if (name.type == TOKEN_SYMBOL) { |
317 | Object obj = make_symbol(name.value); | 346 | Object obj = make_symbol(name.value); |
@@ -471,8 +500,24 @@ parse_tree(Chunk *chunk, Compiler *compiler) { | |||
471 | return; | 500 | return; |
472 | } break; | 501 | } break; |
473 | case TOKEN_SYMBOL: { | 502 | case TOKEN_SYMBOL: { |
474 | Object obj = make_symbol(tok.value); | 503 | bool found = false; |
475 | emit_constant(chunk, tok, obj); | 504 | size_t idx = 0; |
505 | // NOTE: This is dumb and potentially slow. | ||
506 | for (size_t i = 0; i < array_size(chunk->params); i++) { | ||
507 | if (sv_equal(&tok.value, &chunk->params[i])) { | ||
508 | found = true; | ||
509 | idx = i; | ||
510 | break; | ||
511 | } | ||
512 | } | ||
513 | if (!found) { | ||
514 | Object obj = make_symbol(tok.value); | ||
515 | emit_constant(chunk, tok, obj); | ||
516 | return; | ||
517 | } | ||
518 | |||
519 | add_code(chunk, OP_LOCAL, tok.line, tok.column); | ||
520 | add_code(chunk, idx, tok.line, tok.column); | ||
476 | return; | 521 | return; |
477 | } break; | 522 | } break; |
478 | case TOKEN_NIL: { | 523 | case TOKEN_NIL: { |
@@ -500,14 +545,16 @@ compile(Token *tokens) { | |||
500 | .tokens = tokens, | 545 | .tokens = tokens, |
501 | .current = 0, | 546 | .current = 0, |
502 | }; | 547 | }; |
503 | Token start_tok = peek_token(&compiler); | 548 | Token main_start = peek_token(&compiler); |
504 | while (has_next_token(&compiler) && peek_token(&compiler).type != TOKEN_EOF) { | 549 | while (has_next_token(&compiler)) { |
550 | Token start = peek_token(&compiler); | ||
505 | parse_tree(chunk, &compiler); | 551 | parse_tree(chunk, &compiler); |
506 | if (peek_token(&compiler).type != TOKEN_EOF) { | 552 | if (peek_token(&compiler).type == TOKEN_EOF) { |
507 | add_code(chunk, OP_DROP, start_tok.line, start_tok.column); | 553 | break; |
508 | } | 554 | } |
555 | add_code(chunk, OP_DROP, start.line, start.column); | ||
509 | } | 556 | } |
510 | add_code(chunk, OP_RETURN, start_tok.line, start_tok.column); | 557 | add_code(chunk, OP_RETURN, main_start.line, main_start.column); |
511 | return chunk; | 558 | return chunk; |
512 | } | 559 | } |
513 | 560 | ||