Files
DiceCloud/app/imports/parser/parseTree/IndexNode.js

65 lines
1.8 KiB
JavaScript

import ParseNode from '/imports/parser/parseTree/ParseNode.js';
import ArrayNode from '/imports/parser/parseTree/ArrayNode.js';
import ErrorNode from '/imports/parser/parseTree/ErrorNode.js';
export default class IndexNode extends ParseNode {
constructor({array, index}) {
super(...arguments);
this.array = array;
this.index = index;
}
resolve(fn, scope, context){
let index = this.index[fn](scope, context);
let array = this.array[fn](scope, context);
if (index.isInteger && array instanceof ArrayNode){
if (index.value < 1 || index.value > array.values.length){
if (context){
context.storeError({
type: 'warning',
message: `Index of ${index.value} is out of range for an array` +
` of length ${array.values.length}`,
});
}
}
let selection = array.values[index.value - 1];
if (selection){
let result = selection[fn](scope, context);
return result;
}
} else if (fn === 'reduce'){
if (!(array instanceof ArrayNode)){
return new ErrorNode({
node: this,
error: 'Can not get the index of a non-array node: ' +
this.array.toString() + ' = ' + array.toString(),
context,
});
} else if (!index.isInteger){
return new ErrorNode({
node: this,
error: array.toString() + ' is not an integer index of the array',
context,
});
}
}
return new IndexNode({
index,
array,
previousNodes: [this],
});
}
toString(){
return `${this.array.toString()}[${this.index.toString()}]`;
}
traverse(fn){
fn(this);
this.array.traverse(fn);
this.index.traverse(fn);
}
replaceChildren(fn){
this.array = this.array.replaceNodes(fn);
this.index = this.index.replaceNodes(fn);
}
}