mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-17 17:20:29 +02:00
lambda-lifting for (lambda () ...) as consumer of call-with-values
* libguile/vm-engine.c (vm_run): Add new error case, vm_error_not_enough_values. * libguile/vm-i-system.c (goto/nargs, call/nargs): So, in these cases, if we get too many values, we don't truncate the values like we do in the single-value continuation case, or in the mvbind case. What to do? I guess we either truncate them here, or only allow the correct number of values. Dunno. Mark the code as a fixme. (truncate-values): New instruction, for mv-bind: checks that the number of values on the stack is compatible with the number of bindings we have arranged for them, truncating if necessary. * module/language/scheme/translate.scm (custom-transformer-table): Compile receive as a primary form -- not so much because it is a primary form, but more to test the mv-bind machinery. Also it's more efficient, I think. * module/system/il/compile.scm (lift-variables!): New helper, factored out of `optimize'. (optimize): Add a few more cases. Adapt `lambda' optimization, which isn't much. I'm not happy with ghil as a mungeable language. Add a case for call-with-values with the second argument is a lambda: lift the lambda. Untested. (codegen): Refactor the push-bindings! code. Compile mv-bind. * module/system/il/ghil.scm (<ghil-mv-bind>): Add mv-bind construct, along with its procedures. * module/system/il/glil.scm (<glil-mv-bind>): Add mv-bind construct, different from the high-level one. It makes sense in the source, I think. * module/system/vm/assemble.scm (codegen): Assemble glil-mv-bind by pushing onto the bindings list, and actually push some code to truncate the values.
This commit is contained in:
parent
87e7228ff6
commit
d51406fe87
7 changed files with 110 additions and 14 deletions
|
@ -713,6 +713,7 @@ VM_DEFINE_INSTRUCTION (goto_nargs, "goto/nargs", 0, 0, 1)
|
|||
SCM x;
|
||||
POP (x);
|
||||
nargs = scm_to_int (x);
|
||||
/* FIXME: should truncate values? */
|
||||
goto vm_goto_args;
|
||||
}
|
||||
|
||||
|
@ -721,6 +722,7 @@ VM_DEFINE_INSTRUCTION (call_nargs, "call/nargs", 0, 0, 1)
|
|||
SCM x;
|
||||
POP (x);
|
||||
nargs = scm_to_int (x);
|
||||
/* FIXME: should truncate values? */
|
||||
goto vm_call;
|
||||
}
|
||||
|
||||
|
@ -963,6 +965,29 @@ VM_DEFINE_INSTRUCTION (return_values_star, "return/values*", 1, -1, -1)
|
|||
goto vm_return_values;
|
||||
}
|
||||
|
||||
VM_DEFINE_INSTRUCTION (truncate_values, "truncate-values", 2, -1, -1)
|
||||
{
|
||||
SCM x;
|
||||
int nbinds, rest;
|
||||
POP (x);
|
||||
nvalues = scm_to_int (x);
|
||||
nbinds = FETCH ();
|
||||
rest = FETCH ();
|
||||
|
||||
if (rest)
|
||||
nbinds--;
|
||||
|
||||
if (nvalues < nbinds)
|
||||
goto vm_error_not_enough_values;
|
||||
|
||||
if (rest)
|
||||
POP_LIST (nvalues - nbinds);
|
||||
else
|
||||
DROPN (nvalues - nbinds);
|
||||
|
||||
NEXT;
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-file-style: "gnu"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue