1
Fork 0
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:
Andy Wingo 2008-09-18 22:49:55 +02:00
parent 87e7228ff6
commit d51406fe87
7 changed files with 110 additions and 14 deletions

View file

@ -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"