guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] GNU Guile branch, wip-case-lambda, updated. release_1-9-


From: Andy Wingo
Subject: [Guile-commits] GNU Guile branch, wip-case-lambda, updated. release_1-9-4-18-g4413823
Date: Sat, 17 Oct 2009 15:23:24 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=441382394cbe8ae382b314e6c2199197576dae00

The branch, wip-case-lambda has been updated
       via  441382394cbe8ae382b314e6c2199197576dae00 (commit)
      from  8de2de57d6920e22b66cd53ada90b635e895db90 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 441382394cbe8ae382b314e6c2199197576dae00
Author: Andy Wingo <address@hidden>
Date:   Sat Oct 17 17:23:09 2009 +0200

    finish support for optional & keyword args; update ecmascript compiler
    
    * libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump.
    * libguile/vm-i-system.c (br-if-nargs-ne, br-if-args-lt)
      (br-if-nargs-gt): New instructions, for use by different lambda cases.
      (bind-optionals, bind-optionals/shuffle, bind-kwargs): New
      instructions, for binding optional and keyword arguments. Renumber
      other ops.
    
    * module/language/ecmascript/compile-tree-il.scm (comp, comp-body):
      Update for new tree-il. Use the new optional argument mechanism
      instead of emulating it with rest arguments.
    
    * module/language/glil/compile-assembly.scm (glil->assembly): Tweaks for
      optional and keyword argument compilation.
    
    * module/language/tree-il.scm (parse-tree-il, unparse-tree-il): Make the
      else case optional, in the s-expression serialization of tree-il.
    
    * module/language/tree-il/compile-glil.scm (flatten): Handle all of the
      lambda-case capabilities.

-----------------------------------------------------------------------

Summary of changes:
 libguile/_scm.h                                |    2 +-
 libguile/vm-engine.c                           |   15 ++
 libguile/vm-i-system.c                         |  186 ++++++++++++++++++++----
 module/language/ecmascript/compile-tree-il.scm |  124 ++++++++--------
 module/language/glil/compile-assembly.scm      |   13 +-
 module/language/tree-il.scm                    |   34 +++--
 module/language/tree-il/compile-glil.scm       |   77 +++++++---
 7 files changed, 318 insertions(+), 133 deletions(-)

diff --git a/libguile/_scm.h b/libguile/_scm.h
index 53b698e..a7a5e8f 100644
--- a/libguile/_scm.h
+++ b/libguile/_scm.h
@@ -172,7 +172,7 @@
 
 /* Major and minor versions must be single characters. */
 #define SCM_OBJCODE_MAJOR_VERSION 0
-#define SCM_OBJCODE_MINOR_VERSION H
+#define SCM_OBJCODE_MINOR_VERSION I
 #define SCM_OBJCODE_MAJOR_VERSION_STRING        \
   SCM_CPP_STRINGIFY(SCM_OBJCODE_MAJOR_VERSION)
 #define SCM_OBJCODE_MINOR_VERSION_STRING        \
diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c
index f86a498..5d8f655 100644
--- a/libguile/vm-engine.c
+++ b/libguile/vm-engine.c
@@ -170,6 +170,21 @@ VM_NAME (struct scm_vm *vp, SCM program, SCM *argv, int 
nargs)
     finish_args = SCM_EOL;
     goto vm_error;
 
