mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-07 23:38:47 +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);
|
void **s_top(struct State *s);
|
||||||
bool s_is_empty(struct State *s);
|
bool s_is_empty(struct State *s);
|
||||||
|
void **s_nth(struct State *s, aint n);
|
||||||
void **s_peek(struct State *s);
|
void **s_peek(struct State *s);
|
||||||
aint *s_peek_i(struct State *s);
|
aint *s_peek_i(struct State *s);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -283,15 +283,16 @@ void run(bytefile *bf) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 5: // CALLC %d // call clojure
|
case 5: { // CALLC %d // call clojure
|
||||||
ip_read_int(&s.ip); // args count
|
aint args_count = ip_read_int(&s.ip); // args count
|
||||||
|
|
||||||
call_happened = true;
|
call_happened = true;
|
||||||
s.is_closure_call = true;
|
s.is_closure_call = true;
|
||||||
s.call_ip = s.ip;
|
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;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 6: { // CALL 0x%.8x %d // call function
|
case 6: { // CALL 0x%.8x %d // call function
|
||||||
int call_p = ip_read_int(&s.ip);
|
int call_p = ip_read_int(&s.ip);
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,20 @@ bool s_is_empty(struct State* s) {
|
||||||
return false;
|
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) {
|
void** s_peek(struct State* s) {
|
||||||
if (s->sp == s_top(s)) {
|
if (s->sp == s_top(s)) {
|
||||||
failure("empty stack");
|
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);
|
printf("-> %i locals sz\n", locals_sz);
|
||||||
|
|
||||||
// check that params count is valid
|
// 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");
|
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");
|
failure("not enough parameters in function stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_closure_call) {
|
void* closure = is_closure_call ? s_nth(s, args_sz) : NULL;
|
||||||
s_push_nil(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* closure = s_peek(s);
|
|
||||||
|
|
||||||
// s_push_nil(s); // sp contains value, frame starts with next value
|
// 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
|
// create frame
|
||||||
struct Frame frame = {
|
struct Frame frame = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue