summaryrefslogtreecommitdiff
path: root/libguile/vm-i-system.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2013-01-23 16:12:08 +0100
committerAndy Wingo <wingo@pobox.com>2013-01-23 16:12:08 +0100
commit747bd5347d8b36c41809a16cb3f17b23e9afa9bf (patch)
treec8fa343e92b5446e92b38efaa105489f4817e9be /libguile/vm-i-system.c
parentd7874b91830ebb1dbfc887d5309e5fce46a87fc2 (diff)
parentfaabd16157f8b55766cf890e79129c066fbc124b (diff)
downloadguile-747bd5347d8b36c41809a16cb3f17b23e9afa9bf.tar.gz
merge stable-2.0
There are some bugs with command-line handling that will be sorted out with the next commit.
Diffstat (limited to 'libguile/vm-i-system.c')
-rw-r--r--libguile/vm-i-system.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c
index a05326868..ac1d4a61a 100644
--- a/libguile/vm-i-system.c
+++ b/libguile/vm-i-system.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001,2008,2009,2010,2011,2012 Free Software Foundation, Inc.
+/* Copyright (C) 2001,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -647,6 +647,8 @@ VM_DEFINE_INSTRUCTION (49, bind_optionals_shuffle, "bind-optionals/shuffle", 6,
NEXT;
}
+/* See also bind-optionals/shuffle-or-br below. */
+
/* Flags that determine whether other keywords are allowed, and whether a
rest argument is expected. These values must match those used by the
glil->assembly compiler. */
@@ -1571,6 +1573,61 @@ VM_DEFINE_INSTRUCTION (95, assert_nargs_ee_locals, "assert-nargs-ee/locals", 1,
NEXT;
}
+/* Like bind-optionals/shuffle, but if there are too many positional
+ arguments, jumps to the next case-lambda clause. */
+VM_DEFINE_INSTRUCTION (96, bind_optionals_shuffle_or_br, "bind-optionals/shuffle-or-br", 9, -1, -1)
+{
+ SCM *walk;
+ scm_t_ptrdiff nreq, nreq_and_opt, ntotal;
+ scm_t_int32 offset;
+ nreq = FETCH () << 8;
+ nreq += FETCH ();
+ nreq_and_opt = FETCH () << 8;
+ nreq_and_opt += FETCH ();
+ ntotal = FETCH () << 8;
+ ntotal += FETCH ();
+ FETCH_OFFSET (offset);
+
+ /* look in optionals for first keyword or last positional */
+ /* starting after the last required positional arg */
+ walk = fp + nreq;
+ while (/* while we have args */
+ walk <= sp
+ /* and we still have positionals to fill */
+ && walk - fp < 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++;
+ if (/* If we have filled all the positionals */
+ walk - fp == nreq_and_opt
+ /* and there are still more arguments */
+ && walk <= sp
+ /* and the next argument is not a keyword, */
+ && !scm_is_keyword (*walk))
+ {
+ /* Jump to the next case-lambda* clause. */
+ ip += offset;
+ }
+ else
+ {
+ /* Otherwise, finish as in bind-optionals/shuffle: shuffle up,
+ from walk to ntotal */
+ scm_t_ptrdiff nshuf = sp - walk + 1, i;
+ sp = (fp - 1) + ntotal + nshuf;
+ CHECK_OVERFLOW ();
+ for (i = 0; i < nshuf; i++)
+ sp[-i] = walk[nshuf-i-1];
+
+ /* and fill optionals & keyword args with SCM_UNDEFINED */
+ while (walk <= (fp - 1) + ntotal)
+ *walk++ = SCM_UNDEFINED;
+ }
+
+ NEXT;
+}
+
+
/*
(defun renumber-ops ()
"start from top of buffer and renumber 'VM_DEFINE_FOO (\n' sequences"