summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lang/js-lang/builtin/builtin.ts14
-rw-r--r--src/lang/js-lang/builtin/sbuiltin.ts46
-rw-r--r--src/lang/ts-lang/builtin/sbuiltin.ts57
-rw-r--r--src/lang/ts-lang/core/eval.ts6
-rw-r--r--src/lang/ts-lang/core/lexer.ts2
-rw-r--r--src/lang/ts-lang/util/string.ts5
6 files changed, 125 insertions, 5 deletions
diff --git a/src/lang/js-lang/builtin/builtin.ts b/src/lang/js-lang/builtin/builtin.ts
index bc40794..a984ca8 100644
--- a/src/lang/js-lang/builtin/builtin.ts
+++ b/src/lang/js-lang/builtin/builtin.ts
@@ -2,9 +2,17 @@ type BUILTIN = (args: any[]) => any;
export const V_BUILTIN_Arr: BUILTIN = (args) => args;
-// FIXME actually implement this properly
-export const V_BUILTIN_ToString: BUILTIN = (args) =>
- args.length === 1 ? JSON.stringify(args[0]) : JSON.stringify(args);
+const toStringInner = (o: any): string => {
+ if (Array.isArray(o)) {
+ return `[${o.map(toStringInner).join(", ")}]`;
+ }
+
+ return o.toString();
+};
+
+export const V_BUILTIN_ToString: BUILTIN = (args) => {
+ return args.length === 1 ? toStringInner(args[0]) : toStringInner(args);
+};
export const V_BUILTIN_Add: BUILTIN = (args) => {
if (args.every((arg) => ["string", "number"].includes(typeof arg))) {
diff --git a/src/lang/js-lang/builtin/sbuiltin.ts b/src/lang/js-lang/builtin/sbuiltin.ts
index 013854c..60cd117 100644
--- a/src/lang/js-lang/builtin/sbuiltin.ts
+++ b/src/lang/js-lang/builtin/sbuiltin.ts
@@ -40,6 +40,50 @@ export const V_SBUILTIN_Map: SBUILTIN = (node, frame) => {
return values.map((v, i) => callFn(fn, [v, i], frame));
};
+export const V_SBUILTIN_Reduce: SBUILTIN = (node, frame) => {
+ const children = getEvaluatedChildren(node, frame);
+ const fn = children[1] as FnPrim | undefined;
+ const acc = children[2];
+
+ if (!fn?.fn) {
+ throw new Error(
+ `Invalid params for reduce: ${JSON.stringify(children, undefined, 2)}`
+ );
+ }
+
+ const values = children[0];
+
+ if (!Array.isArray(values)) {
+ // add to ts
+ throw new Error(`Can't reduce non-array value: ${values}`);
+ }
+
+ return values.reduce(
+ (acc, cur, idx) => callFn(fn, [acc, cur, idx], frame),
+ acc
+ );
+};
+
+export const V_SBUILTIN_Filter: SBUILTIN = (node, frame) => {
+ const children = getEvaluatedChildren(node, frame);
+ const fn = children[1] as FnPrim | undefined;
+
+ if (!fn?.fn) {
+ throw new Error(
+ `Invalid params for filter: ${JSON.stringify(children, undefined, 2)}`
+ );
+ }
+
+ const values = children[0];
+
+ if (!Array.isArray(values)) {
+ // add to ts
+ throw new Error(`Can't filter non-array value: ${values}`);
+ }
+
+ return values.filter((v, idx) => callFn(fn, [v, idx], frame) === true);
+};
+
export const V_SBUILTIN_IfElse: SBUILTIN = (node, frame) => {
const children = node.children;
@@ -59,5 +103,7 @@ export const V_SBUILTIN_IfElse: SBUILTIN = (node, frame) => {
export const nameToSBUILTIN: Record<string, SBUILTIN> = {
call: V_SBUILTIN_Call,
map: V_SBUILTIN_Map,
+ reduce: V_SBUILTIN_Reduce,
+ filter: V_SBUILTIN_Filter,
"?": V_SBUILTIN_IfElse,
};
diff --git a/src/lang/ts-lang/builtin/sbuiltin.ts b/src/lang/ts-lang/builtin/sbuiltin.ts
index c92fd6a..f089aea 100644
--- a/src/lang/ts-lang/builtin/sbuiltin.ts
+++ b/src/lang/ts-lang/builtin/sbuiltin.ts
@@ -42,6 +42,63 @@ export type SBUILTIN_Map<
GetEvaluatedChildren<Node, Frame, Callstack>
>}`>;
+type Reduce<
+ Arr extends readonly any[],
+ Fn extends FnPrim,
+ Acc,
+ IdxLen extends readonly any[] = readonly []
+> = Arr extends [infer Head, ...infer Tail]
+ ? Reduce<
+ Tail,
+ Fn,
+ CallFn<Fn, [Acc, Head, IdxLen["length"]]>,
+ [...IdxLen, any]
+ >
+ : Acc;
+
+export type SBUILTIN_Reduce<
+ Node extends ASTNode,
+ Frame extends StackFrame,
+ Callstack extends readonly string[]
+> = GetEvaluatedChildren<Node, Frame, Callstack> extends [
+ infer Arr extends readonly any[],
+ infer Fn extends FnPrim,
+ infer Acc
+]
+ ? Reduce<Arr, Fn, Acc>
+ : EvalError<`Invalid params for reduce: ${ToString<
+ GetEvaluatedChildren<Node, Frame, Callstack>
+ >}`>;
+
+type Filter<
+ Arr extends readonly any[],
+ Fn extends FnPrim,
+ Collected extends readonly any[] = [],
+ IdxLen extends readonly any[] = readonly []
+> = Arr extends [infer Head, ...infer Tail]
+ ? Filter<
+ Tail,
+ Fn,
+ CallFn<Fn, [Head, IdxLen["length"]]> extends true
+ ? [...Collected, Head]
+ : Collected,
+ [...IdxLen, any]
+ >
+ : Collected;
+
+export type SBUILTIN_Filter<
+ Node extends ASTNode,
+ Frame extends StackFrame,
+ Callstack extends readonly string[]
+> = GetEvaluatedChildren<Node, Frame, Callstack> extends [
+ infer Arr extends readonly any[],
+ infer Fn extends FnPrim
+]
+ ? Filter<Arr, Fn>
+ : EvalError<`Invalid params for filter: ${ToString<
+ GetEvaluatedChildren<Node, Frame, Callstack>
+ >}`>;
+
export type SBUILTIN_IfElse<
Node extends ASTNode,
Frame extends StackFrame,
diff --git a/src/lang/ts-lang/core/eval.ts b/src/lang/ts-lang/core/eval.ts
index ebc58e7..b937c2e 100644
--- a/src/lang/ts-lang/core/eval.ts
+++ b/src/lang/ts-lang/core/eval.ts
@@ -6,8 +6,10 @@ import {
BUILTIN_Sub,
BUILTIN_ToString,
SBUILTIN_Call,
+ SBUILTIN_Filter,
SBUILTIN_IfElse,
SBUILTIN_Map,
+ SBUILTIN_Reduce,
} from "../builtin";
import { ToString } from "../util";
import {
@@ -34,6 +36,10 @@ export type MapBuiltins<
? SBUILTIN_Call<Node, Frame, Callstack>
: Node["name"] extends "map"
? SBUILTIN_Map<Node, Frame, Callstack>
+ : Node["name"] extends "reduce"
+ ? SBUILTIN_Reduce<Node, Frame, Callstack>
+ : Node["name"] extends "filter"
+ ? SBUILTIN_Filter<Node, Frame, Callstack>
: Node["name"] extends "?"
? SBUILTIN_IfElse<Node, Frame, Callstack>
: Node["name"] extends "tostring"
diff --git a/src/lang/ts-lang/core/lexer.ts b/src/lang/ts-lang/core/lexer.ts
index bcd5785..43dc3e5 100644
--- a/src/lang/ts-lang/core/lexer.ts
+++ b/src/lang/ts-lang/core/lexer.ts
@@ -36,7 +36,7 @@ export type IsClose<T> = T extends `${TokenType.CLOSE_PAREN}` ? true : false;
export type ChunkedLex<
Ctx extends LexerCtx,
Depth extends any[] = []
-> = Depth["length"] extends 50
+> = Depth["length"] extends 25
? Ctx & {
endChunk: true;
}
diff --git a/src/lang/ts-lang/util/string.ts b/src/lang/ts-lang/util/string.ts
index 5772f40..ae17c2c 100644
--- a/src/lang/ts-lang/util/string.ts
+++ b/src/lang/ts-lang/util/string.ts
@@ -5,7 +5,10 @@ export type AddStrings<
? AddStrings<Tail, `${Carry}${Head}`>
: Carry;
-export type ToString<T, Carry extends string = ""> = T extends string | number
+export type ToString<T, Carry extends string = ""> = T extends
+ | string
+ | number
+ | boolean
? `${T}`
: T extends readonly any[]
? T extends readonly [infer Head, ...infer Tail]