mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-05 22:38:44 +00:00
closure fix
This commit is contained in:
parent
bd27e79b22
commit
e9c4d48cf9
3 changed files with 23 additions and 11 deletions
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
void **s_top(struct State *s);
|
||||
bool s_is_empty(struct State *s);
|
||||
void **s_nth(struct State *s, aint n);
|
||||
void **s_peek(struct State *s);
|
||||
aint *s_peek_i(struct State *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -283,15 +283,16 @@ void run(bytefile *bf) {
|
|||
break;
|
||||
}
|
||||
|
||||
case 5: // CALLC %d // call clojure
|
||||
ip_read_int(&s.ip); // args count
|
||||
case 5: { // CALLC %d // call clojure
|
||||
aint args_count = ip_read_int(&s.ip); // args count
|
||||
|
||||
call_happened = true;
|
||||
s.is_closure_call = true;
|
||||
s.call_ip = s.ip;
|
||||
|
||||
s.ip = Belem(s.sp, BOX(0)); // use offset instead ??
|
||||
s.ip = Belem(*s_nth(&s, args_count), BOX(0)); // use offset instead ??
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: { // CALL 0x%.8x %d // call function
|
||||
int call_p = ip_read_int(&s.ip);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,20 @@ bool s_is_empty(struct State* s) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void **s_nth(struct State *s, aint n) {
|
||||
if (n < 0) {
|
||||
failure("can't access stack by negative index");
|
||||
}
|
||||
if (s->sp + n >= s_top(s)) {
|
||||
failure("not enough elements in stack");
|
||||
}
|
||||
if (s->fp != NULL && s->sp + n >= f_locals(s->fp)) {
|
||||
failure("not enough elements in function stack");
|
||||
}
|
||||
|
||||
return s->sp + n;
|
||||
}
|
||||
|
||||
void** s_peek(struct State* s) {
|
||||
if (s->sp == s_top(s)) {
|
||||
failure("empty stack");
|
||||
|
|
@ -115,21 +129,17 @@ void s_enter_f(struct State *s, char *rp, bool is_closure_call, auint args_sz, a
|
|||
printf("-> %i locals sz\n", locals_sz);
|
||||
|
||||
// check that params count is valid
|
||||
if (s->sp + (aint)args_sz - 1 >= s_top(s)) {
|
||||
if (s->sp + (aint)args_sz - (is_closure_call ? 0 : 1) >= s_top(s)) {
|
||||
failure("not enough parameters in stack");
|
||||
}
|
||||
if (s->fp != NULL && s->sp + (aint)args_sz - 1 >= f_locals(s->fp)) {
|
||||
if (s->fp != NULL && s->sp + (aint)args_sz - (is_closure_call ? 0 : 1) >= f_locals(s->fp)) {
|
||||
failure("not enough parameters in function stack");
|
||||
}
|
||||
|
||||
if (!is_closure_call) {
|
||||
s_push_nil(s);
|
||||
}
|
||||
|
||||
void* closure = s_peek(s);
|
||||
void* closure = is_closure_call ? s_nth(s, args_sz) : NULL;
|
||||
|
||||
// s_push_nil(s); // sp contains value, frame starts with next value
|
||||
s_pushn_nil(s, frame_sz() - 1);
|
||||
s_pushn_nil(s, frame_sz());
|
||||
|
||||
// create frame
|
||||
struct Frame frame = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue