Compare commits
3 Commits
12f42a86f6
...
f7b470c0b1
Author | SHA1 | Date |
---|---|---|
bog | f7b470c0b1 | |
bog | 29fded5cb9 | |
bog | ea5991732c |
|
@ -16,3 +16,37 @@
|
||||||
;; inner variable
|
;; inner variable
|
||||||
($ (d x) ($ y 3) (+ x y))
|
($ (d x) ($ y 3) (+ x y))
|
||||||
(assert-eq? 7 (d 4))
|
(assert-eq? 7 (d 4))
|
||||||
|
|
||||||
|
;; recursivity
|
||||||
|
($ (e n)
|
||||||
|
(if (eq? 0 n) 1
|
||||||
|
(* n (e (- n 1)))))
|
||||||
|
|
||||||
|
(assert-eq? 120 (e 5))
|
||||||
|
|
||||||
|
;; self keyword
|
||||||
|
(assert-eq? 720 ((-> (x)
|
||||||
|
(if (eq? x 0)
|
||||||
|
1
|
||||||
|
(* x (self (- x 1))))) 6))
|
||||||
|
|
||||||
|
;; inner functions
|
||||||
|
($ (f n)
|
||||||
|
($ (inner n) (+ n 1))
|
||||||
|
(inner (inner n)))
|
||||||
|
|
||||||
|
(assert-eq? 3 (f 1))
|
||||||
|
|
||||||
|
;; return function
|
||||||
|
($ (g)
|
||||||
|
($ (inner n) (* 7 n))
|
||||||
|
inner)
|
||||||
|
|
||||||
|
(assert-eq? 42 ( (g) 6 ))
|
||||||
|
|
||||||
|
;; return lambda
|
||||||
|
($ (h)
|
||||||
|
(-> (n)
|
||||||
|
(* 3 (- n 2))))
|
||||||
|
|
||||||
|
(assert-eq? 15 ( (h) 7 ))
|
||||||
|
|
|
@ -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))
|
19
lib/core.cpp
19
lib/core.cpp
|
@ -1,6 +1,7 @@
|
||||||
#include "../src/Loader.hpp"
|
#include "../src/Loader.hpp"
|
||||||
#include "src/Logger.hpp"
|
#include "src/Logger.hpp"
|
||||||
#include "src/Value.hpp"
|
#include "src/Value.hpp"
|
||||||
|
#include "src/opcodes.hpp"
|
||||||
|
|
||||||
GRINO_ERROR(assertion_error);
|
GRINO_ERROR(assertion_error);
|
||||||
|
|
||||||
|
@ -345,6 +346,24 @@ extern "C" void lib(grino::Loader& loader)
|
||||||
return grino::Value::make_nil(args.back()->loc());
|
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){
|
loader.add_native("eq?", [](auto args){
|
||||||
auto lhs = args.front();
|
auto lhs = args.front();
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,16 @@ namespace grino
|
||||||
m_scope.size());
|
m_scope.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string name = "self";
|
||||||
|
|
||||||
|
if (!m_decl_context.empty())
|
||||||
|
{
|
||||||
|
name = m_decl_context.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
sym.declare(node->loc(), name, get_local_address(),
|
||||||
|
m_scope.size());
|
||||||
|
|
||||||
auto prog = std::make_shared<Program>();
|
auto prog = std::make_shared<Program>();
|
||||||
auto body = node->child(1).lock();
|
auto body = node->child(1).lock();
|
||||||
compile(body, *prog, sym);
|
compile(body, *prog, sym);
|
||||||
|
@ -128,9 +138,12 @@ namespace grino
|
||||||
auto expr = node->child(1).lock();
|
auto expr = node->child(1).lock();
|
||||||
size_t address = get_local_address();
|
size_t address = get_local_address();
|
||||||
|
|
||||||
|
m_decl_context.push_back(ident);
|
||||||
compile(expr, program, sym);
|
compile(expr, program, sym);
|
||||||
|
m_decl_context.pop_back();
|
||||||
|
|
||||||
sym.declare(node->loc(), ident, address, m_scope.size());
|
sym.declare(node->loc(), ident, address, m_scope.size());
|
||||||
|
|
||||||
program.push_instr(OPCODE_STORE_LOCAL, address);
|
program.push_instr(OPCODE_STORE_LOCAL, address);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ namespace grino
|
||||||
explicit Compiler(Logger& logger);
|
explicit Compiler(Logger& logger);
|
||||||
virtual ~Compiler();
|
virtual ~Compiler();
|
||||||
|
|
||||||
|
size_t scope() const { return m_scope.size(); }
|
||||||
|
|
||||||
void compile(std::shared_ptr<Node> node,
|
void compile(std::shared_ptr<Node> node,
|
||||||
Program& program,
|
Program& program,
|
||||||
SymTable& sym);
|
SymTable& sym);
|
||||||
|
@ -33,6 +35,7 @@ namespace grino
|
||||||
std::shared_ptr<StaticFunction>> m_statics;
|
std::shared_ptr<StaticFunction>> m_statics;
|
||||||
|
|
||||||
std::vector<size_t> m_scope;
|
std::vector<size_t> m_scope;
|
||||||
|
std::vector<std::string> m_decl_context;
|
||||||
|
|
||||||
size_t get_local_address();
|
size_t get_local_address();
|
||||||
void enter_scope(bool reset=false);
|
void enter_scope(bool reset=false);
|
||||||
|
|
|
@ -127,7 +127,8 @@ namespace grino
|
||||||
args.insert(std::begin(args), program().constant(pop()));
|
args.insert(std::begin(args), program().constant(pop()));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ref = program().constant(pop())->as_ref();
|
auto ref_val = program().constant(pop());
|
||||||
|
size_t ref = ref_val->as_ref();
|
||||||
auto fun = heap(ref)->as_function();
|
auto fun = heap(ref)->as_function();
|
||||||
|
|
||||||
if (fun->is_native())
|
if (fun->is_native())
|
||||||
|
@ -149,6 +150,8 @@ namespace grino
|
||||||
set_local(i, args[i]);
|
set_local(i, args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_local(args.size(), ref_val);
|
||||||
|
|
||||||
m_pc = 0;
|
m_pc = 0;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
Loading…
Reference in New Issue