From 583e0b431a6581206368968d56287a858d53b10a Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 26 Oct 2021 13:34:44 +0200 Subject: Add initial parameter support for function calls --- src/bytecode/compiler.h | 83 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 18 deletions(-) (limited to 'src/bytecode/compiler.h') 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) { break; } parse_tree(chunk, compiler); - if (tok.type == TOKEN_SYMBOL) { - add_code(chunk, OP_GET, tok.line, tok.column); - } n++; } emit_constant(chunk, start, FIXNUM_VAL(n)); @@ -142,9 +139,6 @@ compile_list_unary_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { return; } parse_tree(chunk, compiler); - if (tok.type == TOKEN_SYMBOL) { - add_code(chunk, OP_GET, tok.line, tok.column); - } add_code(chunk, op, start.line, start.column); n++; if (n > 1) { @@ -231,9 +225,6 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { return; } parse_tree(chunk, compiler); - if (expr.type == TOKEN_SYMBOL) { - add_code(chunk, OP_GET, expr.line, expr.column); - } if (peek_token(compiler).type != TOKEN_RPAREN) { error_push((Error){ .type = ERR_TYPE_COMPILER, @@ -250,8 +241,44 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { void compile_lambda(Chunk *chunk, Compiler *compiler, Token start, StringView name) { Object fun = make_lambda(name); - // FIXME: skipping arguments for now. Assuming nil. - next_token(compiler); + + // Prepeare parameters. + Token tok = next_token(compiler); + if (tok.type == TOKEN_LPAREN){ + while (has_next_token(compiler)) { + Token tok = next_token(compiler); + if (tok.type == TOKEN_EOF) { + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_UNBALANCED_PAREN, + .line = start.line, + .col = start.column, + }); + return; + } + if (tok.type == TOKEN_RPAREN) { + break; + } + if (tok.type != TOKEN_SYMBOL) { + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_WRONG_ARG_TYPE, + .line = tok.line, + .col = tok.column, + }); + return; + } + array_push(fun.chunk->params, tok.value); + } + } else if (tok.type != TOKEN_NIL) { + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_WRONG_ARG_TYPE, + .line = tok.line, + .col = tok.column, + }); + return; + } // Compile body. while (has_next_token(compiler)) { @@ -297,6 +324,7 @@ compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) { // FIXME: skipping arguments for now. Assuming nil. // Compile body. + size_t n = 0; while (has_next_token(compiler)) { Token tok = peek_token(compiler); if (tok.type == TOKEN_EOF) { @@ -312,6 +340,7 @@ compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) { next_token(compiler); break; } + parse_tree(chunk, compiler); } if (name.type == TOKEN_SYMBOL) { Object obj = make_symbol(name.value); @@ -471,8 +500,24 @@ parse_tree(Chunk *chunk, Compiler *compiler) { return; } break; case TOKEN_SYMBOL: { - Object obj = make_symbol(tok.value); - emit_constant(chunk, tok, obj); + bool found = false; + size_t idx = 0; + // NOTE: This is dumb and potentially slow. + for (size_t i = 0; i < array_size(chunk->params); i++) { + if (sv_equal(&tok.value, &chunk->params[i])) { + found = true; + idx = i; + break; + } + } + if (!found) { + Object obj = make_symbol(tok.value); + emit_constant(chunk, tok, obj); + return; + } + + add_code(chunk, OP_LOCAL, tok.line, tok.column); + add_code(chunk, idx, tok.line, tok.column); return; } break; case TOKEN_NIL: { @@ -500,14 +545,16 @@ compile(Token *tokens) { .tokens = tokens, .current = 0, }; - Token start_tok = peek_token(&compiler); - while (has_next_token(&compiler) && peek_token(&compiler).type != TOKEN_EOF) { + Token main_start = peek_token(&compiler); + while (has_next_token(&compiler)) { + Token start = peek_token(&compiler); parse_tree(chunk, &compiler); - if (peek_token(&compiler).type != TOKEN_EOF) { - add_code(chunk, OP_DROP, start_tok.line, start_tok.column); + if (peek_token(&compiler).type == TOKEN_EOF) { + break; } + add_code(chunk, OP_DROP, start.line, start.column); } - add_code(chunk, OP_RETURN, start_tok.line, start_tok.column); + add_code(chunk, OP_RETURN, main_start.line, main_start.column); return chunk; } -- cgit v1.2.1