diff options
author | Andy Wingo <wingo@pobox.com> | 2013-01-23 16:12:08 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2013-01-23 16:12:08 +0100 |
commit | 747bd5347d8b36c41809a16cb3f17b23e9afa9bf (patch) | |
tree | c8fa343e92b5446e92b38efaa105489f4817e9be /libguile/vm-i-system.c | |
parent | d7874b91830ebb1dbfc887d5309e5fce46a87fc2 (diff) | |
parent | faabd16157f8b55766cf890e79129c066fbc124b (diff) | |
download | guile-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.c | 59 |
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" |