import { ASTNode, NodeType } from "./common"; import { Lex } from "./lexer"; import { Parse } from "./parser"; export type FnError = `Function execution error: ${T}`; export type ToStringInner = T extends | string | number ? `${T}` : T extends readonly any[] ? T extends readonly [infer Head, ...infer Tail] ? `${ToStringInner< Tail, `${Carry extends "" ? "" : `${Carry}, `}${ToStringInner}` >}` : `[${Carry}]` : FnError<`Can't stringify`>; export type UnarrayIfOnlyHead = T extends [ infer Head, infer Next ] ? T : T extends [infer Head] ? Head : T; export type NumberToArray< Number extends number, Carry extends readonly any[] = [] > = Number extends Carry["length"] ? Carry : NumberToArray; export type NumbersToArray< Numbers extends readonly number[], Carry extends readonly any[] = [] > = Numbers extends [ infer Head extends number, ...infer Tail extends readonly number[] ] ? NumbersToArray]> : Carry; export type AddNumbers = NumbersToArray extends infer T extends readonly any[] ? T["length"] : never; export type AddStrings< Strings extends readonly string[], Carry extends string = "" > = Strings extends [infer Head extends string, ...infer Tail extends string[]] ? AddStrings : Carry; export type MultiplyInner< N extends number, MS extends readonly any[], Carry extends number = 0 > = MS extends [infer Head extends number, ...infer Tail extends readonly any[]] ? MultiplyInner> : Carry; export type Multiply = MultiplyInner< M, NumberToArray >; export type BUILTIN_Arr = Args; export type BUILTIN_ToString = ToStringInner< UnarrayIfOnlyHead<{ [Idx in keyof Args]: ToStringInner; }> >; export type BUILTIN_Add = Args extends readonly string[] ? AddStrings : Args extends readonly number[] ? AddNumbers : FnError<`Cannot add operands ${ToStringInner}`>; export type BUILTIN_Mul = Args extends [ infer A, infer B, infer C ] ? FnError<`Can only multiply [number, number], but got ${ToStringInner}`> : Args extends [infer M extends number, infer N extends number] ? Multiply : FnError<`Can only multiply [number, number], but got ${ToStringInner}`>; export type SENTINEL_NO_BUILTIN = "__NO_BUILTIN__"; export type MapBuiltins = Node["children"] extends infer Children extends readonly ASTNode[] ? { [Idx in keyof Children]: Children[Idx] extends ASTNode ? Evaluate : never; } extends infer Args extends readonly any[] ? Node["name"] extends "tostring" ? BUILTIN_ToString : Node["name"] extends "arr" ? BUILTIN_Arr : Node["name"] extends "add" ? BUILTIN_Add : Node["name"] extends "mul" ? BUILTIN_Mul : SENTINEL_NO_BUILTIN : never : never; export type EvalError = `Eval error: ${T}`; export type Evaluate = Node["type"] extends NodeType.INT ? Node["value"] : Node["type"] extends NodeType.EXT ? MapBuiltins : EvalError<`Unhandled node type ${Node["type"]}`>; const input = `` as const; const lex_result = null as unknown as Lex; const parse_result = null as unknown as Parse; const eval_result = null as unknown as Evaluate;