summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2025-11-02 18:08:16 -0800
committerKai Stevenson <kai@kaistevenson.com>2025-11-02 18:09:14 -0800
commite9f3c782bc10d4c5c44faf768aa60cd6bcc66574 (patch)
treecb4e447a5ce5deffe989a65ff774e90f0e8ad518 /src
parentf53622d63c74a1e2dd0397f4a26f31aa72dea60b (diff)
refactor
Diffstat (limited to 'src')
-rw-r--r--src/lang/builtin/index.ts34
-rw-r--r--src/lang/core/common.ts (renamed from src/lib/core/common.ts)0
-rw-r--r--src/lang/core/eval.ts42
-rw-r--r--src/lang/core/index.ts (renamed from src/lib/core/index.ts)0
-rw-r--r--src/lang/core/lexer.ts (renamed from src/lib/core/lexer.ts)0
-rw-r--r--src/lang/core/parser.ts (renamed from src/lib/core/parser.ts)0
-rw-r--r--src/lang/index.ts (renamed from src/lib/index.ts)0
-rw-r--r--src/lang/util/index.ts3
-rw-r--r--src/lang/util/number.ts34
-rw-r--r--src/lang/util/string.ts17
-rw-r--r--src/lang/util/utils.ts8
-rw-r--r--src/lib/core/eval.ts126
12 files changed, 138 insertions, 126 deletions
diff --git a/src/lang/builtin/index.ts b/src/lang/builtin/index.ts
new file mode 100644
index 0000000..373f54a
--- /dev/null
+++ b/src/lang/builtin/index.ts
@@ -0,0 +1,34 @@
+import {
+ AddNumbers,
+ AddStrings,
+ Multiply,
+ ToString,
+ UnarrayIfOnlyHead,
+} from "../util";
+
+export type FnError<T extends string> = `Function execution error: ${T}`;
+
+export type BUILTIN_Arr<Args extends readonly any[]> = Args;
+
+export type BUILTIN_ToString<Args extends readonly any[]> = ToString<
+ UnarrayIfOnlyHead<{
+ [Idx in keyof Args]: ToString<Args[Idx]>;
+ }>
+>;
+
+export type BUILTIN_Add<Args extends readonly any[]> =
+ Args extends readonly string[]
+ ? AddStrings<Args>
+ : Args extends readonly number[]
+ ? AddNumbers<Args>
+ : FnError<`Cannot add operands ${ToString<Args>}`>;
+
+export type BUILTIN_Mul<Args extends readonly any[]> = Args extends [
+ infer A,
+ infer B,
+ infer C
+]
+ ? FnError<`Can only multiply [number, number], but got ${ToString<Args>}`>
+ : Args extends [infer M extends number, infer N extends number]
+ ? Multiply<M, N>
+ : FnError<`Can only multiply [number, number], but got ${ToString<Args>}`>;
diff --git a/src/lib/core/common.ts b/src/lang/core/common.ts
index c1a1dc3..c1a1dc3 100644
--- a/src/lib/core/common.ts
+++ b/src/lang/core/common.ts
diff --git a/src/lang/core/eval.ts b/src/lang/core/eval.ts
new file mode 100644
index 0000000..6a25a6c
--- /dev/null
+++ b/src/lang/core/eval.ts
@@ -0,0 +1,42 @@
+import {
+ BUILTIN_Add,
+ BUILTIN_Arr,
+ BUILTIN_Mul,
+ BUILTIN_ToString,
+} from "../builtin";
+import { ASTNode, NodeType } from "./common";
+import { Lex } from "./lexer";
+import { Parse } from "./parser";
+
+export type SENTINEL_NO_BUILTIN = "__NO_BUILTIN__";
+export type MapBuiltins<Node extends ASTNode> =
+ Node["children"] extends infer Children extends readonly ASTNode[]
+ ? {
+ [Idx in keyof Children]: Children[Idx] extends ASTNode
+ ? Evaluate<Children[Idx]>
+ : never;
+ } extends infer Args extends readonly any[]
+ ? Node["name"] extends "tostring"
+ ? BUILTIN_ToString<Args>
+ : Node["name"] extends "arr"
+ ? BUILTIN_Arr<Args>
+ : Node["name"] extends "add"
+ ? BUILTIN_Add<Args>
+ : Node["name"] extends "mul"
+ ? BUILTIN_Mul<Args>
+ : SENTINEL_NO_BUILTIN
+ : never
+ : never;
+
+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.EXT
+ ? MapBuiltins<Node>
+ : EvalError<`Unhandled node type ${Node["type"]}`>;
+
+const input = `` 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/index.ts b/src/lang/core/index.ts
index e69de29..e69de29 100644
--- a/src/lib/core/index.ts
+++ b/src/lang/core/index.ts
diff --git a/src/lib/core/lexer.ts b/src/lang/core/lexer.ts
index 33a408a..33a408a 100644
--- a/src/lib/core/lexer.ts
+++ b/src/lang/core/lexer.ts
diff --git a/src/lib/core/parser.ts b/src/lang/core/parser.ts
index 79218e9..79218e9 100644
--- a/src/lib/core/parser.ts
+++ b/src/lang/core/parser.ts
diff --git a/src/lib/index.ts b/src/lang/index.ts
index 8d119de..8d119de 100644
--- a/src/lib/index.ts
+++ b/src/lang/index.ts
diff --git a/src/lang/util/index.ts b/src/lang/util/index.ts
new file mode 100644
index 0000000..00a3e54
--- /dev/null
+++ b/src/lang/util/index.ts
@@ -0,0 +1,3 @@
+export * from "./number";
+export * from "./utils";
+export * from "./string";
diff --git a/src/lang/util/number.ts b/src/lang/util/number.ts
new file mode 100644
index 0000000..132994b
--- /dev/null
+++ b/src/lang/util/number.ts
@@ -0,0 +1,34 @@
+export type NumberToArray<
+ Number extends number,
+ Carry extends readonly any[] = []
+> = Number extends Carry["length"]
+ ? Carry
+ : NumberToArray<Number, [...Carry, any]>;
+
+export type NumbersToArray<
+ Numbers extends readonly number[],
+ Carry extends readonly any[] = []
+> = Numbers extends [
+ infer Head extends number,
+ ...infer Tail extends readonly number[]
+]
+ ? NumbersToArray<Tail, [...Carry, ...NumberToArray<Head>]>
+ : Carry;
+
+export type AddNumbers<Numbers extends readonly number[]> =
+ NumbersToArray<Numbers> extends infer T extends readonly any[]
+ ? T["length"]
+ : never;
+
+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<N, Tail, AddNumbers<[Carry, N]>>
+ : Carry;
+
+export type Multiply<M extends number, N extends number> = MultiplyInner<
+ M,
+ NumberToArray<N>
+>;
diff --git a/src/lang/util/string.ts b/src/lang/util/string.ts
new file mode 100644
index 0000000..5772f40
--- /dev/null
+++ b/src/lang/util/string.ts
@@ -0,0 +1,17 @@
+export type AddStrings<
+ Strings extends readonly string[],
+ Carry extends string = ""
+> = Strings extends [infer Head extends string, ...infer Tail extends string[]]
+ ? AddStrings<Tail, `${Carry}${Head}`>
+ : Carry;
+
+export type ToString<T, Carry extends string = ""> = T extends string | number
+ ? `${T}`
+ : T extends readonly any[]
+ ? T extends readonly [infer Head, ...infer Tail]
+ ? `${ToString<
+ Tail,
+ `${Carry extends "" ? "" : `${Carry}, `}${ToString<Head>}`
+ >}`
+ : `[${Carry}]`
+ : never;
diff --git a/src/lang/util/utils.ts b/src/lang/util/utils.ts
new file mode 100644
index 0000000..ac36ca1
--- /dev/null
+++ b/src/lang/util/utils.ts
@@ -0,0 +1,8 @@
+export type UnarrayIfOnlyHead<T extends readonly any[]> = T extends [
+ infer Head,
+ infer Next
+]
+ ? T
+ : T extends [infer Head]
+ ? Head
+ : T;
diff --git a/src/lib/core/eval.ts b/src/lib/core/eval.ts
deleted file mode 100644
index 59cda1d..0000000
--- a/src/lib/core/eval.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-import { ASTNode, NodeType } from "./common";
-import { Lex } from "./lexer";
-import { Parse } from "./parser";
-
-export type FnError<T extends string> = `Function execution error: ${T}`;
-
-export type ToStringInner<T, Carry extends string = ""> = T extends
- | string
- | number
- ? `${T}`
- : T extends readonly any[]
- ? T extends readonly [infer Head, ...infer Tail]
- ? `${ToStringInner<
- Tail,
- `${Carry extends "" ? "" : `${Carry}, `}${ToStringInner<Head>}`
- >}`
- : `[${Carry}]`
- : FnError<`Can't stringify`>;
-
-export type UnarrayIfOnlyHead<T extends readonly any[]> = 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<Number, [...Carry, any]>;
-
-export type NumbersToArray<
- Numbers extends readonly number[],
- Carry extends readonly any[] = []
-> = Numbers extends [
- infer Head extends number,
- ...infer Tail extends readonly number[]
-]
- ? NumbersToArray<Tail, [...Carry, ...NumberToArray<Head>]>
- : Carry;
-
-export type AddNumbers<Numbers extends readonly number[]> =
- NumbersToArray<Numbers> 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<Tail, `${Carry}${Head}`>
- : 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<N, Tail, AddNumbers<[Carry, N]>>
- : Carry;
-export type Multiply<M extends number, N extends number> = MultiplyInner<
- M,
- NumberToArray<N>
->;
-
-export type BUILTIN_Arr<Args extends readonly any[]> = Args;
-
-export type BUILTIN_ToString<Args extends readonly any[]> = ToStringInner<
- UnarrayIfOnlyHead<{
- [Idx in keyof Args]: ToStringInner<Args[Idx]>;
- }>
->;
-
-export type BUILTIN_Add<Args extends readonly any[]> =
- Args extends readonly string[]
- ? AddStrings<Args>
- : Args extends readonly number[]
- ? AddNumbers<Args>
- : FnError<`Cannot add operands ${ToStringInner<Args>}`>;
-
-export type BUILTIN_Mul<Args extends readonly any[]> = Args extends [
- infer A,
- infer B,
- infer C
-]
- ? FnError<`Can only multiply [number, number], but got ${ToStringInner<Args>}`>
- : Args extends [infer M extends number, infer N extends number]
- ? Multiply<M, N>
- : FnError<`Can only multiply [number, number], but got ${ToStringInner<Args>}`>;
-
-export type SENTINEL_NO_BUILTIN = "__NO_BUILTIN__";
-export type MapBuiltins<Node extends ASTNode> =
- Node["children"] extends infer Children extends readonly ASTNode[]
- ? {
- [Idx in keyof Children]: Children[Idx] extends ASTNode
- ? Evaluate<Children[Idx]>
- : never;
- } extends infer Args extends readonly any[]
- ? Node["name"] extends "tostring"
- ? BUILTIN_ToString<Args>
- : Node["name"] extends "arr"
- ? BUILTIN_Arr<Args>
- : Node["name"] extends "add"
- ? BUILTIN_Add<Args>
- : Node["name"] extends "mul"
- ? BUILTIN_Mul<Args>
- : SENTINEL_NO_BUILTIN
- : never
- : never;
-
-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.EXT
- ? MapBuiltins<Node>
- : EvalError<`Unhandled node type ${Node["type"]}`>;
-
-const input = `` 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>;