diff options
| -rw-r--r-- | src/lang/js-lang/builtin/sbuiltin.ts | 2 | ||||
| -rw-r--r-- | src/lang/js-lang/core/eval.ts | 29 | ||||
| -rw-r--r-- | src/lang/ks-lang/index.ts | 13 | ||||
| -rw-r--r-- | test/test.ts | 10 |
4 files changed, 28 insertions, 26 deletions
diff --git a/src/lang/js-lang/builtin/sbuiltin.ts b/src/lang/js-lang/builtin/sbuiltin.ts index 663c2f9..013854c 100644 --- a/src/lang/js-lang/builtin/sbuiltin.ts +++ b/src/lang/js-lang/builtin/sbuiltin.ts @@ -7,7 +7,7 @@ export const V_SBUILTIN_Call: SBUILTIN = (node, frame) => { const children = getEvaluatedChildren(node, frame); const fn = children[0] as FnPrim | undefined; - if (!fn?.fn) { + if (!fn) { throw new Error( `Invalid params for function call: ${JSON.stringify( children, diff --git a/src/lang/js-lang/core/eval.ts b/src/lang/js-lang/core/eval.ts index 1a9e292..dfbd3ce 100644 --- a/src/lang/js-lang/core/eval.ts +++ b/src/lang/js-lang/core/eval.ts @@ -6,9 +6,8 @@ import { NodeType, FnPrim, SENTINEL_NO_BUILTIN, - NamedFnPrim, } from "../../ts-lang"; -import { nameToBUILTIN, nameToSBUILTIN, V_SBUILTIN_Map } from "../builtin"; +import { nameToBUILTIN, nameToSBUILTIN } from "../builtin"; const V_SENTINEL_NO_BUILTIN: SENTINEL_NO_BUILTIN = "__NO_BUILTIN__"; @@ -35,14 +34,7 @@ const handleBind = (node: ASTNode, frame: StackFrame) => { const inner = _evaluate(node.children[1], frame); if (inner.fn) { - const named: NamedFnPrim<any, any, any, any> = { - args: inner.args, - fn: inner.fn, - name: node.children[0].name, - frame, - }; - - return named; + return [inner, frame, node.children[0]["name"]]; } return inner; @@ -60,18 +52,23 @@ const handleFn = (node: ASTNode): FnPrim => { const mapZip = (args: ASTNode[], values: any[]) => Object.fromEntries(args.map(({ name }, i) => [name, values[i]])); -export const callFn = (fn: FnPrim, values: any[], frame: StackFrame) => { - if ((fn as NamedFnPrim<any, any, any, any>).frame) { - return _evaluate(fn.fn, { +export const callFn = ( + fn: FnPrim | [FnPrim, StackFrame, ASTNode["name"]], + values: any[], + frame: StackFrame +) => { + if (Array.isArray(fn)) { + const [prim, frame, name] = fn; + return _evaluate(prim.fn, { bindings: { - ...mapZip(fn.args as ASTNode[], values), ...frame.bindings, - ...(fn as NamedFnPrim<any, any, any, any>).frame.bindings, + [name]: fn, + ...mapZip(prim.args as ASTNode[], values), }, }); } return _evaluate(fn.fn, { - bindings: { ...mapZip(fn.args as ASTNode[], values), ...frame.bindings }, + bindings: { ...frame.bindings, ...mapZip(fn.args as ASTNode[], values) }, }); }; diff --git a/src/lang/ks-lang/index.ts b/src/lang/ks-lang/index.ts index 772c9c9..633d9b9 100644 --- a/src/lang/ks-lang/index.ts +++ b/src/lang/ks-lang/index.ts @@ -8,6 +8,7 @@ import { CallFn, EmptyStackFrame, ASTNode, + StackFrame, } from "../ts-lang"; export type TransformArgs<Args extends readonly ASTNode[]> = { @@ -40,13 +41,17 @@ export const createFn = : EvalError<`Program's args do not extend args constraint`> : EvalError<"Cannot create a function from a program that does not eval to a function"> : never => { - const [programFn] = evaluate(parse(lex(program))) as Array<FnPrim>; - if (!programFn.fn) { + const [e] = evaluate(parse(lex(program))) as [ + FnPrim | [FnPrim, StackFrame, ASTNode["name"]] + ]; + + const fn: FnPrim = Array.isArray(e) ? e[0] : e; + + if (!fn.fn) { throw new Error( "Cannot create a function from a program that does not eval to a function" ); } - return ((...args: any[]) => - callFn(programFn, args, emptyStackFrame)) as any; + return ((...args: any[]) => callFn(e, args, emptyStackFrame)) as any; }; diff --git a/test/test.ts b/test/test.ts index 4b281b1..4e0bad4 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1,4 +1,4 @@ -import { _Evaluate, createFn, evaluate, lex, parse } from "../src"; +import { _Evaluate, createFn } from "../src"; const KS_boolToBin = "fn(b, ?(b, 1, 0))"; @@ -10,10 +10,10 @@ const factorial = createFn<[number]>()( `bind(fac,fn(n,?(eq(n, 1),n,mul(n,call(fac,sub(n,1))))))` ); -const res = factorial(6); -console.log(res); +const factRes = factorial(6); +console.log(factRes); const closureTest = createFn<[number]>()(`fn(n, call(fn(m, add(m,n)), n))`); -const res2 = closureTest(5); -console.log(res2); +const closureRes = closureTest(6); +console.log(closureRes); |
