✨ recursive functions.
parent
e786b8f756
commit
968f7a312d
|
@ -2,7 +2,9 @@
|
||||||
#include "lib/commons.h"
|
#include "lib/commons.h"
|
||||||
#include "lib/mod.h"
|
#include "lib/mod.h"
|
||||||
#include "lib/prepass.h"
|
#include "lib/prepass.h"
|
||||||
|
#include "lib/program.h"
|
||||||
#include "lib/sym.h"
|
#include "lib/sym.h"
|
||||||
|
#include "lib/tysy.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "fun.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_t* fun = malloc(sizeof(fun_t));
|
||||||
fun_init(fun, (struct tysy*) compiler->tysy, compiler->err);
|
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,
|
sym_entry_t* entry = sym_try_find_by_name(compiler->sym,
|
||||||
fun_name,
|
fun_name,
|
||||||
compiler->scope,
|
compiler->scope,
|
||||||
|
@ -378,6 +382,14 @@ int compiler_run(compiler_t* compiler, node_t* node, program_t* program)
|
||||||
&tysolver, compiler->err);
|
&tysolver, compiler->err);
|
||||||
|
|
||||||
prepass_run(&pre, (node_t*) node->children.data[2]);
|
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[1], &fun->program);
|
||||||
compiler_run(&comp, (node_t*) node->children.data[2], &fun->program);
|
compiler_run(&comp, (node_t*) node->children.data[2], &fun->program);
|
||||||
program_push_instr(&fun->program, OP_RET, RZ_NO_PARAM);
|
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);
|
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);
|
param_t param = program_push_new_value(program, (struct value*) value);
|
||||||
program_push_instr(program, OP_PUSH, param);
|
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;
|
} break;
|
||||||
|
|
||||||
case OP_CALL: {
|
case OP_CALL: {
|
||||||
size_t const ARG_SZ = param;
|
size_t const ARG_SZ = param + 1;
|
||||||
value_t* args[ARG_SZ];
|
value_t* args[ARG_SZ];
|
||||||
|
|
||||||
fun_t* fun = vm_pop(vm)->value.fun;
|
|
||||||
|
|
||||||
for (size_t i=0; i<ARG_SZ; i++)
|
for (size_t i=0; i<ARG_SZ; i++)
|
||||||
{
|
{
|
||||||
value_t* val = vm_pop(vm);
|
value_t* val = vm_pop(vm);
|
||||||
args[ARG_SZ - 1 - i] = val;
|
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->top_frame->pc++;
|
||||||
vm_frame_push(vm, &fun->program);
|
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];
|
value_t* arg = args[i];
|
||||||
|
|
||||||
vm_push(vm, arg);
|
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;
|
} break;
|
||||||
|
|
|
@ -35,3 +35,26 @@ end
|
||||||
|
|
||||||
assert max(7, 3) == 7
|
assert max(7, 3) == 7
|
||||||
assert max(7, 9) == 9
|
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