Skip to content

Commit

Permalink
more stdlib stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
p7g committed Mar 12, 2021
1 parent d9a2ca9 commit fef874e
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 1 deletion.
20 changes: 20 additions & 0 deletions lib/arraylist.rbcvm
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,24 @@ doc:add(
"function",
"contains(list, thing)",
"Check if any element in `list` is equal to `thing`.",
);

export function to_iter(self) {
let pos = 0;

return function next() {
if (pos >= self:length) {
return null;
}

let val = get(self, pos);
pos = pos + 1;
return val;
};
}

doc:add(
"function",
"to_iter(list)",
"Create an iterator over the arraylist.",
);
6 changes: 6 additions & 0 deletions lib/char.rbcvm
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ export function is_lowercase(c) {

doc:add("function", "is_uppercase(c)", "Return true if `c` is lowercase.");

export function is_whitespace(c) {
return c == ' ' || c == '\n' || c == '\r' || c == '\t';
}

doc:add("function", "is_whitespace(c)", "Check if `c` is an ASCII whitespace character.");

export function to_uppercase(c) {
return chr(ord(c) & ~UPCASE_MASK);
}
Expand Down
54 changes: 54 additions & 0 deletions lib/iter.rbcvm
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,57 @@ export function flat(_it) {
}

doc:add("function", "flat(it)", "Flattens an iterator of iterators.");

export function fold1(it, reducer) {
it = ensure_iterable(it);
return fold(it, it(), reducer);
}

doc:add(
"function",
"fold1(it, reducer)",
"Reduce the iterator, using the first value as the initial value of the accumulator.",
);

export function fold(it, init, reducer) {
foreach(it, function (item) {
init = reducer(init, item);
});
return init;
}

doc:add(
"function",
"fold(it, init, reducer)",
"Reduce the iterator, using `init` as the initial value of the accumulator.",
);

export function max(it) {
return fold(it, null, function (greatest, item) {
if (greatest == null || item > greatest) {
return item;
}
return greatest;
});
}

doc:add(
"function",
"max(it)",
"Find the largest item in the iterator (using `>`).",
);

export function min(it) {
return fold(it, null, function (least, item) {
if (least == null || item < least) {
return item;
}
return least;
});
}

doc:add(
"function",
"min(it)",
"Find the smallest item in the iterator (using `<`).",
);
70 changes: 69 additions & 1 deletion lib/string.rbcvm
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import array;
import arraylist;
import char;
import docs;
import fn;
Expand Down Expand Up @@ -157,4 +158,71 @@ export function contains(self, c) {
return -1 != index(self, c);
}

doc:add("function", "contains(string, c)", "Check if `string` contains the character `c`.");
doc:add("function", "contains(string, c)", "Check if `string` contains the character `c`.");

export function lstrip(string, pred=char.is_whitespace) {
let chars = chars(string);
let len = array.length(chars);
for (let i = 0; i < len && pred(chars[i]); i = i + 1) {}
if (i == 0) {
return string;
}
return from_chars(array.slice(chars, i, len));
}

doc:add(
"function",
"lstrip(string, pred=char.is_whitespace)",
"Remove characters from the start of the string while `pred` remains true.",
);

export function rstrip(string, pred=char.is_whitespace) {
let chars = chars(string);
let len = array.length(chars);
for (let i = len - 1; i >= 0 && pred(chars[i]); i = i - 1) {}
if (i == len - 1) {
return string;
}
return from_chars(array.slice(chars, 0, i + 1));
}

doc:add(
"function",
"rstrip(string, pred=char.is_whitespace)",
"Remove characters from the end of the string while `pred` remains true.",
);

export function strip(string, lpred=char.is_whitespace, rpred=null) {
return rstrip(lstrip(string, lpred), rpred || lpred);
}

doc:add(
"function",
"strip(string, lpred=char.is_whitespace, rpred=null)",
"Remove characters from both ends of the string while predicates remain true.
If only `lpred` is passed it's used for the start and end of the string.
If `rpred` is also passed, it's used for the end of the string.",
);

export function split(string, on) {
let parts = arraylist.new();
let chars = chars(string);
let len = array.length(chars);
let prev = 0;

for (let i = 0; i <= len; i = i + 1) {
if (i == len || chars[i] == on) {
arraylist.push(parts, from_chars(array.slice(chars, prev, i)));
prev = i + 1;
continue;
}
}

return arraylist.to_array(parts);
}

doc:add(
"function",
"split(string, on)",
"Break a string into an array of parts, where each part is separated by `on`.",
);

0 comments on commit fef874e

Please sign in to comment.