summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-01-25 09:59:40 -0800
committerKaz Kylheku <kaz@kylheku.com>2012-01-25 09:59:40 -0800
commit11173ced6d65339869fe74fbc9c4452a75e3fe26 (patch)
tree6c7e21fa0f7ebab6d5b4af9dc960fd96660682be /lib.c
parent8b4578f295cc022e8bf0bb62d1a8cf8673636f27 (diff)
downloadtxr-11173ced6d65339869fe74fbc9c4452a75e3fe26.tar.gz
txr-11173ced6d65339869fe74fbc9c4452a75e3fe26.tar.bz2
txr-11173ced6d65339869fe74fbc9c4452a75e3fe26.zip
* eval.c (dwim_s): New symbol variable.
(dwim_loc, op_dwim): New static functions. (op_modplace): Support assignment to dwim forms with the help of dwim_loc. (expand_place): Handle dwim places. (eval_init): Initialize dwim_s. Register dwim operator in op_table. * eval.h (dwim_s): Declared. * lib.c (chr_str, chr_str_set): Allow negative indices to index backwards from end of string. (vecref, vecref_l): Allow negative indices to index from rear of array. (obj_print, obj_pprint): Render (dwim ...) forms as [...]. * parser.l: Peoduce new METABKT token type for @[, and '[', ']' tokens. * parser.y (METABKT): New token. %type declaration for '['. (list): Support square-bracket style of list, translated into dwim form. (meta_expr): Support @[...] variant. (yybadtoken): Handle METABKT in switch. * txr.1: Documented [...] syntax and dwim operator. * txr.vim: Updated.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c78
1 files changed, 56 insertions, 22 deletions
diff --git a/lib.c b/lib.c
index a05ead7e..7496385b 100644
--- a/lib.c
+++ b/lib.c
@@ -1630,27 +1630,41 @@ val chr_num(val num)
return chr(n);
}
-val chr_str(val str, val index)
+val chr_str(val str, val ind)
{
- bug_unless (length_str_gt(str, index));
+ cnum index = c_num(ind);
+
+ if (index < 0) {
+ ind = plus(length_str(str), ind);
+ index = c_num(ind);
+ }
+
+ bug_unless (index >= 0 && length_str_gt(str, ind));
if (lazy_stringp(str)) {
- lazy_str_force_upto(str, index);
- return chr(c_str(str->ls.prefix)[c_num(index)]);
+ lazy_str_force_upto(str, ind);
+ return chr(c_str(str->ls.prefix)[index]);
} else {
- return chr(c_str(str)[c_num(index)]);
+ return chr(c_str(str)[index]);
}
}
-val chr_str_set(val str, val index, val chr)
+val chr_str_set(val str, val ind, val chr)
{
- bug_unless (length_str_gt(str, index));
+ cnum index = c_num(ind);
+
+ if (index < 0) {
+ ind = plus(length_str(str), ind);
+ index = c_num(ind);
+ }
+
+ bug_unless (index >= 0 && length_str_gt(str, ind));
if (lazy_stringp(str)) {
- lazy_str_force_upto(str, index);
- str->ls.prefix->st.str[c_num(index)] = c_chr(chr);
+ lazy_str_force_upto(str, ind);
+ str->ls.prefix->st.str[index] = c_chr(chr);
} else {
- str->st.str[c_num(index)] = c_chr(chr);
+ str->st.str[index] = c_chr(chr);
}
return chr;
@@ -2493,16 +2507,20 @@ val vec_set_length(val vec, val length)
val vecref(val vec, val ind)
{
- type_check(vec, VEC);
- range_bug_unless (c_num(ind) < c_num(vec->v.vec[vec_length]));
- return vec->v.vec[c_num(ind)];
+ cnum index = c_num(ind);
+ cnum len = c_num(length_vec(vec));
+ if (index < 0)
+ index = len + index;
+ range_bug_unless (index >= 0 && index < len);
+ return vec->v.vec[index];
}
val *vecref_l(val vec, val ind)
{
- type_check(vec, VEC);
- range_bug_unless (c_num(ind) < c_num(vec->v.vec[vec_length]));
- return vec->v.vec + c_num(ind);
+ cnum index = c_num(ind);
+ cnum len = c_num(length_vec(vec));
+ range_bug_unless (index >= 0 && index < len);
+ return vec->v.vec + index;
}
val vec_push(val vec, val item)
@@ -3385,17 +3403,25 @@ val obj_print(val obj, val out)
obj_print(second(obj), out);
} else {
val iter;
- put_char(out, chr('('));
+ val closepar = chr(')');
+ if (sym == dwim_s && consp(cdr(obj))) {
+ put_char(out, chr('['));
+ obj = cdr(obj);
+ closepar = chr(']');
+ } else {
+ put_char(out, chr('('));
+ }
+
for (iter = obj; consp(iter); iter = cdr(iter)) {
obj_print(car(iter), out);
if (nullp(cdr(iter))) {
- put_char(out, chr(')'));
+ put_char(out, closepar);
} else if (consp(cdr(iter))) {
put_char(out, chr(' '));
} else {
put_string(out, lit(" . "));
obj_print(cdr(iter), out);
- put_char(out, chr(')'));
+ put_char(out, closepar);
}
}
}
@@ -3524,17 +3550,25 @@ val obj_pprint(val obj, val out)
obj_pprint(second(obj), out);
} else {
val iter;
- put_char(out, chr('('));
+ val closepar = chr(')');
+ if (sym == dwim_s && consp(cdr(obj))) {
+ put_char(out, chr('['));
+ obj = cdr(obj);
+ closepar = chr(']');
+ } else {
+ put_char(out, chr('('));
+ }
+
for (iter = obj; consp(iter); iter = cdr(iter)) {
obj_pprint(car(iter), out);
if (nullp(cdr(iter))) {
- put_char(out, chr(')'));
+ put_char(out, closepar);
} else if (consp(cdr(iter))) {
put_char(out, chr(' '));
} else {
put_string(out, lit(" . "));
obj_pprint(cdr(iter), out);
- put_char(out, chr(')'));
+ put_char(out, closepar);
}
}
}