diff options
-rw-r--r-- | lib.c | 96 | ||||
-rw-r--r-- | tests/012/callable.tl | 8 | ||||
-rw-r--r-- | txr.1 | 28 |
3 files changed, 101 insertions, 31 deletions
@@ -13134,42 +13134,78 @@ val replace(val seq, val items, val from, val to) val dwim_set(val place_p, val seq, varg vargs) { val self = lit("index/range assignment"); + type_t st = type(seq); - switch (type(seq)) { - case COBJ: - if (type(seq) == COBJ) { - if (seq->co.cls == hash_cls) { - args_normalize_least(vargs, 3); - - switch (vargs->fill) { - case 2: - (void) sethash(seq, vargs->arg[0], vargs->arg[1]); - break; - case 3: - if (vargs->list) - goto excargs; - (void) sethash(seq, vargs->arg[0], vargs->arg[2]); - break; - default: - goto fewargs; + switch (st) { + case NUM: + case BGNUM: + case RNG: + { + args_normalize_least(vargs, 3); + switch (vargs->fill) { + case 2: + { + val arg = vargs->arg[0]; + val newval = vargs->arg[1]; + switch (type(arg)) { + case NUM: + case BGNUM: + case RNG: + goto notplace; + default: + if (st == RNG) { + range_bind (x, y, seq); + if (!place_p && listp(arg)) + goto notplace; + return replace(arg, newval, x, y); + } else { + (void) refset(arg, seq, newval); + return seq; + } + } } + case 1: + case 0: + goto fewargs; + default: + goto excargs; + } + } + case COBJ: + if (seq->co.cls == hash_cls) { + args_normalize_least(vargs, 3); - return seq; + switch (vargs->fill) { + case 2: + (void) sethash(seq, vargs->arg[0], vargs->arg[1]); + break; + case 3: + if (vargs->list) + goto excargs; + (void) sethash(seq, vargs->arg[0], vargs->arg[2]); + break; + case 1: + case 0: + goto fewargs; + default: + goto excargs; } - if (obj_struct_p(seq)) { - { - val lambda_set_meth = get_special_slot(seq, lambda_set_m); - if (lambda_set_meth) { - (void) funcall(method_args(seq, lambda_set_s, vargs)); - return seq; - } + + return seq; + } + if (obj_struct_p(seq)) { + { + val lambda_set_meth = get_special_slot(seq, lambda_set_m); + if (lambda_set_meth) { + (void) funcall(method_args(seq, lambda_set_s, vargs)); + return seq; } - if (get_special_slot(seq, car_m)) - goto list; - type_mismatch(lit("~a: object ~s lacks " - "~s or ~s method"), - self, seq, lambda_set_s, car_s, nao); } + if (get_special_slot(seq, car_m)) + goto list; + type_mismatch(lit("~a: object ~s lacks " + "~s or ~s method"), + self, seq, lambda_set_s, car_s, nao); } /* fallthrough */ default: diff --git a/tests/012/callable.tl b/tests/012/callable.tl index 0f0e9327..9e88b955 100644 --- a/tests/012/callable.tl +++ b/tests/012/callable.tl @@ -21,3 +21,11 @@ (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))) + +(mtest + (set [1 1] 2) :error + (set [1 1..2] 2) :error + (set [1..2 1] 2) :error + (set [1..2 1..2] 2) :error + (let ((abc "abc")) (set [1..2 abc] "42") abc) "a42c" + (let ((abc "abc")) (set [1 abc] #\d) abc) "adc") @@ -14291,10 +14291,14 @@ defined by \*(TX programs. .mets (gethash < hash < key <> [ alt ]) .mets (hash-userdata << hash ) .mets (dwim < obj-place < index <> [ alt ]) +.mets (dwim < integer < obj-place ) ;; integers are callable +.mets (dwim < range < obj-place ) ;; ranges are callable .mets (sub-list < obj >> [ from <> [ to ]]) .mets (sub-vec < obj >> [ from <> [ to ]]) .mets (sub-str < str >> [ from <> [ to ]]) .mets >> [ obj-place < index <> [ alt ]] ;; equivalent to dwim +.mets >> [ integer < obj-place ] +.mets >> [ range < obj-place ] .mets (symbol-value << symbol-valued-form ) .mets (symbol-function << function-name-valued-form ) .mets (symbol-macro << symbol-valued-form ) @@ -15966,9 +15970,11 @@ retrieve a global macro expander using the function .coNP Operator @ dwim .synb .mets (dwim << argument *) -.mets <> '[' argument *']' .mets (set (dwim < obj-place < index <> [ alt ]) << new-value ) +.mets (set (dwim >> { integer | << range } << obj-place ) << new-value ) +.mets <> '[' argument *']' .mets (set >> '[' obj-place < index <> [ alt ]']' << new-value ) +.mets (set >> '[{' integer | << range } << obj-place']' << new-value ) .syne .desc The @@ -16296,14 +16302,34 @@ These, in turn, rely on the specialized functions. .code carray-sub and .codn carray-replace . + .meIP >> [ buf << index ] Indexing is supported for objects of type .codn buf . This provides a way to access and store the individual bytes of a buffer. + +.meIP >> [ integer << sequence ] +If the left argument is an integer, it denotes selection of an +element from +.metn sequence . +The +.meta integer +value acts as the index into a vector-like or list-like sequence, +or a key into a hash table. + +.meIP >> [ range << sequence ] +If the left argument is an range, it denotes selection of a +subrange of +.metn sequence . .RE .PP +Note that the various above forms are not actually special cases of +.code dwim +but the consequence of the objects appearing as the first argument being +callable as functions, and their respective semantics. + .TP* "Range Indexing:" Vector and list range indexing is based from zero, meaning that the first element is numbered zero, the second one |