A few changes.

This commit is contained in:
Calvin Rose 2018-05-18 16:24:09 -04:00
parent 4ecc88af37
commit 36ecbeffa6
2 changed files with 52 additions and 27 deletions

View File

@ -396,7 +396,6 @@ an indexed type (array, tuple) with a function to produce a value."
"Map a function over every element in an array or tuple and return
the same type as the input sequence."
[f & inds]
(def res @[])
(def ninds (length inds))
(if (= 0 ninds) (error "expected at least 1 indexed collection."))
(var limit (length (get inds 0)))
@ -404,13 +403,14 @@ the same type as the input sequence."
(def l (length (get inds i)))
(if (< l limit) (:= limit l)))
(def [i1 i2 i3 i4] inds)
(def res (array.new limit))
(switch ninds
1 (for [i 0 limit] (array.push res (f (get i1 i))))
2 (for [i 0 limit] (array.push res (f (get i1 i) (get i2 i))))
3 (for [i 0 limit] (array.push res (f (get i1 i) (get i2 i) (get i3 i))))
4 (for [i 0 limit] (array.push res (f (get i1 i) (get i2 i) (get i3 i) (get i4 i))))
(for [i 0 limit]
(def args @[])
(def args (array.new ninds))
(for [j 0 ninds] (array.push args (get (get inds j) i)))
(array.push res (apply1 f args))))
res)
@ -432,7 +432,7 @@ return a new indexed type."
3 (for [i 0 limit] (f (get i1 i) (get i2 i) (get i3 i)))
4 (for [i 0 limit] (f (get i1 i) (get i2 i) (get i3 i) (get i4 i)))
(for [i 0 limit]
(def args @[])
(def args (array.new ninds))
(for [j 0 ninds] (array.push args (get (get inds j) i)))
(apply1 f args))))
@ -452,8 +452,9 @@ type as the input sequence."
"Given a predicate, take only elements from an array or tuple for
which (pred element) is truthy. Returns the same type as the input sequence."
[pred ind t]
(def res @[])
(for [i 0 (length ind)]
(def len (length ind))
(def res (array.new len))
(for [i 0 len]
(def item (get ind i))
(if (pred item)
(array.push res item)))
@ -461,6 +462,13 @@ which (pred element) is truthy. Returns the same type as the input sequence."
(apply1 tuple res)
res))
(defn range
"Create an array of values [0, n)."
[n]
(def arr (array.new n))
(for [i 0 n] (put arr i i))
arr)
(defn find-index
"Find the index of indexed type for which pred is true. Returns nil if not found."
[pred ind]

View File

@ -711,14 +711,14 @@ static int cfun_reverse(DstArgs args) {
DST_RETURN_STRING(args, dst_string_end(buf));
}
static int findsetup(DstArgs args, struct kmp_state *s) {
static int findsetup(DstArgs args, struct kmp_state *s, int32_t extra) {
const uint8_t *text, *pat;
int32_t textlen, patlen, start;
DST_MINARITY(args, 2);
DST_MAXARITY(args, 3);
DST_MAXARITY(args, 3 + extra);
DST_ARG_BYTES(pat, patlen, args, 0);
DST_ARG_BYTES(text, textlen, args, 1);
if (args.n == 3) {
if (args.n >= 3) {
DST_ARG_INTEGER(start, args, 2);
if (start < 0) {
DST_THROW(args, "expected non-negative start index");
@ -734,7 +734,7 @@ static int findsetup(DstArgs args, struct kmp_state *s) {
static int cfun_find(DstArgs args) {
int32_t result;
struct kmp_state state;
int status = findsetup(args, &state);
int status = findsetup(args, &state, 0);
if (status) return status;
result = kmp_next(&state);
kmp_deinit(&state);
@ -747,7 +747,7 @@ static int cfun_findall(DstArgs args) {
int32_t result;
DstArray *array;
struct kmp_state state;
int status = findsetup(args, &state);
int status = findsetup(args, &state, 0);
if (status) return status;
array = dst_array(0);
while ((result = kmp_next(&state)) >= 0) {
@ -759,11 +759,7 @@ static int cfun_findall(DstArgs args) {
struct replace_state {
struct kmp_state kmp;
const uint8_t *text;
const uint8_t *pat;
const uint8_t *subst;
int32_t textlen;
int32_t patlen;
int32_t substlen;
};
@ -785,11 +781,7 @@ static int replacesetup(DstArgs args, struct replace_state *s) {
}
kmp_init(&s->kmp, text, textlen, pat, patlen);
s->kmp.i = start;
s->text = text;
s->pat = pat;
s->subst = subst;
s->patlen = patlen;
s->textlen = textlen;
s->substlen = substlen;
return DST_SIGNAL_OK;
}
@ -803,14 +795,14 @@ static int cfun_replace(DstArgs args) {
result = kmp_next(&s.kmp);
if (result < 0) {
kmp_deinit(&s.kmp);
DST_RETURN_STRING(args, dst_string(s.text, s.textlen));
DST_RETURN_STRING(args, dst_string(s.kmp.text, s.kmp.textlen));
}
buf = dst_string_begin(s.textlen - s.patlen + s.substlen);
memcpy(buf, s.text, result);
buf = dst_string_begin(s.kmp.textlen - s.kmp.patlen + s.substlen);
memcpy(buf, s.kmp.text, result);
memcpy(buf + result, s.subst, s.substlen);
memcpy(buf + result + s.substlen,
s.text + result + s.patlen,
s.textlen - result - s.patlen);
s.kmp.text + result + s.kmp.patlen,
s.kmp.textlen - result - s.kmp.patlen);
kmp_deinit(&s.kmp);
DST_RETURN_STRING(args, dst_string_end(buf));
}
@ -823,19 +815,43 @@ static int cfun_replaceall(DstArgs args) {
int32_t lastindex = 0;
int status = replacesetup(args, &s);
if (status) return status;
dst_buffer_init(&b, s.textlen);
dst_buffer_init(&b, s.kmp.textlen);
while ((result = kmp_next(&s.kmp)) >= 0) {
dst_buffer_push_bytes(&b, s.text + lastindex, result - lastindex);
dst_buffer_push_bytes(&b, s.kmp.text + lastindex, result - lastindex);
dst_buffer_push_bytes(&b, s.subst, s.substlen);
lastindex = result + s.patlen;
lastindex = result + s.kmp.patlen;
}
dst_buffer_push_bytes(&b, s.text + lastindex, s.textlen - lastindex);
dst_buffer_push_bytes(&b, s.kmp.text + lastindex, s.kmp.textlen - lastindex);
ret = dst_string(b.data, b.count);
dst_buffer_deinit(&b);
kmp_deinit(&s.kmp);
DST_RETURN_STRING(args, ret);
}
static int cfun_split(DstArgs args) {
int32_t result;
DstArray *array;
struct kmp_state state;
int32_t limit = -1, lastindex = 0;
if (args.n == 4) {
DST_ARG_INTEGER(limit, args, 3);
}
int status = findsetup(args, &state, 1);
if (status) return status;
array = dst_array(0);
while ((result = kmp_next(&state)) >= 0 && limit--) {
const uint8_t *slice = dst_string(state.text + lastindex, result - lastindex);
dst_array_push(array, dst_wrap_string(slice));
lastindex = result + state.patlen;
}
{
const uint8_t *slice = dst_string(state.text + lastindex, state.textlen - lastindex);
dst_array_push(array, dst_wrap_string(slice));
}
kmp_deinit(&state);
DST_RETURN_ARRAY(args, array);
}
static const DstReg cfuns[] = {
{"string.slice", cfun_slice},
{"string.repeat", cfun_repeat},
@ -848,6 +864,7 @@ static const DstReg cfuns[] = {
{"string.find-all", cfun_findall},
{"string.replace", cfun_replace},
{"string.replace-all", cfun_replaceall},
{"string.split", cfun_split},
{NULL, NULL}
};