From 574f8373e799dd5c88b4a669f8a1b62b48426cca Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Mon, 1 Mar 2021 14:47:46 +0200 Subject: [PATCH] Fixed crash when indexing a non-array node, added more array node errors --- app/imports/parser/parseTree/IndexNode.js | 34 +++++++++++++++++-- .../parser/parseTree/ParenthesisNode.js | 1 + 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/app/imports/parser/parseTree/IndexNode.js b/app/imports/parser/parseTree/IndexNode.js index 850ff088..fdd6c6c6 100644 --- a/app/imports/parser/parseTree/IndexNode.js +++ b/app/imports/parser/parseTree/IndexNode.js @@ -1,4 +1,6 @@ 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}) { @@ -8,16 +10,42 @@ export default class IndexNode extends ParseNode { } resolve(fn, scope, context){ let index = this.index[fn](scope, context); - if (index.isInteger){ - let selection = this.array.values[index.value - 1]; + 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: this.array[fn](scope, context), + array, previousNodes: [this], }); } diff --git a/app/imports/parser/parseTree/ParenthesisNode.js b/app/imports/parser/parseTree/ParenthesisNode.js index eda6038f..db6b5e14 100644 --- a/app/imports/parser/parseTree/ParenthesisNode.js +++ b/app/imports/parser/parseTree/ParenthesisNode.js @@ -8,6 +8,7 @@ export default class ParenthesisNode extends ParseNode { resolve(fn, scope, context){ let content = this.content[fn](scope, context); if ( + fn === 'reduce' || content.constructor.name === 'ConstantNode' || content.constructor.name === 'ErrorNode' ){