✨ recursive functions.
parent
e786b8f756
commit
968f7a312d
|
@ -2,7 +2,9 @@
|
|||
#include "lib/commons.h"
|
||||
#include "lib/mod.h"
|
||||
#include "lib/prepass.h"
|
||||
#include "lib/program.h"
|
||||
#include "lib/sym.h"
|
||||
#include "lib/tysy.h"
|
||||
#include "node.h"
|
||||
#include "fun.h"
|
||||
|
||||
|
@ -355,6 +357,8 @@ int compiler_run(compiler_t* compiler, node_t* node, program_t* program)
|
|||
fun_t* fun = malloc(sizeof(fun_t));
|
||||
fun_init(fun, (struct tysy*) compiler->tysy, compiler->err);
|
||||
|
||||
value_t* value = tysy_new_fun(compiler->tysy, fun, node->line);
|
||||
|
||||
sym_entry_t* entry = sym_try_find_by_name(compiler->sym,
|
||||
fun_name,
|
||||
compiler->scope,
|
||||
|
@ -378,6 +382,14 @@ int compiler_run(compiler_t* compiler, node_t* node, program_t* program)
|
|||
&tysolver, compiler->err);
|
||||
|
||||
prepass_run(&pre, (node_t*) node->children.data[2]);
|
||||
|
||||
// self
|
||||
sym_declare((sym_t*) fun->sym, fun_name,
|
||||
tysy_try_find_type(comp.tysy, "fun"),
|
||||
comp.scope,
|
||||
SYM_DECL,
|
||||
node);
|
||||
|
||||
compiler_run(&comp, (node_t*) node->children.data[1], &fun->program);
|
||||
compiler_run(&comp, (node_t*) node->children.data[2], &fun->program);
|
||||
program_push_instr(&fun->program, OP_RET, RZ_NO_PARAM);
|
||||
|
@ -387,7 +399,7 @@ int compiler_run(compiler_t* compiler, node_t* node, program_t* program)
|
|||
compiler_free(&comp);
|
||||
}
|
||||
|
||||
value_t* value = tysy_new_fun(compiler->tysy, fun, node->line);
|
||||
// value_t* value = tysy_new_fun(compiler->tysy, fun, node->line);
|
||||
param_t param = program_push_new_value(program, (struct value*) value);
|
||||
program_push_instr(program, OP_PUSH, param);
|
||||
|
||||
|
|
10
lib/vm.c
10
lib/vm.c
|
@ -505,17 +505,19 @@ int vm_exec_instr(vm_t* vm, Opcode op, param_t param)
|
|||
} break;
|
||||
|
||||
case OP_CALL: {
|
||||
size_t const ARG_SZ = param;
|
||||
size_t const ARG_SZ = param + 1;
|
||||
value_t* args[ARG_SZ];
|
||||
|
||||
fun_t* fun = vm_pop(vm)->value.fun;
|
||||
|
||||
for (size_t i=0; i<ARG_SZ; i++)
|
||||
{
|
||||
value_t* val = vm_pop(vm);
|
||||
args[ARG_SZ - 1 - i] = val;
|
||||
}
|
||||
|
||||
value_t* fun_val = args[ARG_SZ - 1];
|
||||
assert(fun_val->type->kind == TYPE_FUN);
|
||||
fun_t* fun = fun_val->value.fun;
|
||||
|
||||
vm->top_frame->pc++;
|
||||
vm_frame_push(vm, &fun->program);
|
||||
|
||||
|
@ -524,7 +526,7 @@ int vm_exec_instr(vm_t* vm, Opcode op, param_t param)
|
|||
value_t* arg = args[i];
|
||||
|
||||
vm_push(vm, arg);
|
||||
vm_local_store(vm, i, vm->top_frame->sp - 1);
|
||||
vm_local_store(vm, ARG_SZ - 1 - i, vm->top_frame->sp - 1);
|
||||
}
|
||||
|
||||
} break;
|
||||
|
|
|
@ -35,3 +35,26 @@ end
|
|||
|
||||
assert max(7, 3) == 7
|
||||
assert max(7, 9) == 9
|
||||
|
||||
# RECURSIVITY
|
||||
# ===========
|
||||
|
||||
fun fac(n)
|
||||
if n == 0 then
|
||||
return 1
|
||||
end
|
||||
|
||||
return n * fac(n - 1)
|
||||
end
|
||||
|
||||
assert fac(5) == 120
|
||||
|
||||
fun fib(n)
|
||||
if n == 0 or n == 1 then
|
||||
return 1
|
||||
end
|
||||
|
||||
return fib(n - 2) + fib(n - 1)
|
||||
end
|
||||
|
||||
assert fib(6) == 13
|
Loading…
Reference in New Issue