From f0cd7a3cab56a6f8d7b4520aaa168a271a94d6d4 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 27 Oct 2021 10:43:30 +0200 Subject: Add initial implementation of locals --- src/bytecode/compiler.h | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) (limited to 'src/bytecode/compiler.h') diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index 6a17beb..7497ea7 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h @@ -34,8 +34,8 @@ has_next_token(const Compiler *compiler) { ssize_t find_local_index(Chunk *chunk, Token tok) { // 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])) { + for (size_t i = 0; i < array_size(chunk->locals); i++) { + if (sv_equal(&tok.value, &chunk->locals[i])) { return i; } } @@ -203,9 +203,11 @@ compile_list_simple_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { }); } +#define STR_ARRAY(ARR) (StringView){(ARR), array_size(ARR)} + void compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { - Token name = peek_token(compiler); + Token name = next_token(compiler); if (name.type != TOKEN_SYMBOL) { error_push((Error){ .type = ERR_TYPE_COMPILER, @@ -215,9 +217,29 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { }); return; } - Object obj = make_symbol(name.value); - emit_constant(chunk, name, obj); - next_token(compiler); + // TODO: If we are inside a function and we are using OP_DEF, we just + // declare the local variable directly in the stack. No need for symbols! + // TODO: If we are inside a function and we are using OP_SET, check if the + // local variable has been defined before, if not try to read from the + // globals for setting. + if (sv_equal(&STRING(""), &STR_ARRAY(chunk->name))) { + Object obj = make_symbol(name.value); + emit_constant(chunk, name, obj); + } else { + // TODO: only do this if we are defining! not setting. + // Check if we already have the local + ssize_t idx = find_local_index(chunk, name); + if (idx < 0) { + array_push(chunk->locals, name.value); + idx = array_size(chunk->locals) - 1; + } + if (op == OP_DEF) { + op = OP_DEF_LOCAL; + } else if (op == OP_SET) { + op = OP_SET_LOCAL; + } + emit_constant(chunk, name, FIXNUM_VAL(idx)); + } Token tok = peek_token(compiler); if (name.type == TOKEN_EOF || tok.type == TOKEN_EOF) { @@ -282,7 +304,19 @@ compile_lambda(Chunk *chunk, Compiler *compiler, Token start, StringView name) { }); return; } + // Check if parameters name already exists. + ssize_t idx = find_local_index(fun.chunk, tok); + if (idx >= 0) { + error_push((Error){ + .type = ERR_TYPE_COMPILER, + .value = ERR_AMBIGUOUS_PARAMS, + .line = tok.line, + .col = tok.column, + }); + return; + } array_push(fun.chunk->params, tok.value); + array_push(fun.chunk->locals, tok.value); } } else if (tok.type != TOKEN_NIL) { error_push((Error){ @@ -549,7 +583,7 @@ parse_tree(Chunk *chunk, Compiler *compiler) { Chunk * compile(Token *tokens) { Chunk *chunk = NULL; - chunk = NEW_CHUNK("main"); + chunk = NEW_CHUNK(""); Compiler compiler = (Compiler){ .tokens = tokens, .current = 0, -- cgit v1.2.1