From d54e595644fcaf6756d53d368213ad3129c49327 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Mon, 25 Oct 2021 15:46:48 +0200 Subject: Add initial `fun` declaration compilation --- src/bytecode/compiler.h | 57 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 6 deletions(-) (limited to 'src/bytecode/compiler.h') diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index 4130269..2c7827f 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h @@ -14,7 +14,7 @@ Token next_token(Compiler *compiler); Token peek_token(const Compiler *compiler); bool has_next_token(const Compiler *compiler); -Object compile(Token *tokens); +Chunk * compile(Token *tokens); Token peek_token(const Compiler *compiler) { @@ -247,6 +247,49 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { add_code(chunk, op, start.line, start.column); } +void +compile_fun_op(Chunk *chunk, Compiler *compiler, Token start) { + Token name = peek_token(compiler); + if (name.type != TOKEN_SYMBOL) { + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_WRONG_ARG_TYPE, + .line = start.line, + .col = start.column, + }); + return; + } + parse_tree(chunk, compiler); + + // TODO: compile lambda expression. + Object fun = make_lambda(name.value); + // FIXME: skipping arguments for now. Assuming nil. + next_token(compiler); + + // Compile body. + while (has_next_token(compiler)) { + Token tok = peek_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) { + next_token(compiler); + break; + } + parse_tree(fun.chunk, compiler); + } + add_code(fun.chunk, OP_RETURN, start.line, start.column); + + emit_constant(chunk, start, fun); + add_code(chunk, OP_DEF, start.line, start.column); +} + void compile_if_op(Chunk *chunk, Compiler *compiler, Token start) { Token tok = peek_token(compiler); @@ -332,6 +375,7 @@ parse_list(Chunk *chunk, Compiler *compiler, Token start) { case TOKEN_NEWLINE: { compile_list_simple_op(chunk, compiler, start, OP_NEWLINE); } break; case TOKEN_DEF: { compile_declare_op(chunk, compiler, start, OP_DEF); } break; case TOKEN_SET: { compile_declare_op(chunk, compiler, start, OP_SET); } break; + case TOKEN_FUN: { compile_fun_op(chunk, compiler, start); } break; case TOKEN_IF: { compile_if_op(chunk, compiler, start); } break; default: { error_push((Error){ @@ -415,19 +459,20 @@ parse_tree(Chunk *chunk, Compiler *compiler) { return; } -Object +Chunk * compile(Token *tokens) { - Object main = make_lambda((StringView){"main", sizeof("main")}); + Chunk *chunk = NULL; + chunk = NEW_CHUNK("main"); Compiler compiler = (Compiler){ .tokens = tokens, .current = 0, }; Token start_tok = peek_token(&compiler); while (has_next_token(&compiler) && peek_token(&compiler).type != TOKEN_EOF) { - parse_tree(main.chunk, &compiler); + parse_tree(chunk, &compiler); } - add_code(main.chunk, OP_RETURN, start_tok.line, start_tok.column); - return main; + add_code(chunk, OP_RETURN, start_tok.line, start_tok.column); + return chunk; } #endif // BDL_COMPILER_H -- cgit v1.2.1