diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | eval.c | 14 | ||||
-rw-r--r-- | lib.c | 17 | ||||
-rw-r--r-- | lib.h | 1 | ||||
-rw-r--r-- | txr.1 | 24 |
5 files changed, 55 insertions, 13 deletions
@@ -1,5 +1,17 @@ 2014-02-02 Kaz Kylheku <kaz@kylheku.com> + * eval.c (apply): Support string and vector arglist. + (do_eval_args): Support string or vector in dot position. + + * lib.c (tolist): New function. + + * lib.h (tolist): Declared. + + * txr.1: Document how apply and dot position in compound forms + supports strings as well as vectors. + +2014-02-02 Kaz Kylheku <kaz@kylheku.com> + * eval.c (do_eval_args): If the dotted position of the argument list evaluates to a vector, then convert the vector to a list. @@ -312,8 +312,13 @@ val apply(val fun, val arglist, val ctx_form) type_check (fun, FUN); - type_assert (listp(arglist), - (lit("~s: arglist ~s is not a list"), car(ctx_form), arglist, nao)); + if (!listp(arglist)) { + val arglist_conv = tolist(arglist); + type_assert (listp(arglist_conv), + (lit("~s: arglist ~s is not a list"), car(ctx_form), + arglist, nao)); + arglist = arglist_conv; + } variadic = fun->f.variadic; fixparam = fun->f.fixparam; @@ -430,9 +435,8 @@ static val do_eval_args(val form, val env, val ctx_form, ptail = list_collect(ptail, do_eval(car(form), env, ctx_form, lookup)); if (form) { val dotpos = do_eval(form, env, ctx_form, lookup); - ptail = list_collect_append(ptail, if3(vectorp(dotpos), - list_vector(dotpos), - dotpos)); + ptail = list_collect_append(ptail, if3(listp(dotpos), + dotpos, tolist(dotpos))); } return values; } @@ -470,6 +470,23 @@ val to_seq(val seq) } } +val tolist(val seq) +{ + switch (type(seq)) { + case VEC: + return list_vector(seq); + case STR: + case LIT: + case LSTR: + return list_str(seq); + case NIL: + case CONS: + case LCONS: + default: + return seq; + } +} + val *list_collect(val *ptail, val obj) { switch (type(*ptail)) { @@ -377,6 +377,7 @@ val push(val v, val *plist); val copy_list(val list); val make_like(val list, val thatobj); val to_seq(val obj); +val tolist(val seq); val nreverse(val in); val reverse(val in); val append2(val list1, val list2); @@ -5022,10 +5022,11 @@ If the form is a function call then the arguments are evaluated. If any of the arugments are symbols, they are treated according to Lisp-2 namespacing rules. Additionally, if there is an expression in the dotted position, it is also -evaluated. It should evaluate to a list or vector. The elements of the list -or vector generate additional arguments for the function call. -In some other Lisp dialects, a function called apply (or similar) must be -used to do the same thing. +evaluated. It should evaluate to a sequence: a list, vector or string. The +elements of the sequence generate additional arguments for the function +call. In some other Lisp dialects, a function called apply (or similar) must +be used to do the same thing, and applying sequences other than lists is not +supported. The DWIM brackets are similar, except that the first position is an arbitrary expression which is evaluated according to the same rules as the remaining @@ -5041,9 +5042,11 @@ Examples: ;; a contains 3 ;; b contains 4 ;; c contains #(5 6 7) + ;; s contains "xyz" (foo a b . c) ;; calls (foo 3 4 5 6 7) (foo a) ;; calls (foo 3) + (foo . s) ;; calls (foo #\ex #\ey #\ez) [foo a b . c] ;; calls (foo 3 4 5 6 7) @@ -7130,14 +7133,16 @@ can be expressed as: .TP Syntax: - (apply <function> <arglist>) + (apply <function> <argsequence>) .TP Description: -The apply function converts a list of values <arglist> into individual arguments -which are passed to <function>. The return value of the apply invocation is -that of <function>. +The apply function converts a sequence of values <argsequence> into individual +arguments which are passed to <function>. The return value of the apply +invocation is that of <function>. + +<argsequence> must be list, vector or string. .TP Examples: @@ -7145,6 +7150,9 @@ Examples: ;; '(1 2 3) becomes arguments to list, thus (list 1 2 3). (apply (fun list) '(1 2 3)) -> (1 2 3) + ;; "abc" is separated into characters which become arguments of list + (apply (fun list) "abc") -> (#\ea #\eb #\ec) + .TP Dialect Note 1: |