display dynamic errors too
This commit is contained in:
parent
abd3bd3645
commit
955bb17f9a
3 changed files with 46 additions and 17 deletions
|
|
@ -9,7 +9,10 @@ export interface DynamicEnvironment {
|
|||
names: any;
|
||||
}
|
||||
|
||||
export type EvalResult = any;
|
||||
export interface EvalResult {
|
||||
val?: any;
|
||||
err?: Error;
|
||||
};
|
||||
|
||||
export function evalExpr(s: ExprBlockState, env: DynamicEnvironment): EvalResult {
|
||||
if (s.kind === "input") {
|
||||
|
|
@ -28,44 +31,65 @@ export function evalExpr(s: ExprBlockState, env: DynamicEnvironment): EvalResult
|
|||
|
||||
export function evalInput(s: InputBlockState, env: DynamicEnvironment): EvalResult {
|
||||
if (s.value.kind === "literal") {
|
||||
if (s.text === '') {
|
||||
return {
|
||||
err: new Error('cannot parse empty string as '+s.value.type)
|
||||
};
|
||||
}
|
||||
const ctor = {
|
||||
Int: BigInt,
|
||||
Double: Number,
|
||||
}[s.value.type] as (s: string) => any;
|
||||
return ctor(s.text);
|
||||
return {
|
||||
val: ctor(s.text)
|
||||
};
|
||||
}
|
||||
else if (s.value.kind === "name") {
|
||||
const found = trie.get(env.names)(s.text);
|
||||
if (found) {
|
||||
if (found.recursive) {
|
||||
// dirty
|
||||
return found.i();
|
||||
}
|
||||
return found.i;
|
||||
return {val: found.i};
|
||||
}
|
||||
}
|
||||
return {
|
||||
err: new Error(`'${s.text}' not found`),
|
||||
}
|
||||
}
|
||||
|
||||
export function evalCall(s: CallBlockState, env: DynamicEnvironment): EvalResult {
|
||||
const fn = evalExpr(s.fn, env);
|
||||
const input = evalExpr(s.input, env);
|
||||
if (fn !== undefined && input !== undefined) {
|
||||
if (fn.val !== undefined && input.val !== undefined) {
|
||||
try {
|
||||
return fn(input);
|
||||
const result = fn.val(input.val)
|
||||
return { val: result } ;
|
||||
}
|
||||
catch (e: any) {
|
||||
return { err: e };
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
export function evalLet(s: LetInBlockState, env: DynamicEnvironment): EvalResult {
|
||||
const valueEnv = {
|
||||
names: trie.insert(env.names)(s.name)({
|
||||
recursive: true,
|
||||
i: () => { try { return value; } catch (e) {} },
|
||||
i: () => {
|
||||
try {
|
||||
return { val };
|
||||
} catch (e) {
|
||||
return { err: e };
|
||||
}
|
||||
},
|
||||
}),
|
||||
};
|
||||
const value = evalExpr(s.value, valueEnv);
|
||||
const {val} = evalExpr(s.value, valueEnv);
|
||||
const innerEnv = {
|
||||
names: trie.insert(env.names)(s.name)({i: value}),
|
||||
names: trie.insert(env.names)(s.name)({i: val}),
|
||||
}
|
||||
return evalExpr(s.inner, innerEnv);
|
||||
}
|
||||
|
|
@ -75,7 +99,8 @@ export function evalLambda(s: LambdaBlockState, env: DynamicEnvironment): EvalRe
|
|||
const innerEnv = {
|
||||
names: trie.insert(env.names)(s.paramName)({i: x})
|
||||
};
|
||||
return evalExpr(s.expr, innerEnv);
|
||||
const result = evalExpr(s.expr, innerEnv);
|
||||
return result.val;
|
||||
};
|
||||
return fn;
|
||||
return {val: fn};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue