diff options
-rw-r--r-- | lib.c | 26 | ||||
-rw-r--r-- | tests/012/callable.tl | 23 | ||||
-rw-r--r-- | tests/012/iter.tl | 4 | ||||
-rw-r--r-- | txr.1 | 35 |
4 files changed, 86 insertions, 2 deletions
@@ -8333,6 +8333,7 @@ INLINE val do_generic_funcall(val fun, struct args *args_in) case BUF: carray: default: + dfl: bug_unless (args->argc >= ARGS_MIN); args_normalize_least(args, 3); @@ -8364,6 +8365,31 @@ INLINE val do_generic_funcall(val fun, struct args *args_in) fun = cdr(binding); } break; + case NUM: + case BGNUM: + args_normalize_least(args, 1); + + switch (args->fill) { + case 0: + callerror(fun, lit("missing required arguments")); + case 1: + return ref(args->arg[0], fun); + default: + callerror(fun, lit("too many arguments")); + } + case RNG: + if (opt_compat && opt_compat <= 288) + goto dfl; + args_normalize_least(args, 1); + + switch (args->fill) { + case 0: + callerror(fun, lit("missing required arguments")); + case 1: + return sub(args->arg[0], fun->rn.from, fun->rn.to); + default: + callerror(fun, lit("too many arguments")); + } case COBJ: if (fun->co.cls == hash_cls) { bug_unless (args->argc >= ARGS_MIN); diff --git a/tests/012/callable.tl b/tests/012/callable.tl new file mode 100644 index 00000000..0f0e9327 --- /dev/null +++ b/tests/012/callable.tl @@ -0,0 +1,23 @@ +(load "../common") + +(mtest + [0 '(1 2 3)] 1 + [1 '(1 2 3)] 2 + [2 '(1 2 3)] 3) + +(mtest + [0 "abc"] #\a + [1 "abc"] #\b + [2 "abc"] #\c) + +(mtest + [0..1 '(1 2 3)] (1) + [1..3 '(1 2 3)] (2 3)) + +(mtest + [0..0 "abc"] "" + [0..2 "abc"] "ab" + [-1..: "abc"] "c") + +(test (mapcar [callf list* 2 0 1 3..:] '((A B C X) (D E F Y) (G H I Z))) + ((C A B X) (F D E Y) (I G H Z))) diff --git a/tests/012/iter.tl b/tests/012/iter.tl index 9b1db6f5..1b1bfd1e 100644 --- a/tests/012/iter.tl +++ b/tests/012/iter.tl @@ -49,7 +49,7 @@ "D01" "D02" "D03" "D04" "D05" "D10" "D11" "D12" "D13" "D14" "D15" "E01" "E02" "E03" "E04" "E05" "E10" "E11" "E12" "E13" "E14" "E15" "F01" "F02" "F03" "F04" "F05" "F10" "F11" "F12" "F13" "F14" "F15") - [maprod append "A".."F" ["00".."99" 1..11]] + [maprod append "A".."F" [1..11 "00".."99"]] ("A01" "A02" "A03" "A04" "A05" "A06" "A07" "A08" "A09" "A10" "B01" "B02" "B03" "B04" "B05" "B06" "B07" "B08" "B09" "B10" "C01" "C02" "C03" "C04" "C05" "C06" "C07" "C08" "C09" "C10" "D01" "D02" "D03" @@ -58,7 +58,7 @@ "F06" "F07" "F08" "F09" "F10")) (test - [mapcar identity [0..10 3 6]] (3 4 5)) + [mapcar identity [3..6 0..10]] (3 4 5)) ;; iterating from fixnum to bignum was rejected in up to txr-269. (test (each ((x fixnum-max..(* 5 fixnum-max))) (return 42)) 42) @@ -13816,6 +13816,15 @@ operates on a string argument. It returns the leftmost matching substring, or else .codn nil . +Structure objects are callable if they implement the +.code lambda +method. + +Integers and ranges are callable like functions. They take one argument, +which must be a sequence or hash. An integer selects the corresponding +element position from the sequence, and a range extracts a slice of +its argument. + .B Example 1: .verb @@ -13878,6 +13887,26 @@ substring within the argument .strn abcd . +.B Example 5: + +.verb + [1 "abcd"] -> #\eb + + ["abcd" 1] -> #\eb +.brev +An integer used as function indexes into sequence. +This produces the same result as when the sequence is used +as a function with an integer argument. + +.B Example 6: + +.verb + [1..3 '(a b c d)] -> (b c) + ['(a b c d) 1..3] -> (b c) +.brev + +A range used as a function extracts a slice of its argument. + .SS* Special Variables Similarly to Common Lisp, \*(TL is lexically scoped by default, but also has dynamically scoped (a.k.a "special") variables. @@ -91611,6 +91640,12 @@ of these version values, the described behaviors are provided if is given an argument which is equal or lower. For instance .code "-C 103" selects the behaviors described below for version 105, but not those for 102. +.IP 288 +Integers and ranges callable like functions are a new feature introduced +after \*(TX 288. The latter, callable ranges, are a breaking change; +certain expressions with a range in the function position interpreted +the range as a sequence. Using this compatibility value disables ranges being +callable, restoring the old behaviors. .IP 283 In \*(TX 283 and older versions, the .meta flags |