From 8b610f2bcfc223333254ce9679730c42dce6d26e Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Mon, 3 Nov 2025 23:41:31 -0800 Subject: add createFn --- src/js-lang/builtin/builtin.ts | 39 ------------ src/js-lang/builtin/index.ts | 2 - src/js-lang/builtin/sbuiltin.ts | 46 -------------- src/js-lang/core/eval.ts | 83 ------------------------- src/js-lang/core/index.ts | 3 - src/js-lang/core/lexer.ts | 46 -------------- src/js-lang/core/parser.ts | 132 ---------------------------------------- src/js-lang/index.ts | 1 - 8 files changed, 352 deletions(-) delete mode 100644 src/js-lang/builtin/builtin.ts delete mode 100644 src/js-lang/builtin/index.ts delete mode 100644 src/js-lang/builtin/sbuiltin.ts delete mode 100644 src/js-lang/core/eval.ts delete mode 100644 src/js-lang/core/index.ts delete mode 100644 src/js-lang/core/lexer.ts delete mode 100644 src/js-lang/core/parser.ts delete mode 100644 src/js-lang/index.ts (limited to 'src/js-lang') diff --git a/src/js-lang/builtin/builtin.ts b/src/js-lang/builtin/builtin.ts deleted file mode 100644 index dde91b6..0000000 --- a/src/js-lang/builtin/builtin.ts +++ /dev/null @@ -1,39 +0,0 @@ -type BUILTIN = (args: any[]) => any; - -export const V_BUILTIN_Arr: BUILTIN = (args) => args; - -// FIXME actually implement this properly -export const V_BUILTIN_ToString: BUILTIN = (args) => - args.length === 1 ? JSON.stringify(args[0]) : JSON.stringify(args); - -export const V_BUILTIN_Add: BUILTIN = (args) => { - if (args.every((arg) => ["string", "number"].includes(typeof arg))) { - return args.reduce( - (acc, cur) => acc + cur, - typeof args[0] === "string" ? "" : 0 - ); - } - - throw new Error(`Cannot add operands ${JSON.stringify(args, undefined, 2)}`); -}; - -export const V_BUILTIN_Mul: BUILTIN = (args) => { - if (args.every((arg) => typeof arg === "number") && args.length === 2) { - return args.reduce((acc, cur) => acc * cur, 1); - } - - throw new Error( - `Can only multiply [number, number], but got ${JSON.stringify( - args, - undefined, - 2 - )}` - ); -}; - -export const nameToBUILTIN: Record = { - arr: V_BUILTIN_Arr, - tostring: V_BUILTIN_ToString, - add: V_BUILTIN_Add, - mul: V_BUILTIN_Mul, -}; diff --git a/src/js-lang/builtin/index.ts b/src/js-lang/builtin/index.ts deleted file mode 100644 index 00e77f7..0000000 --- a/src/js-lang/builtin/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./builtin"; -export * from "./sbuiltin"; diff --git a/src/js-lang/builtin/sbuiltin.ts b/src/js-lang/builtin/sbuiltin.ts deleted file mode 100644 index 44c969d..0000000 --- a/src/js-lang/builtin/sbuiltin.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { callFn, getEvaluatedChildren } from "../core/eval"; -import { ASTNode, FnPrim, StackFrame } from "../../ts-lang"; - -type SBUILTIN = (node: ASTNode, frame: StackFrame) => any; - -export const V_SBUITLIN_Call: SBUILTIN = (node, frame) => { - const children = getEvaluatedChildren(node, frame); - const fn = children[0] as FnPrim | undefined; - - if (!fn?.fn) { - throw new Error( - `Invalid params for function call: ${JSON.stringify( - children, - undefined, - 2 - )}` - ); - } - - return callFn(fn, children.slice(1), frame); -}; - -export const V_SBUILTIN_Map: SBUILTIN = (node, frame) => { - const children = getEvaluatedChildren(node, frame); - const fn = children[1] as FnPrim | undefined; - - if (!fn?.fn) { - throw new Error( - `Invalid params for map: ${JSON.stringify(children, undefined, 2)}` - ); - } - - const values = children[0]; - - if (!Array.isArray(values)) { - // add to ts - throw new Error(`Can't map non-array value: ${values}`); - } - - return values.map((v, i) => callFn(fn, [v, i], frame)); -}; - -export const nameToSBUILTIN: Record = { - call: V_SBUITLIN_Call, - map: V_SBUILTIN_Map, -}; diff --git a/src/js-lang/core/eval.ts b/src/js-lang/core/eval.ts deleted file mode 100644 index 60a2059..0000000 --- a/src/js-lang/core/eval.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { - ASTNode, - StackFrame, - Evaluate, - EmptyStackFrame, - NodeType, - FnPrim, - SENTINEL_NO_BUILTIN, -} from "../../ts-lang"; -import { nameToBUILTIN, nameToSBUILTIN, V_SBUILTIN_Map } from "../builtin"; - -const V_SENTINEL_NO_BUILTIN: SENTINEL_NO_BUILTIN = "__NO_BUILTIN__"; - -const mapBuiltins = (node: ASTNode, frame: StackFrame): any => { - if (node.name in nameToSBUILTIN) { - return nameToSBUILTIN[node.name](node, frame); - } - if (node.name in nameToBUILTIN) { - return nameToBUILTIN[node.name](getEvaluatedChildren(node, frame)); - } - - return V_SENTINEL_NO_BUILTIN; -}; - -const findInStack = (frame: StackFrame, nameToFind: string) => { - if (nameToFind in frame.bindings) { - return frame.bindings[nameToFind]; - } - - if (!frame.parent) { - throw new Error(`Can't find name ${nameToFind} on the stack`); - } - - return findInStack(frame.parent, nameToFind); -}; - -const handleFn = (node: ASTNode): FnPrim => { - const fn = node.children[node.children.length - 1]; - - return { - args: node.children.slice(0, node.children.length - 1), - fn, - }; -}; - -const mapZip = (args: ASTNode[], values: any[]) => - Object.fromEntries(args.map(({ name }, i) => [name, values[i]])); - -export const callFn = (fn: FnPrim, values: any[], frame: StackFrame) => - _evaluate(fn.fn, { - bindings: mapZip(fn.args as ASTNode[], values), - parent: frame, - }); - -export const _evaluate = (node: ASTNode, frame: StackFrame) => { - if (node.type === NodeType.INT) { - return node.value; - } - - if (node.type === NodeType.EXT) { - if (node.name === "fn") { - return handleFn(node); - } - - const builtinResult = mapBuiltins(node, frame); - if (builtinResult !== V_SENTINEL_NO_BUILTIN) { - return builtinResult; - } - - return findInStack(frame, node.name); - } - - throw new Error(`Unhandled node type ${node.type}`); -}; - -export const getEvaluatedChildren = (node: ASTNode, frame: StackFrame) => - node.children.map((child) => _evaluate(child, frame)); - -export const emptyStackFrame: EmptyStackFrame = { bindings: {}, parent: null }; - -export const evaluate = ( - node: Node -): Evaluate => _evaluate(node, emptyStackFrame) as Evaluate; diff --git a/src/js-lang/core/index.ts b/src/js-lang/core/index.ts deleted file mode 100644 index 22ac2d2..0000000 --- a/src/js-lang/core/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./eval"; -export * from "./parser"; -export * from "./lexer"; diff --git a/src/js-lang/core/lexer.ts b/src/js-lang/core/lexer.ts deleted file mode 100644 index 95e0e19..0000000 --- a/src/js-lang/core/lexer.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { TokenType, Lex, Token } from "../../ts-lang"; - -const WHITESPACE_TOKENS = [ - TokenType.SPACE, - TokenType.COMMA, - TokenType.SEMICOLON, -] as string[]; - -export const lex = (raw: Raw): Lex => { - let _raw: string = raw; - let nameCollection = ""; - const tokens: Token[] = []; - - while (_raw) { - const head = _raw[0]; - _raw = _raw.slice(1); - - const processNameCollection = () => { - if (nameCollection) { - tokens.push({ type: TokenType.NAME, name: nameCollection }); - nameCollection = ""; - } - }; - - if (WHITESPACE_TOKENS.includes(head)) { - processNameCollection(); - continue; - } - - if (head === TokenType.OPEN_PAREN) { - processNameCollection(); - tokens.push({ type: TokenType.OPEN_PAREN, name: "" }); - continue; - } - - if (head === TokenType.CLOSE_PAREN) { - processNameCollection(); - tokens.push({ type: TokenType.CLOSE_PAREN, name: "" }); - continue; - } - - nameCollection += head; - } - - return tokens as Lex; -}; diff --git a/src/js-lang/core/parser.ts b/src/js-lang/core/parser.ts deleted file mode 100644 index f193d6a..0000000 --- a/src/js-lang/core/parser.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { Token, Parse, TokenType, ASTNode, NodeType } from "../../ts-lang"; -import { lex } from "./lexer"; - -const resolveNodeFromToken = (token: Token): ASTNode => { - // FIXME not correct - if (!isNaN(Number(token.name))) { - return { - type: NodeType.INT, - name: "", - value: Number(token.name), - children: [], - }; - } - if (token.name[0] === '"' && token.name[token.name.length - 1] === '"') { - return { - type: NodeType.INT, - name: "", - value: token.name.slice(1, token.name.length - 1), - children: [], - }; - } - return { - type: NodeType.EXT, - name: token.name, - value: null, - children: [], - }; -}; - -const _parse = ({ - remainingTokens, - lastToken, - stack, -}: { - remainingTokens: Token[]; - lastToken: Token | null; - stack: ASTNode[]; -}): ASTNode | null => { - const head = remainingTokens.shift(); - if (!head) { - if (lastToken) { - (stack[stack.length - 1].children as ASTNode[]).push( - resolveNodeFromToken(lastToken) - ); - - return _parse({ - lastToken: null, - remainingTokens: [], - stack, - }); - } - - return stack[0] ?? null; - } - - if (lastToken) { - if (head.type === TokenType.NAME) { - (stack[stack.length - 1].children as ASTNode[]).push( - resolveNodeFromToken(lastToken) - ); - return _parse({ - lastToken: head, - remainingTokens, - stack, - }); - } - - if (head.type === TokenType.CLOSE_PAREN) { - const top = stack.pop()!; - (top.children as ASTNode[]).push(resolveNodeFromToken(lastToken)); - (stack[stack.length - 1].children as ASTNode[]).push(top); - - return _parse({ - lastToken: null, - remainingTokens, - stack, - }); - } - - if (head.type === TokenType.OPEN_PAREN) { - return _parse({ - lastToken: null, - remainingTokens, - stack: [...stack, resolveNodeFromToken(lastToken)], - }); - } - - throw new Error( - `${JSON.stringify({ - lastToken, - remainingTokens, - stack, - })} Was not expecting ${head.type}` - ); - } - - if (head.type === TokenType.NAME) { - return _parse({ - lastToken: head, - remainingTokens, - stack, - }); - } - - if (head.type === TokenType.CLOSE_PAREN) { - const top = stack.pop()!; - (stack[stack.length - 1].children as ASTNode[]).push(top); - - return _parse({ - lastToken: null, - remainingTokens, - stack, - }); - } - - throw new Error( - `${JSON.stringify({ - lastToken, - remainingTokens, - stack, - })} Expected nextToken to be a name or close paren at ${head.type}` - ); -}; - -export const parse = ( - raw: Raw -): Parse => - _parse({ - remainingTokens: raw as unknown as Token[], - lastToken: null, - stack: [{ type: NodeType.EXT, name: "arr", value: null, children: [] }], - }) as Parse; diff --git a/src/js-lang/index.ts b/src/js-lang/index.ts deleted file mode 100644 index 8d119de..0000000 --- a/src/js-lang/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./core"; -- cgit v1.2.3-70-g09d2