diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/core/eval.ts | 54 | ||||
| -rw-r--r-- | src/lib/core/parser.ts | 10 |
2 files changed, 61 insertions, 3 deletions
diff --git a/src/lib/core/eval.ts b/src/lib/core/eval.ts index 779bfd9..7c2c91b 100644 --- a/src/lib/core/eval.ts +++ b/src/lib/core/eval.ts @@ -1,7 +1,55 @@ -import { ASTNode } from "./common"; +import { ASTNode, NodeType } from "./common"; import { Lex } from "./lexer"; import { Parse } from "./parser"; -export type Evaluate<Node extends ASTNode> = "Not implemented"; +export type FnError<T extends string> = `Function execution error: ${T}`; -const test_result = null as unknown as Evaluate<Parse<Lex<"print(a)">>>; +export type ToStringInner<T, Carry extends string = ""> = T extends + | string + | number + ? `${T}` + : T extends readonly any[] + ? T extends [infer Head, ...infer Tail] + ? `${ToStringInner< + Tail, + `${Carry extends "" ? "" : `${Carry}, `}${ToStringInner<Head>}` + >}` + : `[${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 BUILTIN_Print<Args extends readonly ASTNode[]> + +export type SENTINEL_NO_BUILTIN = "__NO_BUILTIN__"; +export type MapBuiltins<Node extends ASTNode> = Node["name"] extends "tostring" + ? BUILTIN_ToString<Node["children"]> + : SENTINEL_NO_BUILTIN; + +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["type"] extends NodeType.EXT + ? MapBuiltins<Node> + : EvalError<`Unhandled node type ${Node["type"]}`>; + +const input = `tostring(5, 3)` 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>; diff --git a/src/lib/core/parser.ts b/src/lib/core/parser.ts index d608eca..27133b2 100644 --- a/src/lib/core/parser.ts +++ b/src/lib/core/parser.ts @@ -199,6 +199,16 @@ export type _Parse<Ctx extends ParserCtx> = Ctx["remainingTokens"] extends [ }> : Ctx & Error<`Expected nextToken to be a name or close paren at ${Head["type"]}`> + : Ctx["lastToken"] extends Token + ? // case where we ended with a name + _Parse<{ + lastToken: null; + remainingTokens: []; + stack: PushChildToLastElementOfStack< + Ctx["stack"], + ResolveNodeFromToken<Ctx["lastToken"]> + >; + }> : Ctx["stack"][0]; export type Parse<Raw extends readonly Token[]> = _Parse<{ |