+  vm_error_kwargs_length_not_even:
+    err_msg  = scm_from_locale_string ("Bad keyword argument list: odd 
length");
+    finish_args = SCM_EOL;
+    goto vm_error;
+
+  vm_error_kwargs_invalid_keyword:
+    err_msg  = scm_from_locale_string ("Bad keyword argument list: expected 
keyword");
+    finish_args = SCM_EOL;
+    goto vm_error;
+
+  vm_error_kwargs_unrecognized_keyword:
+    err_msg  = scm_from_locale_string ("Bad keyword argument list: 
unrecognized keyword");
+    finish_args = SCM_EOL;
+    goto vm_error;
+
   vm_error_too_many_args:
     err_msg  = scm_from_locale_string ("VM: Too many arguments");
     finish_args = scm_list_1 (scm_from_int (nargs));
diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c
index b1a261a..66e4935 100644
--- a/libguile/vm-i-system.c
+++ b/libguile/vm-i-system.c
@@ -480,7 +480,43 @@ VM_DEFINE_INSTRUCTION (37, br_if_not_null, 
"br-if-not-null", 3, 0, 0)
  * Subprogram call
  */
 
-VM_DEFINE_INSTRUCTION (38, assert_nargs_ee, "assert-nargs-ee", 2, 0, 0)
+VM_DEFINE_INSTRUCTION (38, br_if_nargs_ne, "br-if-nargs-ne", 5, 0, 0)
+{
+  scm_t_ptrdiff n;
+  n = FETCH () << 8;
+  n += FETCH ();
+  scm_t_int32 offset;
+  FETCH_OFFSET (offset);
+  if (sp - (fp - 1) != n)
+    ip += offset;
+  NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (39, br_if_nargs_lt, "br-if-nargs-lt", 5, 0, 0)
+{
+  scm_t_ptrdiff n;
+  n = FETCH () << 8;
+  n += FETCH ();
+  scm_t_int32 offset;
+  FETCH_OFFSET (offset);
+  if (sp - (fp - 1) < n)
+    ip += offset;
+  NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (40, br_if_nargs_gt, "br-if-nargs-gt", 5, 0, 0)
+{
+  scm_t_ptrdiff n;
+  n = FETCH () << 8;
+  n += FETCH ();
+  scm_t_int32 offset;
+  FETCH_OFFSET (offset);
+  if (sp - (fp - 1) > n)
+    ip += offset;
+  NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (41, assert_nargs_ee, "assert-nargs-ee", 2, 0, 0)
 {
   scm_t_ptrdiff n;
   n = FETCH () << 8;
@@ -490,7 +526,7 @@ VM_DEFINE_INSTRUCTION (38, assert_nargs_ee, 
"assert-nargs-ee", 2, 0, 0)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (39, assert_nargs_ge, "assert-nargs-ge", 2, 0, 0)
+VM_DEFINE_INSTRUCTION (42, assert_nargs_ge, "assert-nargs-ge", 2, 0, 0)
 {
   scm_t_ptrdiff n;
   n = FETCH () << 8;
@@ -500,7 +536,95 @@ VM_DEFINE_INSTRUCTION (39, assert_nargs_ge, 
"assert-nargs-ge", 2, 0, 0)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (40, bind_rest, "bind-rest", 2, -1, -1)
+VM_DEFINE_INSTRUCTION (43, bind_optionals, "bind-optionals", 2, -1, -1)
+{
+  scm_t_ptrdiff n;
+  n = FETCH () << 8;
+  n += FETCH ();
+  while (sp - (fp - 1) < n)
+    PUSH (SCM_UNDEFINED);
+  NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (44, bind_optionals_shuffle, "bind-optionals/shuffle", 
6, -1, -1)
+{
+  SCM *walk;
+  scm_t_ptrdiff nreq, nreq_and_opt, ntotal;
+  nreq = FETCH () << 8;
+  nreq += FETCH ();
+  nreq_and_opt = FETCH () << 8;
+  nreq_and_opt += FETCH ();
+  ntotal = FETCH () << 8;
+  ntotal += FETCH ();
+
+  /* look in optionals for first keyword or last positional */
+  /* starting after the last required positional arg */
+  walk = (fp - 1) + nreq;
+  while (/* while we have args */
+         walk <= sp
+         /* and we still have positionals to fill */
+         && walk - (fp - 1) < nreq_and_opt
+         /* and we haven't reached a keyword yet */
+         && !scm_is_keyword (*walk))
+    /* bind this optional arg (by leaving it in place) */
+    walk++;
+  /* now shuffle up, from walk to ntotal */
+  {
+    scm_t_ptrdiff nshuf = sp - walk + 1;
+    sp = (fp - 1) + ntotal + nshuf;
+    CHECK_OVERFLOW ();
+    while (nshuf--)
+      sp[-nshuf] = walk[nshuf];
+  }
+  /* and fill optionals & keyword args with SCM_UNDEFINED */
+  while (walk < (fp - 1) + ntotal)
+    *walk++ = SCM_UNDEFINED;
+
+  NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (45, bind_kwargs, "bind-kwargs", 5, 0, 0)
+{
+  scm_t_uint16 idx;
+  scm_t_ptrdiff nkw;
+  int allow_other_keys;
+  SCM kw;
+  idx = FETCH () << 8;
+  idx += FETCH ();
+  nkw = FETCH () << 8;
+  nkw += FETCH ();
+  allow_other_keys = FETCH ();
+
+  if ((sp - (fp - 1) - nkw) % 2)
+    goto vm_error_kwargs_length_not_even;
+
+  CHECK_OBJECT (idx);
+  kw = OBJECT_REF (idx);
+  /* switch nkw to be a negative index below sp */
+  for (nkw = -(sp - (fp - 1) - nkw) + 1; nkw < 0; nkw += 2)
+    {
+      SCM walk;
+      if (!scm_is_keyword (sp[nkw]))
+        goto vm_error_kwargs_invalid_keyword;
+      for (walk = kw; scm_is_pair (walk); walk = SCM_CDR (walk))
+        {
+          if (scm_is_eq (SCM_CAAR (walk), sp[nkw]))
+            {
+              SCM si = SCM_CDAR (walk);
+              LOCAL_SET (SCM_I_INUMP (si) ? SCM_I_INUM (si) : scm_to_long (si),
+                         sp[nkw + 1]);
+              break;
+            }
+        }
+      if (!allow_other_keys && !scm_is_pair (walk))
+        goto vm_error_kwargs_unrecognized_keyword;
+      nkw += 2;
+    }
+
+  NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (46, bind_rest, "bind-rest", 2, -1, -1)
 {
   scm_t_ptrdiff n;
   SCM rest = SCM_EOL;
@@ -513,7 +637,7 @@ VM_DEFINE_INSTRUCTION (40, bind_rest, "bind-rest", 2, -1, 
-1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (41, reserve_locals, "reserve-locals", 2, -1, -1)
+VM_DEFINE_INSTRUCTION (47, reserve_locals, "reserve-locals", 2, -1, -1)
 {
   SCM *old_sp;
   scm_t_int32 n;
@@ -534,7 +658,7 @@ VM_DEFINE_INSTRUCTION (41, reserve_locals, 
"reserve-locals", 2, -1, -1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (42, new_frame, "new-frame", 0, 0, 3)
+VM_DEFINE_INSTRUCTION (48, new_frame, "new-frame", 0, 0, 3)
 {
   /* NB: if you change this, see frames.c:vm-frame-num-locals */
   /* and frames.h, vm-engine.c, etc of course */
@@ -544,7 +668,7 @@ VM_DEFINE_INSTRUCTION (42, new_frame, "new-frame", 0, 0, 3)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (43, call, "call", 1, -1, 1)
+VM_DEFINE_INSTRUCTION (49, call, "call", 1, -1, 1)
 {
   SCM x;
   nargs = FETCH ();
@@ -605,7 +729,7 @@ VM_DEFINE_INSTRUCTION (43, call, "call", 1, -1, 1)
   goto vm_error_wrong_type_apply;
 }
 
-VM_DEFINE_INSTRUCTION (44, goto_args, "goto/args", 1, -1, 1)
+VM_DEFINE_INSTRUCTION (50, goto_args, "goto/args", 1, -1, 1)
 {
   register SCM x;
   nargs = FETCH ();
@@ -678,7 +802,7 @@ VM_DEFINE_INSTRUCTION (44, goto_args, "goto/args", 1, -1, 1)
   goto vm_error_wrong_type_apply;
 }
 
-VM_DEFINE_INSTRUCTION (45, goto_nargs, "goto/nargs", 0, 0, 1)
+VM_DEFINE_INSTRUCTION (51, goto_nargs, "goto/nargs", 0, 0, 1)
 {
   SCM x;
   POP (x);
@@ -687,7 +811,7 @@ VM_DEFINE_INSTRUCTION (45, goto_nargs, "goto/nargs", 0, 0, 
1)
   goto vm_goto_args;
 }
 
-VM_DEFINE_INSTRUCTION (46, call_nargs, "call/nargs", 0, 0, 1)
+VM_DEFINE_INSTRUCTION (52, call_nargs, "call/nargs", 0, 0, 1)
 {
   SCM x;
   POP (x);
@@ -696,7 +820,7 @@ VM_DEFINE_INSTRUCTION (46, call_nargs, "call/nargs", 0, 0, 
1)
   goto vm_call;
 }
 
-VM_DEFINE_INSTRUCTION (47, mv_call, "mv-call", 4, -1, 1)
+VM_DEFINE_INSTRUCTION (53, mv_call, "mv-call", 4, -1, 1)
 {
   SCM x;
   scm_t_int32 offset;
@@ -758,7 +882,7 @@ VM_DEFINE_INSTRUCTION (47, mv_call, "mv-call", 4, -1, 1)
   goto vm_error_wrong_type_apply;
 }
 
-VM_DEFINE_INSTRUCTION (48, apply, "apply", 1, -1, 1)
+VM_DEFINE_INSTRUCTION (54, apply, "apply", 1, -1, 1)
 {
   int len;
   SCM ls;
@@ -777,7 +901,7 @@ VM_DEFINE_INSTRUCTION (48, apply, "apply", 1, -1, 1)
   goto vm_call;
 }
 
-VM_DEFINE_INSTRUCTION (49, goto_apply, "goto/apply", 1, -1, 1)
+VM_DEFINE_INSTRUCTION (55, goto_apply, "goto/apply", 1, -1, 1)
 {
   int len;
   SCM ls;
@@ -796,7 +920,7 @@ VM_DEFINE_INSTRUCTION (49, goto_apply, "goto/apply", 1, -1, 
1)
   goto vm_goto_args;
 }
 
-VM_DEFINE_INSTRUCTION (50, call_cc, "call/cc", 0, 1, 1)
+VM_DEFINE_INSTRUCTION (56, call_cc, "call/cc", 0, 1, 1)
 {
   int first;
   SCM proc, cont;
@@ -833,7 +957,7 @@ VM_DEFINE_INSTRUCTION (50, call_cc, "call/cc", 0, 1, 1)
     }
 }
 
-VM_DEFINE_INSTRUCTION (51, goto_cc, "goto/cc", 0, 1, 1)
+VM_DEFINE_INSTRUCTION (57, goto_cc, "goto/cc", 0, 1, 1)
 {
   int first;
   SCM proc, cont;
@@ -865,7 +989,7 @@ VM_DEFINE_INSTRUCTION (51, goto_cc, "goto/cc", 0, 1, 1)
     }
 }
 
-VM_DEFINE_INSTRUCTION (52, return, "return", 0, 1, 1)
+VM_DEFINE_INSTRUCTION (58, return, "return", 0, 1, 1)
 {
  vm_return:
   EXIT_HOOK ();
@@ -901,7 +1025,7 @@ VM_DEFINE_INSTRUCTION (52, return, "return", 0, 1, 1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (53, return_values, "return/values", 1, -1, -1)
+VM_DEFINE_INSTRUCTION (59, return_values, "return/values", 1, -1, -1)
 {
   /* nvalues declared at top level, because for some reason gcc seems to think
      that perhaps it might be used without declaration. Fooey to that, I say. 
*/
@@ -956,7 +1080,7 @@ VM_DEFINE_INSTRUCTION (53, return_values, "return/values", 
1, -1, -1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (54, return_values_star, "return/values*", 1, -1, -1)
+VM_DEFINE_INSTRUCTION (60, return_values_star, "return/values*", 1, -1, -1)
 {
   SCM l;
 
@@ -979,7 +1103,7 @@ VM_DEFINE_INSTRUCTION (54, return_values_star, 
"return/values*", 1, -1, -1)
   goto vm_return_values;
 }
 
-VM_DEFINE_INSTRUCTION (55, truncate_values, "truncate-values", 2, -1, -1)
+VM_DEFINE_INSTRUCTION (61, truncate_values, "truncate-values", 2, -1, -1)
 {
   SCM x;
   int nbinds, rest;
@@ -1002,7 +1126,7 @@ VM_DEFINE_INSTRUCTION (55, truncate_values, 
"truncate-values", 2, -1, -1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (56, box, "box", 1, 1, 0)
+VM_DEFINE_INSTRUCTION (62, box, "box", 1, 1, 0)
 {
   SCM val;
   POP (val);
@@ -1016,7 +1140,7 @@ VM_DEFINE_INSTRUCTION (56, box, "box", 1, 1, 0)
      (set! a (lambda () (b ...)))
      ...)
  */
-VM_DEFINE_INSTRUCTION (57, empty_box, "empty-box", 1, 0, 0)
+VM_DEFINE_INSTRUCTION (63, empty_box, "empty-box", 1, 0, 0)
 {
   SYNC_BEFORE_GC ();
   LOCAL_SET (FETCH (),
@@ -1024,7 +1148,7 @@ VM_DEFINE_INSTRUCTION (57, empty_box, "empty-box", 1, 0, 
0)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (58, local_boxed_ref, "local-boxed-ref", 1, 0, 1)
+VM_DEFINE_INSTRUCTION (64, local_boxed_ref, "local-boxed-ref", 1, 0, 1)
 {
   SCM v = LOCAL_REF (FETCH ());
   ASSERT_BOUND_VARIABLE (v);
@@ -1032,7 +1156,7 @@ VM_DEFINE_INSTRUCTION (58, local_boxed_ref, 
"local-boxed-ref", 1, 0, 1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (59, local_boxed_set, "local-boxed-set", 1, 1, 0)
+VM_DEFINE_INSTRUCTION (65, local_boxed_set, "local-boxed-set", 1, 1, 0)
 {
   SCM v, val;
   v = LOCAL_REF (FETCH ());
@@ -1042,7 +1166,7 @@ VM_DEFINE_INSTRUCTION (59, local_boxed_set, 
"local-boxed-set", 1, 1, 0)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (60, free_ref, "free-ref", 1, 0, 1)
+VM_DEFINE_INSTRUCTION (66, free_ref, "free-ref", 1, 0, 1)
 {
   scm_t_uint8 idx = FETCH ();
   
@@ -1053,7 +1177,7 @@ VM_DEFINE_INSTRUCTION (60, free_ref, "free-ref", 1, 0, 1)
 
 /* no free-set -- if a var is assigned, it should be in a box */
 
-VM_DEFINE_INSTRUCTION (61, free_boxed_ref, "free-boxed-ref", 1, 0, 1)
+VM_DEFINE_INSTRUCTION (67, free_boxed_ref, "free-boxed-ref", 1, 0, 1)
 {
   SCM v;
   scm_t_uint8 idx = FETCH ();
@@ -1064,7 +1188,7 @@ VM_DEFINE_INSTRUCTION (61, free_boxed_ref, 
"free-boxed-ref", 1, 0, 1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (62, free_boxed_set, "free-boxed-set", 1, 1, 0)
+VM_DEFINE_INSTRUCTION (68, free_boxed_set, "free-boxed-set", 1, 1, 0)
 {
   SCM v, val;
   scm_t_uint8 idx = FETCH ();
@@ -1076,7 +1200,7 @@ VM_DEFINE_INSTRUCTION (62, free_boxed_set, 
"free-boxed-set", 1, 1, 0)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (63, make_closure, "make-closure", 0, 2, 1)
+VM_DEFINE_INSTRUCTION (69, make_closure, "make-closure", 0, 2, 1)
 {
   SCM vect;
   POP (vect);
@@ -1087,7 +1211,7 @@ VM_DEFINE_INSTRUCTION (63, make_closure, "make-closure", 
0, 2, 1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (64, make_variable, "make-variable", 0, 0, 1)
+VM_DEFINE_INSTRUCTION (70, make_variable, "make-variable", 0, 0, 1)
 {
   SYNC_BEFORE_GC ();
   /* fixme underflow */
@@ -1095,7 +1219,7 @@ VM_DEFINE_INSTRUCTION (64, make_variable, 
"make-variable", 0, 0, 1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (65, fix_closure, "fix-closure", 2, 0, 1)
+VM_DEFINE_INSTRUCTION (71, fix_closure, "fix-closure", 2, 0, 1)
 {
   SCM x, vect;
   unsigned int i = FETCH ();
@@ -1109,7 +1233,7 @@ VM_DEFINE_INSTRUCTION (65, fix_closure, "fix-closure", 2, 
0, 1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (66, define, "define", 0, 0, 2)
+VM_DEFINE_INSTRUCTION (72, define, "define", 0, 0, 2)
 {
   SCM sym, val;
   POP (sym);
@@ -1121,7 +1245,7 @@ VM_DEFINE_INSTRUCTION (66, define, "define", 0, 0, 2)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (67, make_keyword, "make-keyword", 0, 1, 1)
+VM_DEFINE_INSTRUCTION (73, make_keyword, "make-keyword", 0, 1, 1)
 {
   CHECK_UNDERFLOW ();
   SYNC_REGISTER ();
@@ -1129,7 +1253,7 @@ VM_DEFINE_INSTRUCTION (67, make_keyword, "make-keyword", 
0, 1, 1)
   NEXT;
 }
 
-VM_DEFINE_INSTRUCTION (68, make_symbol, "make-symbol", 0, 1, 1)
+VM_DEFINE_INSTRUCTION (74, make_symbol, "make-symbol", 0, 1, 1)
 {
   CHECK_UNDERFLOW ();
   SYNC_REGISTER ();
diff --git a/module/language/ecmascript/compile-tree-il.scm 
b/module/language/ecmascript/compile-tree-il.scm
index 88f3db7..d14d764 100644
--- a/module/language/ecmascript/compile-tree-il.scm
+++ b/module/language/ecmascript/compile-tree-il.scm
@@ -326,14 +326,20 @@
       ((begin . ,forms)
        `(begin ,@(map (lambda (x) (comp x e)) forms)))
       ((lambda ,formals ,body)
-       (let ((%args (gensym "%args ")))
-         (-> (lambda '%args %args '()
-                     (comp-body (econs '%args %args e) body formals '%args)))))
+       (let ((syms (map (lambda (x)
+                          (gensym (string-append (symbol->string x) " ")))
+                        formals)))
+         (-> (lambda '()
+               (-> (lambda-case
+                    `((() ,formals #f #f ,syms #f)
+                      ,(comp-body e body formals syms))))))))
       ((call/this ,obj ,prop . ,args)
        (@impl call/this*
               obj
-              (-> (lambda '() '() '()
-                          `(apply ,(@impl pget obj prop) ,@args)))))
+              (-> (lambda '() 
+                    (-> (lambda-case
+                         `((() #f #f #f () #f)
+                           (apply ,(@impl pget obj prop) ,@args))))))))
       ((call (pref ,obj ,prop) ,args)
        (comp `(call/this ,(comp obj e)
                          ,(-> (const prop))
@@ -433,40 +439,46 @@
              (%continue (gensym "%continue ")))
          (let ((e (econs '%loop %loop (econs '%continue %continue e))))
            (-> (letrec '(%loop %continue) (list %loop %continue)
-                       (list (-> (lambda '() '() '()
-                                         (-> (begin
-                                               (comp statement e)
-                                               (-> (apply (-> (lexical 
'%continue %continue)))
-                                                   )))))
-                             
-                             (-> (lambda '() '() '()
-                                         (-> (if (@impl ->boolean (comp test 
e))
-                                                 (-> (apply (-> (lexical 
'%loop %loop))))
-                                                 (@implv *undefined*))))))
+                       (list (-> (lambda '()
+                                   (-> (lambda-case
+                                        `((() #f #f #f () #f)
+                                          ,(-> (begin
+                                                 (comp statement e)
+                                                 (-> (apply (-> (lexical 
'%continue %continue)))))))))))
+                             (-> (lambda '()
+                                   (-> (lambda-case
+                                        `((() #f #f #f () #f)
+                                          ,(-> (if (@impl ->boolean (comp test 
e))
+                                                   (-> (apply (-> (lexical 
'%loop %loop))))
+                                                   (@implv *undefined*)))))))))
                        (-> (apply (-> (lexical '%loop %loop)))))))))
       ((while ,test ,statement)
        (let ((%continue (gensym "%continue ")))
          (let ((e (econs '%continue %continue e)))
            (-> (letrec '(%continue) (list %continue)
-                       (list (-> (lambda '() '() '()
-                                         (-> (if (@impl ->boolean (comp test 
e))
-                                                 (-> (begin (comp statement e)
-                                                            (-> (apply (-> 
(lexical '%continue %continue))))))
-                                                 (@implv *undefined*))))))
+                       (list (-> (lambda '()
+                                   (-> (lambda-case
+                                        `((() #f #f #f () #f)
+                                          ,(-> (if (@impl ->boolean (comp test 
e))
+                                                   (-> (begin (comp statement 
e)
+                                                              (-> (apply (-> 
(lexical '%continue %continue))))))
+                                                   (@implv *undefined*)))))))))
                        (-> (apply (-> (lexical '%continue %continue)))))))))
       
       ((for ,init ,test ,inc ,statement)
        (let ((%continue (gensym "%continue ")))
          (let ((e (econs '%continue %continue e)))
            (-> (letrec '(%continue) (list %continue)
-                       (list (-> (lambda '() '() '()
-                                         (-> (if (if test
-                                                     (@impl ->boolean (comp 
test e))
-                                                     (comp 'true e))
-                                                 (-> (begin (comp statement e)
-                                                            (comp (or inc 
'(begin)) e)
-                                                            (-> (apply (-> 
(lexical '%continue %continue))))))
-                                                 (@implv *undefined*))))))
+                       (list (-> (lambda '()
+                                   (-> (lambda-case
+                                        `((() #f #f #f () #f)
+                                          ,(-> (if (if test
+                                                       (@impl ->boolean (comp 
test e))
+                                                       (comp 'true e))
+                                                   (-> (begin (comp statement 
e)
+                                                              (comp (or inc 
'(begin)) e)
+                                                              (-> (apply (-> 
(lexical '%continue %continue))))))
+                                                   (@implv *undefined*)))))))))
                        (-> (begin (comp (or init '(begin)) e)
                                   (-> (apply (-> (lexical '%continue 
%continue)))))))))))
       
@@ -476,18 +488,20 @@
          (let ((e (econs '%enum %enum (econs '%continue %continue e))))
            (-> (letrec '(%enum %continue) (list %enum %continue)
                        (list (@impl make-enumerator (comp object e))
-                             (-> (lambda '() '() '()
-                                         (-> (if (@impl ->boolean
-                                                        (@impl pget
-                                                               (-> (lexical 
'%enum %enum))
-                                                               (-> (const 
'length))))
-                                                 (-> (begin
-                                                       (comp `(= ,var 
(call/this ,(-> (lexical '%enum %enum))
-                                                                               
  ,(-> (const 'pop))))
-                                                             e)
-                                                       (comp statement e)
-                                                       (-> (apply (-> (lexical 
'%continue %continue))))))
-                                                 (@implv *undefined*))))))
+                             (-> (lambda '()
+                                   (-> (lambda-case
+                                        `((() #f #f #f () #f)
+                                          (-> (if (@impl ->boolean
+                                                         (@impl pget
+                                                                (-> (lexical 
'%enum %enum))
+                                                                (-> (const 
'length))))
+                                                  (-> (begin
+                                                        (comp `(= ,var 
(call/this ,(-> (lexical '%enum %enum))
+                                                                               
   ,(-> (const 'pop))))
+                                                              e)
+                                                        (comp statement e)
+                                                        (-> (apply (-> 
(lexical '%continue %continue))))))
+                                                  (@implv *undefined*)))))))))
                        (-> (apply (-> (lexical '%continue %continue)))))))))
       
       ((block ,x)
@@ -495,18 +509,22 @@
       (else
        (error "compilation not yet implemented:" x)))))
 
-(define (comp-body e body formals %args)
+(define (comp-body e body formals formal-syms)
   (define (process)
-    (let lp ((in body) (out '()) (rvars (reverse formals)))
+    (let lp ((in body) (out '()) (rvars '()))
       (pmatch in
         (((var (,x) . ,morevars) . ,rest)
          (lp `((var . ,morevars) . ,rest)
              out
-             (if (memq x rvars) rvars (cons x rvars))))
+             (if (or (memq x rvars) (memq x formals))
+                 rvars
+                 (cons x rvars))))
         (((var (,x ,y) . ,morevars) . ,rest)
          (lp `((var . ,morevars) . ,rest)
              `((= (ref ,x) ,y) . ,out)
-             (if (memq x rvars) rvars (cons x rvars))))
+             (if (or (memq x rvars) (memq x formals))
+                 rvars
+                 (cons x rvars))))
         (((var) . ,rest)
          (lp rest out rvars))
         ((,x . ,rest) (guard (and (pair? x) (eq? (car x) 'lambda)))
@@ -532,18 +550,6 @@
            (syms (map (lambda (x)
                         (gensym (string-append (symbol->string x) " ")))
                       names))
-           (e (fold acons e names syms)))
-      (let ((%argv (lookup %args e)))
-        (let lp ((names names) (syms syms))
-          (if (null? names)
-              ;; fixme: here check for too many args
-              (comp out e)
-              (-> (let (list (car names)) (list (car syms))
-                       (list (-> (if (-> (apply (-> (primitive 'null?)) %argv))
-                                     (-> (@implv *undefined*))
-                                     (-> (let1 (-> (apply (-> (primitive 
'car)) %argv))
-                                               (lambda (v)
-                                                 (-> (set! %argv
-                                                     (-> (apply (-> (primitive 
'cdr)) %argv))))
-                                                 (-> (lexical v v))))))))
-                       (lp (cdr names) (cdr syms))))))))))
+           (e (fold econs (fold econs e formals formal-syms) names syms)))
+      (-> (let names syms (map (lambda (x) (->@implv *undefined*)) names)
+               (comp out e))))))
diff --git a/module/language/glil/compile-assembly.scm 
b/module/language/glil/compile-assembly.scm
index 62b8523..7069522 100644
--- a/module/language/glil/compile-assembly.scm
+++ b/module/language/glil/compile-assembly.scm
@@ -250,7 +250,7 @@
                            ,(modulo (+ nreq nopt) 256))))
              (else
               (if else-label
-                  `((br-if-nargs-ge ,(quotient (+ nreq nopt) 256)
+                  `((br-if-nargs-gt ,(quotient (+ nreq nopt) 256)
                                     ,(modulo (+ nreq nopt) 256)
                                     ,else-label))
                   `((assert-nargs-ee ,(quotient (+ nreq nopt) 256)
@@ -274,7 +274,9 @@
                   `((assert-nargs-ge ,(quotient nreq 256)
                                      ,(modulo nreq 256)))))
              (bind-optionals-and-shuffle
-              `((bind-optionals-and-shuffle-kwargs
+              `((bind-optionals/shuffle
+                 ,(quotient nreq 256)
+                 ,(modulo nreq 256)
                  ,(quotient (+ nreq nopt) 256)
                  ,(modulo (+ nreq nopt) 256)
                  ,(quotient (apply max (+ nreq nopt) (map cdr kw)) 256)
@@ -284,13 +286,12 @@
               ;; in, space has been made for kwargs, and the kwargs
               ;; themselves have been shuffled above the slots for all
               ;; req/opt/kwargs locals.
-              `((,(if allow-other-keys? 'bind-kwargs/aok 'bind-kwargs/no-aok)
+              `((bind-kwargs
                  ,(quotient kw-idx 256)
                  ,(modulo kw-idx 256)
-                 ,(quotient (+ nreq nopt) 256)
-                 ,(modulo (+ nreq nopt) 256)
                  ,(quotient (apply max (+ nreq nopt) (map cdr kw)) 256)
-                 ,(modulo (apply max (+ nreq nopt) (map cdr kw)) 256))))
+                 ,(modulo (apply max (+ nreq nopt) (map cdr kw)) 256)
+                 ,(if allow-other-keys? 1 0))))
              (bind-rest
               (if rest?
                   `((bind-rest ,(quotient (apply max (+ nreq nopt) (map cdr 
kw)) 256)
diff --git a/module/language/tree-il.scm b/module/language/tree-il.scm
index d645caf..41fc015 100644
--- a/module/language/tree-il.scm
+++ b/module/language/tree-il.scm
@@ -140,6 +140,12 @@
                         (retrans body)
                         (and=> else retrans)))
 
+     ((lambda-case ((,req ,opt ,rest ,kw ,vars ,predicate) ,body))
+      (make-lambda-case loc req opt rest kw vars
+                        (and=> predicate retrans)
+                        (retrans body)
+                        #f))
+
      ((const ,exp)
       (make-const loc exp))
 
@@ -202,7 +208,7 @@
     ((<lambda-case> req opt rest kw vars predicate body else)
      `(lambda-case ((,req ,opt ,rest ,kw ,vars ,(and=> predicate 
unparse-tree-il))
                     ,(unparse-tree-il body))
-                   ,(and=> else unparse-tree-il)))
+                   . ,(if else (list (unparse-tree-il else)) '())))
 
     ((<const> exp)
      `(const ,exp))
@@ -268,19 +274,19 @@
     
     ((<lambda-case> req opt rest kw vars predicate body else)
      ;; FIXME
-     #; `(((,@req
-         ,@(if (not opt)
-               '()
-               (cons #:optional opt))
-         ,@(if (not kw)
-               '()
-               (cons #:key (cdr kw)))
-         ,@(if predicate
-               (list #:predicate (tree-il->scheme predicate))
-               '())
-         . ,(or rest '()))
-        ,(tree-il->scheme body))
-       ,@(if else (tree-il->scheme else) '()))
+     ;; `(((,@req
+     ;;    ,@(if (not opt)
+     ;;          '()
+     ;;          (cons #:optional opt))
+     ;;    ,@(if (not kw)
+     ;;          '()
+     ;;          (cons #:key (cdr kw)))
+     ;;    ,@(if predicate
+     ;;          (list #:predicate (tree-il->scheme predicate))
+     ;;          '())
+     ;;    . ,(or rest '()))
+     ;;   ,(tree-il->scheme body))
+     ;;  ,@(if else (tree-il->scheme else) '()))
      `((,(if rest (apply cons* vars) vars)
         ,(tree-il->scheme body))
        ,@(if else (tree-il->scheme else) '())))
diff --git a/module/language/tree-il/compile-glil.scm 
b/module/language/tree-il/compile-glil.scm
index 41926e6..9a16f0c 100644
--- a/module/language/tree-il/compile-glil.scm
+++ b/module/language/tree-il/compile-glil.scm
@@ -599,28 +599,61 @@
                   (emit-code #f (make-glil-call 'make-closure 2)))))))
        (maybe-emit-return))
       
-      ((<lambda-case> req opt kw rest vars predicate else body)
-       ;; the prelude, to check args & reset the stack pointer,
-       ;; allowing room for locals
-       (let ((nlocs (cdr (hashq-ref allocation x))))
-         (if rest
-             (emit-code #f (make-glil-opt-prelude (length req) 0 #t nlocs #f))
-             (emit-code #f (make-glil-std-prelude (length req) nlocs #f))))
-       ;; box args if necessary
-       (for-each
-        (lambda (v)
-          (pmatch (hashq-ref (hashq-ref allocation v) self)
-            ((#t #t . ,n)
-             (emit-code #f (make-glil-lexical #t #f 'ref n))
-             (emit-code #f (make-glil-lexical #t #t 'box n)))))
-        vars)
-       ;; write bindings info -- FIXME deal with opt/kw
-       (if (not (null? vars))
-           (emit-bindings #f (append req (if rest (list rest) '()))
-                          vars allocation self emit-code))
-       ;; post-prelude case label for label calls
-       (emit-label (car (hashq-ref allocation x)))
-       (let ((else-label (and else (make-label))))
+      ((<lambda-case> src req opt rest kw vars predicate else body)
+       (let ((nlocs (cdr (hashq-ref allocation x)))
+             (else-label (and else (make-label))))
+         ;; the prelude, to check args & reset the stack pointer,
+         ;; allowing room for locals
+         (emit-code
+          src
+          (cond
+           ;; kw := (allow-other-keys? (#:key name var) ...)
+           (kw
+            (make-glil-kw-prelude
+             (length req) (length (or opt '())) (and rest #t)
+             (map (lambda (x)
+                    (pmatch x
+                      ((,key ,name ,var)
+                       (cons key
+                             (pmatch (hashq-ref (hashq-ref allocation var) 
self)
+                               ((#t ,boxed . ,n) n)
+                               (,a (error "bad keyword allocation" x a)))))
+                      (,x (error "bad keyword" x))))
+                  (cdr kw))
+             (car kw) nlocs else-label))
+           ((or rest opt)
+            (make-glil-opt-prelude
+             (length req) (length (or opt '())) (and rest #t) nlocs 
else-label))
+           (#t
+            (make-glil-std-prelude (length req) nlocs else-label))))
+         ;; box args if necessary
+         (for-each
+          (lambda (v)
+            (pmatch (hashq-ref (hashq-ref allocation v) self)
+              ((#t #t . ,n)
+               (emit-code #f (make-glil-lexical #t #f 'ref n))
+               (emit-code #f (make-glil-lexical #t #t 'box n)))))
+          vars)
+         ;; write bindings info
+         (if (not (null? vars))
+             (emit-bindings
+              #f
+              (let lp ((kw (if kw (cdr kw) '()))
+                       (names (append (if opt (reverse opt) '())
+                                      (reverse req)))
+                       (vars (list-tail vars (+ (length req)
+                                                (if opt (length opt) 0)
+                                                (if rest 1 0)))))
+                (pmatch kw
+                  (() (reverse (if rest (cons rest names) names)))
+                  (((,key ,name ,var) . ,kw)
+                   (if (memq var vars)
+                       (lp kw (cons name names) (delq var vars))
+                       (lp kw names vars)))
+                  (,kw (error "bad keywords, yo" kw))))
+              vars allocation self emit-code))
+         ;; post-prelude case label for label calls
+         (emit-label (car (hashq-ref allocation x)))
          (if predicate
              (begin
                (comp-push predicate)


hooks/post-receive
-- 
GNU Guile




reply via email to

[Prev in Thread] Current Thread [Next in Thread]