adding deepEqual. validating vars in eval
This commit is contained in:
parent
c294d7fd6a
commit
e12809efba
4 changed files with 41 additions and 21 deletions
|
|
@ -19,8 +19,8 @@ export const _rt = {
|
|||
max: (a: number) => (b: number) => Math.max(a, b),
|
||||
min: (a: number) => (b: number) => Math.min(a, b),
|
||||
|
||||
eq: (a: any) => (b: any) => ({ _tag: a === b ? 'True' : 'False' }),
|
||||
neq: (a: any) => (b: any) => ({ _tag: a !== b ? 'True' : 'False' }),
|
||||
eq: (a: any) => (b: any) => ({ _tag: deepEqual(a, b) ? 'True' : 'False' }),
|
||||
neq: (a: any) => (b: any) => ({ _tag: deepEqual(a, b) ? 'False' : 'True' }),
|
||||
gt: (a: any) => (b: any) => ({ _tag: a > b ? 'True' : 'False' }),
|
||||
lt: (a: any) => (b: any) => ({ _tag: a < b ? 'True' : 'False' }),
|
||||
gte: (a: any) => (b: any) => ({ _tag: a >= b ? 'True' : 'False' }),
|
||||
|
|
@ -142,7 +142,6 @@ export const _rt = {
|
|||
return printed;
|
||||
},
|
||||
rebind: (name: string, pathOrValue: any, maybeValue?: any) => {
|
||||
console.log("rebind", store, name, pathOrValue, maybeValue);
|
||||
if (maybeValue === undefined) {
|
||||
store[name] = pathOrValue;
|
||||
} else {
|
||||
|
|
@ -202,13 +201,17 @@ export const _rt = {
|
|||
const parser = new Parser(tokens, wrapped);
|
||||
const defs = parser.parse();
|
||||
const ast = defs[0].body;
|
||||
|
||||
// validate free vars
|
||||
// const free = freeVars(ast);
|
||||
// const allowed = new Set([
|
||||
// ...Object.keys(store),
|
||||
// ...Object.keys(_rt),
|
||||
// 'True'
|
||||
// ])
|
||||
const free = freeVars(ast);
|
||||
const allowed = new Set([
|
||||
...Object.keys(store),
|
||||
...Object.keys(_rt)
|
||||
]);
|
||||
const unknown = [...free].filter(v => !allowed.has(v));
|
||||
if (unknown.length > 0) {
|
||||
return { _tag: 'Err', _0: `Unknown: ${unknown.join(', ')}` };
|
||||
}
|
||||
|
||||
const compiled = compile(defs[0].body);
|
||||
const fn = new Function('_rt', 'store', `return ${compiled}`);
|
||||
|
|
@ -314,3 +317,17 @@ export function syncToAst(name: string) {
|
|||
saveDefinitions();
|
||||
}
|
||||
}
|
||||
|
||||
function deepEqual(a: any, b: any): boolean {
|
||||
if (a === b) return true;
|
||||
if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') return false;
|
||||
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
||||
if (Array.isArray(a)) {
|
||||
if (a.length !== b.length) return false;
|
||||
return a.every((v, i) => deepEqual(v, b[i]));
|
||||
}
|
||||
const keysA = Object.keys(a);
|
||||
const keysB = Object.keys(b);
|
||||
if (keysA.length !== keysB.length) return false;
|
||||
return keysA.every(k => deepEqual(a[k], b[k]));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue