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 {
"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."
(target as :list, scrutinee) -> {
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
& }
"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."
(scrutinee as :list, target) -> base :indices_of (scrutinee, target)
}
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."
(target as :list, scrutinee) -> first (indices_of (target, scrutinee))
(target as :string, scrutinee as :string) -> first (indices_of (target, scrutinee))
(scrutinee as :list, target) -> base :index_of (scrutinee, target)
}
& (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
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_realloc: (a: number, b: number, c: number, d: number) => number;
readonly __wbindgen_export_6: WebAssembly.Table;
readonly closure359_externref_shim: (a: number, b: number, c: any) => void;
readonly closure382_externref_shim: (a: number, b: number, c: any, d: any) => void;
readonly closure361_externref_shim: (a: number, b: number, c: any) => void;
readonly closure384_externref_shim: (a: number, b: number, c: any, d: any) => void;
readonly __wbindgen_start: () => void;
}

View File

@ -240,13 +240,13 @@ function _assertNum(n) {
function __wbg_adapter_20(arg0, arg1, arg2) {
_assertNum(arg0);
_assertNum(arg1);
wasm.closure359_externref_shim(arg0, arg1, arg2);
wasm.closure361_externref_shim(arg0, arg1, arg2);
}
function __wbg_adapter_46(arg0, arg1, arg2, arg3) {
_assertNum(arg0);
_assertNum(arg1);
wasm.closure382_externref_shim(arg0, arg1, arg2, arg3);
wasm.closure384_externref_shim(arg0, arg1, arg2, arg3);
}
async function __wbg_load(module, imports) {
@ -403,8 +403,8 @@ function __wbg_get_imports() {
_assertBoolean(ret);
return ret;
};
imports.wbg.__wbindgen_closure_wrapper8162 = function() { return logError(function (arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 360, __wbg_adapter_20);
imports.wbg.__wbindgen_closure_wrapper8168 = function() { return logError(function (arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 362, __wbg_adapter_20);
return ret;
}, arguments) };
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_realloc: (a: number, b: number, c: number, d: number) => number;
export const __wbindgen_export_6: WebAssembly.Table;
export const closure359_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 closure361_externref_shim: (a: number, b: number, c: any) => void;
export const closure384_externref_shim: (a: number, b: number, c: any, d: any) => void;
export const __wbindgen_start: () => void;

View File

@ -123,6 +123,27 @@ pub fn words(str: &Value) -> Value {
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
pub fn concat(x: &Value, y: &Value) -> Value {
match (x, y) {
@ -662,6 +683,14 @@ pub fn make_base() -> Value {
("gt?", Value::BaseFn(Box::new(BaseFn::Binary("gt?", gt)))),
("gte?", Value::BaseFn(Box::new(BaseFn::Binary("gte?", gte)))),
("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)))),
("list", Value::BaseFn(Box::new(BaseFn::Unary("list", list)))),
("lt?", Value::BaseFn(Box::new(BaseFn::Binary("lt?", lt)))),