ADD: if core function.

FIX: block scope.
main
bog 2023-09-12 06:36:55 +02:00
parent ab64ab8007
commit aaeedb1ba9
4 changed files with 59 additions and 2 deletions

View File

@ -12,3 +12,7 @@
;; syntaxic sugar for function declaration ;; syntaxic sugar for function declaration
($ (c n) (* 2 n)) ($ (c n) (* 2 n))
(assert-eq? 18 (c 9)) (assert-eq? 18 (c 9))
;; inner variable
($ (d x) ($ y 3) (+ x y))
(assert-eq? 7 (d 4))

11
examples/if.gri Normal file
View File

@ -0,0 +1,11 @@
(assert-eq? 7 (if true 7 9))
(assert-eq? 9 (if false 7 9))
($ (max x y)
(if (> x y)
x
y
))
(assert-eq? 32 (max 3 32))
(assert-eq? 329 (max 329 32))

View File

@ -4,6 +4,28 @@
GRINO_ERROR(assertion_error); GRINO_ERROR(assertion_error);
extern "C" void lib_flow_control(grino::Loader& loader)
{
loader.add_static("if", [](auto& compiler, auto node, auto& prog, auto& sym) {
auto cond_node = node->child(1).lock();
auto then_node = node->child(2).lock();
auto else_node = node->child(3).lock();
compiler.compile(cond_node, prog, sym);
size_t brf = prog.size();
prog.push_instr(grino::OPCODE_BRF, 0);
compiler.compile(then_node, prog, sym);
size_t br = prog.size();
prog.push_instr(grino::OPCODE_BR, 0);
prog.set_param(brf, prog.size());
compiler.compile(else_node, prog, sym);
prog.set_param(br, prog.size());
});
}
extern "C" void lib_int(grino::Loader& loader) extern "C" void lib_int(grino::Loader& loader)
{ {
loader.add_native("+", [](auto args){ loader.add_native("+", [](auto args){
@ -306,6 +328,7 @@ extern "C" void lib(grino::Loader& loader)
lib_int(loader); lib_int(loader);
lib_cmp(loader); lib_cmp(loader);
lib_bool(loader); lib_bool(loader);
lib_flow_control(loader);
loader.add_native("dump", [](auto args){ loader.add_native("dump", [](auto args){
std::string sep; std::string sep;

View File

@ -30,7 +30,6 @@ namespace grino
} }
} break; } break;
case NODE_BLOCK:
case NODE_BODY: { case NODE_BODY: {
for (size_t i=0; i<node->size(); i++) for (size_t i=0; i<node->size(); i++)
{ {
@ -43,6 +42,26 @@ namespace grino
} }
} break; } break;
case NODE_BLOCK: {
enter_scope();
for (size_t i=0; i<node->size(); i++)
{
compile(node->child(i).lock(), program, sym);
if (i < node->size() - 1)
{
program.push_instr(OPCODE_POP);
}
}
std::cout << "-------------------------" << std::endl;
std::cout << sym.string() << std::endl;
leave_scope();
sym.purge(m_scope.size());
} break;
case NODE_FUNCALL: { case NODE_FUNCALL: {
std::string ident = node->child(0).lock()->repr(); std::string ident = node->child(0).lock()->repr();