71 lines
1.9 KiB
JavaScript
71 lines
1.9 KiB
JavaScript
import ParseNode from '/imports/parser/parseTree/ParseNode.js';
|
|
import ErrorNode from '/imports/parser/parseTree/ErrorNode.js';
|
|
import ConstantNode from '/imports/parser/parseTree/ConstantNode.js';
|
|
import functions from '/imports/parser/functions.js';
|
|
|
|
export default class CallNode extends ParseNode {
|
|
constructor({functionName, args}) {
|
|
super(...arguments);
|
|
this.functionName = functionName;
|
|
this.args = args;
|
|
}
|
|
resolve(fn, scope, context){
|
|
let func = functions[this.functionName];
|
|
if (!func) return new ErrorNode({
|
|
node: this,
|
|
error: `${this.functionName} is not a function`,
|
|
context,
|
|
});
|
|
let args = castArgsToType({fn, scope, context, args: this.args, type: func.argumentType});
|
|
if (args.failed){
|
|
if (fn === 'reduce'){
|
|
return new ErrorNode({
|
|
node: this,
|
|
error: 'Could not convert all arguments to the correct type',
|
|
context,
|
|
});
|
|
} else {
|
|
return new CallNode({
|
|
functionName: this.functionName,
|
|
args: args,
|
|
});
|
|
}
|
|
} else {
|
|
try {
|
|
let value = func.fn.apply(null, args);
|
|
return new ConstantNode({
|
|
value,
|
|
type: 'number',
|
|
previousNodes: [this],
|
|
});
|
|
} catch (error) {
|
|
return new ErrorNode({
|
|
node: this,
|
|
error,
|
|
context,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
toString(){
|
|
return `${this.functionName}(${this.args.map(node => node.toString()).join(', ')})`;
|
|
}
|
|
}
|
|
|
|
function castArgsToType({fn, scope, context, args, type}){
|
|
let resolvedArgs = args.map(node => node[fn](scope, context))
|
|
let result = [];
|
|
if (type === 'number'){
|
|
resolvedArgs.forEach(node => {
|
|
if (node.isNumber){
|
|
result.push(node.value);
|
|
} else {
|
|
resolvedArgs.failed = true;
|
|
}
|
|
})
|
|
}
|
|
if (resolvedArgs.failed) return resolvedArgs;
|
|
console.log({result})
|
|
return result;
|
|
}
|