summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/core/common.ts7
-rw-r--r--src/lib/core/eval.ts43
2 files changed, 31 insertions, 19 deletions
diff --git a/src/lib/core/common.ts b/src/lib/core/common.ts
index b5f494e..8cff899 100644
--- a/src/lib/core/common.ts
+++ b/src/lib/core/common.ts
@@ -38,7 +38,12 @@ export type ASTNode<
Type extends NodeType = NodeType,
Name extends string = string,
Value extends any = any,
- Children extends ASTNode[] = ASTNode<NodeType, string, any, any>[]
+ Children extends readonly ASTNode[] = readonly ASTNode<
+ NodeType,
+ string,
+ any,
+ any
+ >[]
> = {
type: Type;
name: Name;
diff --git a/src/lib/core/eval.ts b/src/lib/core/eval.ts
index 7c2c91b..10cc23c 100644
--- a/src/lib/core/eval.ts
+++ b/src/lib/core/eval.ts
@@ -9,7 +9,7 @@ export type ToStringInner<T, Carry extends string = ""> = T extends
| number
? `${T}`
: T extends readonly any[]
- ? T extends [infer Head, ...infer Tail]
+ ? T extends readonly [infer Head, ...infer Tail]
? `${ToStringInner<
Tail,
`${Carry extends "" ? "" : `${Carry}, `}${ToStringInner<Head>}`
@@ -17,11 +17,22 @@ export type ToStringInner<T, Carry extends string = ""> = T extends
: `[${Carry}]`
: FnError<`Can't stringify`>;
-export type BUILTIN_ToString<Args extends readonly ASTNode[]> = {
- [Idx in Exclude<keyof Args, keyof any[]>]: Args[Idx] extends ASTNode
- ? ToStringInner<Evaluate<Args[Idx]>>
- : never;
-};
+export type UnarrayIfOnlyHead<T extends readonly any[]> = T extends [
+ infer Head,
+ infer Next
+]
+ ? T
+ : T extends [infer Head]
+ ? Head
+ : T;
+
+export type BUILTIN_ToString<Args extends readonly ASTNode[]> = ToStringInner<
+ UnarrayIfOnlyHead<{
+ [Idx in keyof Args]: Args[Idx] extends ASTNode
+ ? ToStringInner<Evaluate<Args[Idx]>>
+ : never;
+ }>
+>;
// export type BUILTIN_Print<Args extends readonly ASTNode[]>
export type SENTINEL_NO_BUILTIN = "__NO_BUILTIN__";
@@ -34,22 +45,18 @@ export type EvalError<T extends string> = `Eval error: ${T}`;
export type Evaluate<Node extends ASTNode> = Node["type"] extends NodeType.INT
? Node["value"]
: Node["type"] extends NodeType.ROOT
- ? {
- // FIXME render as array??
- [Idx in Exclude<
- keyof Node["children"],
- keyof any[]
- >]: Node["children"][Idx] extends ASTNode
- ? Evaluate<Node["children"][Idx]>
- : never;
- // indexing for now to remove object syntax
- // pls fix
- }[Exclude<keyof Node["children"], keyof any[]>]
+ ? Node["children"] extends infer Children extends readonly ASTNode[]
+ ? UnarrayIfOnlyHead<{
+ [Idx in keyof Children]: Children[Idx] extends ASTNode
+ ? Evaluate<Children[Idx]>
+ : never;
+ }>
+ : EvalError<`Unexpected error parsing children of ${Node["type"]}`>
: Node["type"] extends NodeType.EXT
? MapBuiltins<Node>
: EvalError<`Unhandled node type ${Node["type"]}`>;
-const input = `tostring(5, 3)` as const;
+const input = `tostring(5, 2)` as const;
const lex_result = null as unknown as Lex<typeof input>;
const parse_result = null as unknown as Parse<typeof lex_result>;
const eval_result = null as unknown as Evaluate<typeof parse_result>;