diff --git a/examples/fun.gri b/examples/fun.gri index aeb7608..ea31b0b 100644 --- a/examples/fun.gri +++ b/examples/fun.gri @@ -49,4 +49,4 @@ (-> (n) (* 3 (- n 2)))) -(assert-eq? 15 ( (h) 7 )) \ No newline at end of file +(assert-eq? 15 ( (h) 7 )) diff --git a/examples/set.gri b/examples/set.gri new file mode 100644 index 0000000..84ed350 --- /dev/null +++ b/examples/set.gri @@ -0,0 +1,10 @@ +($ a 1) +(set! a 2) +(assert-eq? 2 a ) + +($ (b x) (+ x 1)) +($ (c x) (* x 2)) +($ d b) +(assert-eq? 3 (d 2)) +(set! d c) +(assert-eq? 4 (d 2)) \ No newline at end of file diff --git a/lib/core.cpp b/lib/core.cpp index fe103ef..e67810e 100644 --- a/lib/core.cpp +++ b/lib/core.cpp @@ -1,6 +1,7 @@ #include "../src/Loader.hpp" #include "src/Logger.hpp" #include "src/Value.hpp" +#include "src/opcodes.hpp" GRINO_ERROR(assertion_error); @@ -345,6 +346,24 @@ extern "C" void lib(grino::Loader& loader) return grino::Value::make_nil(args.back()->loc()); }); + loader.add_static("set!", [](auto& compiler, + auto node, + auto& program, + auto& sym){ + std::string ident = node->child(1).lock()->repr(); + auto expr = node->child(2).lock(); + + auto entry = sym.find(ident, compiler.scope()); + + if (entry) + { + compiler.compile(expr, program, sym); + program.push_instr(grino::OPCODE_STORE_LOCAL, entry->addr); + } + + program.push_value(grino::Value::make_nil(node->loc())); + }); + loader.add_native("eq?", [](auto args){ auto lhs = args.front(); diff --git a/src/Compiler.hpp b/src/Compiler.hpp index 4e1f555..5b505d2 100644 --- a/src/Compiler.hpp +++ b/src/Compiler.hpp @@ -20,6 +20,8 @@ namespace grino explicit Compiler(Logger& logger); virtual ~Compiler(); + size_t scope() const { return m_scope.size(); } + void compile(std::shared_ptr node, Program& program, SymTable& sym);