summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/lib.c b/lib.c
index 7875c7d2..97a36e3e 100644
--- a/lib.c
+++ b/lib.c
@@ -8537,7 +8537,7 @@ INLINE val do_generic_funcall(val fun, varg args_in)
case 0:
callerror(fun, lit("missing required arguments"));
case 1:
- return sub(args->arg[0], fun->rn.from, fun->rn.to);
+ return rangeref(fun, args->arg[0]);
default:
callerror(fun, lit("too many arguments"));
}
@@ -13288,6 +13288,8 @@ val ref(val seq, val ind)
return vecref(seq, ind);
case BUF:
return buf_get_uchar(seq, ind);
+ case RNG:
+ return rangeref(seq, ind);
default:
type_mismatch(lit("ref: ~s is not a sequence"), seq, nao);
}
@@ -14039,6 +14041,37 @@ val in_range_star(val range, val num)
}
}
+val rangeref(val range, val ind)
+{
+ val self = lit("rangeref");
+
+ if (integerp(ind))
+ {
+ val fr = range->rn.from;
+ val to = range->rn.to;
+ val eind = ind;
+
+ if (to != t && to != colon_k) {
+ val len = minus(to, fr);
+
+ if (minusp(eind))
+ eind = plus(eind, len);
+
+ if (minusp(eind) || ge(eind, len))
+ goto err;
+ } else if (minusp(eind)) {
+ goto err;
+ }
+
+ return plus(fr, eind);
+ err:
+ uw_throwf(error_s, lit("~a: ~s is out of range for ~s"),
+ self, ind, range, nao);
+ }
+
+ return sub(ind, range->rn.from, range->rn.to);
+}
+
#if CONFIG_LOCALE_TOLERANCE
static void locale_init(void)