oxidize index_of and indices_of for dissociated press

This commit is contained in:
Scott Richmond 2025-07-06 16:52:54 -04:00
parent b5a279371f
commit 9ea1a9905f
6 changed files with 42 additions and 51 deletions

View File

@ -859,52 +859,14 @@ fn butlast {
} }
fn indices_of { fn indices_of {
"Takes a list or string and returns a list of all the indices where the scrutinee appears. Returns an empty list if the scrutinee does not appear in the search target." "Takes a list or string and returns a list of all the indices where the target appears. Returns an empty list if the target does not appear in the scrutinee."
(target as :list, scrutinee) -> { (scrutinee as :list, target) -> base :indices_of (scrutinee, target)
fn searcher ((i, indices), curr) -> if eq? (scrutinee, curr)
then (inc (i), append (indices, i))
else (inc (i), indices)
let (_, idxes) = fold (searcher, target, (0, []))
idxes
}
& (target as :string, scrutinee as :string) -> {
& let scrut_len = count (scrutinee)
& fn searcher ((i, indices), curr) -> {
& let srch_substr = slice_n (remaining, scrut_len)
& if eq? (scrutinee, srch_substr)
& then (inc (i), append (indices, i))
& else (inc (i), indices)
& }
& let (_, idxes) = fold (searcher, target, (0, []))
& idxes
& }
} }
fn index_of { fn index_of {
"Takes a list or string returns the first index at which the scrutinee appears. Returns `nil` if the scrutinee does not appear in the search target." "Takes a list or string returns the first index at which the scrutinee appears. Returns `nil` if the scrutinee does not appear in the search target."
(target as :list, scrutinee) -> first (indices_of (target, scrutinee)) (scrutinee as :list, target) -> base :index_of (scrutinee, target)
(target as :string, scrutinee as :string) -> first (indices_of (target, scrutinee))
} }
& (target as :list, scrutinee) -> loop (0) with {
& (i) if gte? (i, count (target)) -> nil
& (i) -> if eq? (scrutinee, at (target, i))
& then i
& else recur (inc (i))
& }
& (target as :string, scrutinee as :string) -> {
& let scrut_len = count (scrutinee)
& loop (0, target) with {
& (i, "") -> nil
& (i, remaining) -> {
& let srch_substr = slice_n (remaining, scrut_len)
& if eq? (scrutinee, srch_substr)
& then i
& else recur (inc (i), rest (remaining))
& }
& }
& }
& }
&&& keywords: funny names &&& keywords: funny names
fn keyword? { fn keyword? {

4
pkg/rudus.d.ts vendored
View File

@ -14,8 +14,8 @@ export interface InitOutput {
readonly __wbindgen_malloc: (a: number, b: number) => number; readonly __wbindgen_malloc: (a: number, b: number) => number;
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
readonly __wbindgen_export_6: WebAssembly.Table; readonly __wbindgen_export_6: WebAssembly.Table;
readonly closure359_externref_shim: (a: number, b: number, c: any) => void; readonly closure361_externref_shim: (a: number, b: number, c: any) => void;
readonly closure382_externref_shim: (a: number, b: number, c: any, d: any) => void; readonly closure384_externref_shim: (a: number, b: number, c: any, d: any) => void;
readonly __wbindgen_start: () => void; readonly __wbindgen_start: () => void;
} }

View File

@ -240,13 +240,13 @@ function _assertNum(n) {
function __wbg_adapter_20(arg0, arg1, arg2) { function __wbg_adapter_20(arg0, arg1, arg2) {
_assertNum(arg0); _assertNum(arg0);
_assertNum(arg1); _assertNum(arg1);
wasm.closure359_externref_shim(arg0, arg1, arg2); wasm.closure361_externref_shim(arg0, arg1, arg2);
} }
function __wbg_adapter_46(arg0, arg1, arg2, arg3) { function __wbg_adapter_46(arg0, arg1, arg2, arg3) {
_assertNum(arg0); _assertNum(arg0);
_assertNum(arg1); _assertNum(arg1);
wasm.closure382_externref_shim(arg0, arg1, arg2, arg3); wasm.closure384_externref_shim(arg0, arg1, arg2, arg3);
} }
async function __wbg_load(module, imports) { async function __wbg_load(module, imports) {
@ -403,8 +403,8 @@ function __wbg_get_imports() {
_assertBoolean(ret); _assertBoolean(ret);
return ret; return ret;
}; };
imports.wbg.__wbindgen_closure_wrapper8162 = function() { return logError(function (arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper8168 = function() { return logError(function (arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 360, __wbg_adapter_20); const ret = makeMutClosure(arg0, arg1, 362, __wbg_adapter_20);
return ret; return ret;
}, arguments) }; }, arguments) };
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) { imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {

BIN
pkg/rudus_bg.wasm (Stored with Git LFS)

Binary file not shown.

View File

@ -9,6 +9,6 @@ export const __wbindgen_free: (a: number, b: number, c: number) => void;
export const __wbindgen_malloc: (a: number, b: number) => number; export const __wbindgen_malloc: (a: number, b: number) => number;
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
export const __wbindgen_export_6: WebAssembly.Table; export const __wbindgen_export_6: WebAssembly.Table;
export const closure359_externref_shim: (a: number, b: number, c: any) => void; export const closure361_externref_shim: (a: number, b: number, c: any) => void;
export const closure382_externref_shim: (a: number, b: number, c: any, d: any) => void; export const closure384_externref_shim: (a: number, b: number, c: any, d: any) => void;
export const __wbindgen_start: () => void; export const __wbindgen_start: () => void;

View File

@ -123,6 +123,27 @@ pub fn words(str: &Value) -> Value {
Value::list(words) Value::list(words)
} }
pub fn index_of(scrutinee: &Value, target: &Value) -> Value {
let scrutinee = scrutinee.as_list();
for (i, value) in scrutinee.iter().enumerate() {
if value == target {
return Value::from_usize(i);
}
}
Value::Nil
}
pub fn indices_of(scrutinee: &Value, target: &Value) -> Value {
let scrutinee = scrutinee.as_list();
let mut indices = Vector::new();
for (i, value) in scrutinee.iter().enumerate() {
if value == target {
indices.push_back(Value::from_usize(i))
}
}
Value::list(indices)
}
// TODO: figure out how to get to opportunistic mutation here // TODO: figure out how to get to opportunistic mutation here
pub fn concat(x: &Value, y: &Value) -> Value { pub fn concat(x: &Value, y: &Value) -> Value {
match (x, y) { match (x, y) {
@ -662,6 +683,14 @@ pub fn make_base() -> Value {
("gt?", Value::BaseFn(Box::new(BaseFn::Binary("gt?", gt)))), ("gt?", Value::BaseFn(Box::new(BaseFn::Binary("gt?", gt)))),
("gte?", Value::BaseFn(Box::new(BaseFn::Binary("gte?", gte)))), ("gte?", Value::BaseFn(Box::new(BaseFn::Binary("gte?", gte)))),
("inc", Value::BaseFn(Box::new(BaseFn::Unary("inc", inc)))), ("inc", Value::BaseFn(Box::new(BaseFn::Unary("inc", inc)))),
(
"index_of",
Value::BaseFn(Box::new(BaseFn::Binary("index_of", index_of))),
),
(
"indices_of",
Value::BaseFn(Box::new(BaseFn::Binary("indices_of", indices_of))),
),
("last", Value::BaseFn(Box::new(BaseFn::Unary("last", last)))), ("last", Value::BaseFn(Box::new(BaseFn::Unary("last", last)))),
("list", Value::BaseFn(Box::new(BaseFn::Unary("list", list)))), ("list", Value::BaseFn(Box::new(BaseFn::Unary("list", list)))),
("lt?", Value::BaseFn(Box::new(BaseFn::Binary("lt?", lt)))), ("lt?", Value::BaseFn(Box::new(BaseFn::Binary("lt?", lt)))),