diff --git a/anonymous-function-test.ar b/anonymous-function-test.ar index 00bae09..2be611c 100644 --- a/anonymous-function-test.ar +++ b/anonymous-function-test.ar @@ -1 +1,3 @@ -term.log(((x)=x*x)()) \ No newline at end of file +let i = 1000000 +while (i) do + i=i-1 \ No newline at end of file diff --git a/src/runtime/assignment/assignment.c b/src/runtime/assignment/assignment.c new file mode 100644 index 0000000..d000923 --- /dev/null +++ b/src/runtime/assignment/assignment.c @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2025 William Bell + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "assignment.h" + +ArErr runtime_assignment(Translated *translated, RuntimeState *state, + struct Stack *stack) { + int64_t length = pop_bytecode(translated, state); + int64_t offset = pop_bytecode(translated, state); + int64_t prehash = pop_bytecode(translated, state); + int64_t from_register = pop_byte(translated, state); + uint64_t hash = + runtime_hash(arena_get(&translated->constants, offset), length, prehash); + ArgonObject *key = + new_string_object(arena_get(&translated->constants, offset), length); + for (Stack *current_stack = stack; current_stack; + current_stack = current_stack->prev) { + ArgonObject *exists = hashmap_lookup_GC(current_stack->scope, hash); + if (exists) { + hashmap_insert_GC(current_stack->scope, hash, key, + state->registers[from_register], 0); + } + } + hashmap_insert_GC(stack->scope, hash, key, state->registers[from_register], + 0); + return no_err; +} \ No newline at end of file diff --git a/src/runtime/assignment/assignment.h b/src/runtime/assignment/assignment.h new file mode 100644 index 0000000..78fdcde --- /dev/null +++ b/src/runtime/assignment/assignment.h @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: 2025 William Bell + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#ifndef runtime_assignment_H +#define runtime_assignment_H +#include "../runtime.h" +#include "../objects/string/string.h" + +ArErr runtime_assignment(Translated *translated, RuntimeState *state, + struct Stack *stack); + +#endif // runtime_assignment_H \ No newline at end of file diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 5d938d6..8e6c105 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -12,6 +12,7 @@ #include "access/access.h" #include "call/call.h" #include "declaration/declaration.h" +#include "assignment/assignment.h" #include "internals/hashmap/hashmap.h" #include "objects/functions/functions.h" #include "objects/literals/literals.h" @@ -679,6 +680,8 @@ ArErr run_instruction(Translated *translated, RuntimeState *state, return load_variable(translated, state, *stack); case OP_DECLARE: return runtime_declaration(translated, state, *stack); + case OP_ASSIGN: + return runtime_assignment(translated, state, *stack); case OP_BOOL:; ArErr err = no_err; uint8_t to_register = pop_byte(translated, state); diff --git a/src/translator/assignment/assignment.c b/src/translator/assignment/assignment.c new file mode 100644 index 0000000..66c1761 --- /dev/null +++ b/src/translator/assignment/assignment.c @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2025 William Bell + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "assignment.h" +#include "../../hash_data/hash_data.h" +#include "../../parser/assignable/identifier/identifier.h" +#include "../translator.h" +#include +#include +#include +#include + +size_t translate_parsed_assignment(Translated *translated, + ParsedAssign *assignment, ArErr *err) { + printf("bruh\n"); + set_registers(translated, 1); + DArray *old_return_jumps = translated->return_jumps; + translated->return_jumps = NULL; + size_t first = translate_parsed(translated, assignment->from, err); + if (err->exists) + return first; + switch (assignment->to->type) { + case AST_IDENTIFIER:; + ParsedIdentifier *identifier = assignment->to->data; + size_t length = strlen(identifier->name); + size_t offset = + arena_push(&translated->constants, identifier->name, length); + + push_instruction_byte(translated, OP_SOURCE_LOCATION); + push_instruction_code(translated, identifier->line); + push_instruction_code(translated, identifier->column); + push_instruction_code(translated, length); + + push_instruction_byte(translated, OP_ASSIGN); + push_instruction_code(translated, length); + push_instruction_code(translated, offset); + push_instruction_code(translated, + siphash64_bytes(identifier->name, length, + siphash_key_fixed_for_translator)); + push_instruction_byte(translated, 0); + break; + default: + fprintf(stderr, "panic: freeing NULL pointer\n"); + exit(EXIT_FAILURE); + } + translated->return_jumps = old_return_jumps; + return first; +} \ No newline at end of file diff --git a/src/translator/assignment/assignment.h b/src/translator/assignment/assignment.h new file mode 100644 index 0000000..9d32a05 --- /dev/null +++ b/src/translator/assignment/assignment.h @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: 2025 William Bell + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#ifndef BYTECODE_ASSIGNMENT_H +#define BYTECODE_ASSIGNMENT_H +#include "../translator.h" +#include "../../parser/assignable/assign/assign.h" + +size_t translate_parsed_assignment(Translated *translated, + ParsedAssign *assignment, ArErr *err); + +#endif \ No newline at end of file diff --git a/src/translator/bytecode_spec.md b/src/translator/bytecode_spec.md index e9bf711..730a92f 100644 --- a/src/translator/bytecode_spec.md +++ b/src/translator/bytecode_spec.md @@ -29,6 +29,17 @@ this operation takes 3 operands. 1. the fixed hash of the variable name. 1. the register of the given value (*) +## OP_ASSIGN + +assigns to a variable in the stack. if the variable doesnt exist on the stack, it is automatically declared on the current scope. + +this operation takes 3 operands. + +1. the length of the variable name. +1. the offset in the constant buffer of the variable name. +1. the fixed hash of the variable name. +1. the register of the given value (*) + ## OP_LOAD_NULL sets a given register to null. diff --git a/src/translator/translator.c b/src/translator/translator.c index 7e2843d..5fe3f19 100644 --- a/src/translator/translator.c +++ b/src/translator/translator.c @@ -9,6 +9,7 @@ #include "access/access.h" #include "call/call.h" #include "declaration/declaration.h" +#include "assignment/assignment.h" #include "dowrap/dowrap.h" #include "function/function.h" #include "identifier/identifier.h" @@ -165,6 +166,9 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue, case AST_OPERATION: return translate_operation(translated, (ParsedOperation *)parsedValue->data, err); + case AST_ASSIGN: + return translate_parsed_assignment(translated, + (ParsedAssign *)parsedValue->data, err); } return 0; } diff --git a/src/translator/translator.h b/src/translator/translator.h index 3f5f05d..8cbe9af 100644 --- a/src/translator/translator.h +++ b/src/translator/translator.h @@ -35,7 +35,8 @@ typedef enum { OP_LOAD_ADDITION_FUNCTION, OP_LOAD_SUBTRACTION_FUNCTION, OP_LOAD_MULTIPLY_FUNCTION, - OP_LOAD_DIVISION_FUNCTION + OP_LOAD_DIVISION_FUNCTION, + OP_ASSIGN } OperationType; void arena_resize(ConstantArena *arena, size_t new_size);