From 56040f3ff85e77311f0c864a89afd63fcf1bdb50 Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Mon, 3 Nov 2025 23:40:02 -0800 Subject: add js-lang, refactor some ts-lang stuff --- src/lang/core/common.ts | 72 -------------------- src/lang/core/eval.ts | 111 ------------------------------- src/lang/core/index.ts | 0 src/lang/core/lexer.ts | 91 ------------------------- src/lang/core/parser.ts | 173 ------------------------------------------------ 5 files changed, 447 deletions(-) delete mode 100644 src/lang/core/common.ts delete mode 100644 src/lang/core/eval.ts delete mode 100644 src/lang/core/index.ts delete mode 100644 src/lang/core/lexer.ts delete mode 100644 src/lang/core/parser.ts (limited to 'src/lang/core') diff --git a/src/lang/core/common.ts b/src/lang/core/common.ts deleted file mode 100644 index 9e3840b..0000000 --- a/src/lang/core/common.ts +++ /dev/null @@ -1,72 +0,0 @@ -export enum TokenType { - OPEN_PAREN = "(", - CLOSE_PAREN = ")", - SPACE = " ", - SEMICOLON = ";", - COMMA = ",", - NAME = "NAME", -} - -export enum TokenSubType { - NA = "NA", - LITERAL = "LITERAL", - REFERENCE = "REFERENCE", -} - -export type Token< - Type extends TokenType = TokenType, - Name extends string = string -> = { - type: Type; - name: Name; -}; - -export type LexerCtx = { - next: string; - nameCollection: string; - tokens: readonly Token[]; -}; - -export enum NodeType { - INT = "INT", - EXT = "EXT", - PARSER_ERROR = "PARSER_ERROR", -} - -export type ASTNode< - Type extends NodeType = NodeType, - Name extends string = string, - Value extends any = any, - Children extends readonly ASTNode[] = readonly ASTNode< - NodeType, - string, - any, - any - >[] -> = { - type: Type; - name: Name; - value: Value; - children: Children; -}; - -export type ParserCtx = { - remainingTokens: readonly Token[]; - lastToken: Token | null; - stack: readonly ASTNode[]; -}; - -export type StackFrame< - Bindings extends Record = Record, - Parent extends StackFrame | null = any -> = { - bindings: Bindings; - parent: Parent; -}; - -export type EmptyStackFrame = StackFrame<{}, null>; - -export type WithPushedBindings< - OldFrame extends StackFrame, - Bindings extends StackFrame["bindings"] -> = StackFrame; diff --git a/src/lang/core/eval.ts b/src/lang/core/eval.ts deleted file mode 100644 index 9181c81..0000000 --- a/src/lang/core/eval.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { - BUILTIN_Add, - BUILTIN_Arr, - BUILTIN_Mul, - BUILTIN_ToString, - SBUILTIN_Call, - SBUILTIN_Map, -} from "../builtin"; -import { ToString } from "../util"; -import { ASTNode, EmptyStackFrame, NodeType, StackFrame } from "./common"; -import { Lex } from "./lexer"; -import { Parse } from "./parser"; - -export type SENTINEL_NO_BUILTIN = "__NO_BUILTIN__"; -export type MapBuiltins< - Node extends ASTNode, - Frame extends StackFrame -> = GetEvaluatedChildren extends infer Args extends readonly any[] - ? Node["name"] extends "call" - ? SBUILTIN_Call - : Node["name"] extends "map" - ? SBUILTIN_Map - : 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; - -export type EvalError = `Eval error: ${T}`; - -export type FindInStack< - Frame extends StackFrame, - NameToFind -> = NameToFind extends keyof Frame["bindings"] - ? Frame["bindings"][NameToFind] - : Frame["parent"] extends null - ? EvalError<`Can't find name "${ToString}" on the stack`> - : FindInStack; - -export type MapOnStack< - Node extends ASTNode, - Frame extends StackFrame -> = FindInStack; - -export type FnPrim< - Args extends readonly ASTNode[] = readonly ASTNode[], - Fn extends ASTNode = ASTNode -> = { args: Args; fn: Fn }; - -export type HandleFn = Node["children"] extends [ - ...infer Args extends ASTNode[], - infer Fn extends ASTNode -] - ? FnPrim - : never; - -export type MapZip< - T extends readonly ASTNode[], - U extends readonly PropertyKey[] -> = { - [Idx in Exclude< - keyof T, - keyof any[] - > as T[Idx] extends infer Node extends ASTNode - ? Node["name"] - : never]: Idx extends keyof U ? U[Idx] : never; -}; - -export type CallFn< - Fn extends FnPrim, - Values extends readonly any[], - Frame extends StackFrame -> = Evaluate, Frame>>; - -export type Evaluate< - Node extends ASTNode, - Frame extends StackFrame = EmptyStackFrame -> = Node["type"] extends NodeType.INT - ? Node["value"] - : Node["type"] extends NodeType.EXT - ? // special builtin - Node["name"] extends "fn" - ? HandleFn - : MapBuiltins extends infer BI - ? BI extends SENTINEL_NO_BUILTIN - ? MapOnStack - : BI - : never - : EvalError<`Unhandled node type ${Node["type"]}`>; - -export type GetEvaluatedChildren< - Node extends ASTNode, - Frame extends StackFrame -> = Node["children"] extends infer Children extends readonly ASTNode[] - ? { - [Idx in keyof Children]: Children[Idx] extends ASTNode - ? Evaluate - : never; - } - : never; - -const input = - `map(arr("hello", "world"), fn(s, i, add(tostring(i), ":", s)))` 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; diff --git a/src/lang/core/index.ts b/src/lang/core/index.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/lang/core/lexer.ts b/src/lang/core/lexer.ts deleted file mode 100644 index 567964f..0000000 --- a/src/lang/core/lexer.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { LexerCtx, Token, TokenSubType, TokenType } from "./common"; - -export type BreakingToken = - | TokenType.OPEN_PAREN - | TokenType.CLOSE_PAREN - | TokenType.COMMA - | TokenType.SEMICOLON - | TokenType.SPACE; - -export type IsWhitespace = T extends `${TokenType.SPACE}` - ? true - : T extends `${TokenType.COMMA}` - ? true - : T extends `${TokenType.SEMICOLON}` - ? true - : false; - -export type ProcessNameCollection< - Ctx extends LexerCtx, - Tail extends string, - _Token extends Token | null -> = { - next: Tail; - nameCollection: ""; - tokens: _Token extends null - ? [ - ...Ctx["tokens"], - ...(Ctx["nameCollection"] extends "" - ? [] - : [Token]) - ] - : [ - ...Ctx["tokens"], - ...(Ctx["nameCollection"] extends "" - ? [_Token] - : [Token, _Token]) - ]; -}; - -export type IsOpen = T extends `${TokenType.OPEN_PAREN}` ? true : false; -export type IsClose = T extends `${TokenType.CLOSE_PAREN}` ? true : false; - -export type ChunkedLex< - Ctx extends LexerCtx, - Depth extends any[] = [] -> = Depth["length"] extends 50 - ? Ctx & { - endChunk: true; - } - : Ctx["next"] extends `${infer Head}${infer Tail}` - ? IsWhitespace extends true - ? ChunkedLex, [0, ...Depth]> - : IsOpen extends true - ? ChunkedLex< - ProcessNameCollection>, - [0, ...Depth] - > - : IsClose extends true - ? ChunkedLex< - ProcessNameCollection>, - [0, ...Depth] - > - : ChunkedLex< - { - next: Tail; - nameCollection: `${Ctx["nameCollection"]}${Head}`; - tokens: Ctx["tokens"]; - }, - [0, ...Depth] - > - : Ctx; - -export type InnerLex< - Next extends string, - NameCollection extends LexerCtx["nameCollection"] = "", - AccTokens extends Token[] = [] -> = Next extends "" - ? AccTokens - : ChunkedLex<{ - next: Next; - tokens: []; - nameCollection: NameCollection; - }> extends infer U - ? U extends LexerCtx & { endChunk: true } - ? InnerLex - : U extends LexerCtx - ? [...AccTokens, ...U["tokens"]] - : never - : never; - -export type Lex = InnerLex; diff --git a/src/lang/core/parser.ts b/src/lang/core/parser.ts deleted file mode 100644 index 2b481fd..0000000 --- a/src/lang/core/parser.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { - ASTNode, - NodeType, - ParserCtx, - Token, - TokenSubType, - TokenType, -} from "./common"; -import { Lex } from "./lexer"; - -export type Error = ASTNode< - NodeType.PARSER_ERROR, - "Error", - T, - [] ->; - -export type PushChild = { - type: Node["type"]; - value: Node["value"]; - name: Node["name"]; - children: [...Node["children"], Child]; -}; - -export type PushChildToLastElementOfStack< - Stack extends ParserCtx["stack"], - Child extends ASTNode -> = Stack extends [...infer Head, infer Tail extends ASTNode] - ? [...Head, PushChild] - : Stack extends [infer Only extends ASTNode] - ? [PushChild] - : never; - -export type PushChildToSecondLastElementOfStack< - Stack extends ParserCtx["stack"], - Child extends ASTNode -> = Stack extends [ - ...infer Head, - infer Tail extends ASTNode, - infer Final extends ASTNode -] - ? [...Head, PushChild, Final] - : Stack extends [infer Only extends ASTNode, infer Final extends ASTNode] - ? [PushChild, Final] - : never; - -export type GetLastOnStack = Stack extends [ - ...infer Head, - infer Tail extends ASTNode -] - ? Tail - : Stack extends [infer Only extends ASTNode] - ? Only - : never; - -export type StackWithoutLast = Stack extends [ - ...infer Head extends ASTNode[], - infer Tail -] - ? [...Head] - : Stack extends [infer Only extends ASTNode] - ? [] - : never; - -type NULL_SENTINEL = { - NULL: true; -}; - -export type ParseNumberLiteral = - T extends `${infer Inner extends number}` ? Inner : NULL_SENTINEL; - -export type ParseStringLiteral = - T extends `"${infer Inner extends string}"` ? Inner : NULL_SENTINEL; - -export type ResolveNodeFromToken<_Token extends Token> = ParseNumberLiteral< - _Token["name"] -> extends number - ? ASTNode, []> - : ParseStringLiteral<_Token["name"]> extends string - ? ASTNode, []> - : ASTNode; - -export type _Parse = Ctx["remainingTokens"] extends [ - infer Head extends Token, - ...infer Tail extends readonly Token[] -] - ? Ctx["lastToken"] extends Token - ? Head["type"] extends TokenType.NAME - ? // we already have a lastToken - // mutate last element of stack to push lastToken as child - // lastToken = nextToken - // goto start - _Parse<{ - lastToken: Head; - remainingTokens: Tail; - stack: PushChildToLastElementOfStack< - Ctx["stack"], - ResolveNodeFromToken - >; - }> - : //nextToken is openParen or close paren - Head["type"] extends TokenType.CLOSE_PAREN - ? // handle lastToken - // set last element of stack as child of prev element on stack - // pop stack - // [stack[last - 1].children.push(stack.pop) - // goto start - _Parse<{ - lastToken: null; - remainingTokens: Tail; - // first push the last name onto the children of the top - // then push the top onto the children of the next - // then remove the top - stack: StackWithoutLast< - PushChildToSecondLastElementOfStack< - Ctx["stack"], - PushChild< - GetLastOnStack, - ResolveNodeFromToken - > - > - >; - }> - : Head["type"] extends TokenType.OPEN_PAREN - ? // push lastToken onto stack - // goto start - _Parse<{ - lastToken: null; - remainingTokens: Tail; - stack: [...Ctx["stack"], ResolveNodeFromToken]; - }> - : Ctx & Error<`Was not expecting ${Head["type"]}`> - : // expect nextToken to be a name or close paren - Head["type"] extends TokenType.NAME - ? // lastToken = nextToken - // goto start - _Parse<{ - lastToken: Head; - remainingTokens: Tail; - stack: Ctx["stack"]; - }> - : Head["type"] extends TokenType.CLOSE_PAREN - ? _Parse<{ - lastToken: null; - remainingTokens: Tail; - // push the top onto the children of the next - // then remove the top - stack: StackWithoutLast< - PushChildToSecondLastElementOfStack< - Ctx["stack"], - GetLastOnStack - > - >; - }> - : 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["stack"][0]; - -export type Parse = _Parse<{ - lastToken: null; - remainingTokens: Raw; - stack: [ASTNode]; -}>; -- cgit v1.2.3-70-g09d2