From c25dcc0a09c7ef9ed7a71586f9c6c1da0e51b0dd Mon Sep 17 00:00:00 2001 From: ThaumRystra <9525416+ThaumRystra@users.noreply.github.com> Date: Thu, 9 Nov 2023 23:04:18 +0200 Subject: [PATCH] Removed Symbol parse node Too much overlap with accessors, so now all symbols are a special case of accessors --- app/imports/parser/grammar.js | 4 +- app/imports/parser/grammar.ne | 2 +- app/imports/parser/parseTree/_index.js | 4 +- app/imports/parser/parseTree/accessor.js | 71 ++++++++++++++---------- app/imports/parser/parseTree/symbol.js | 57 ------------------- 5 files changed, 46 insertions(+), 92 deletions(-) delete mode 100644 app/imports/parser/parseTree/symbol.js diff --git a/app/imports/parser/grammar.js b/app/imports/parser/grammar.js index 2ef69a71..e8e94076 100644 --- a/app/imports/parser/grammar.js +++ b/app/imports/parser/grammar.js @@ -1,4 +1,4 @@ -// Generated automatically by nearley, version 2.16.0 +// Generated automatically by nearley, version 2.20.1 // http://github.com/Hardmath123/nearley function id(x) { return x[0]; } @@ -122,7 +122,7 @@ let ParserRules = [ {"name": "valueExpression", "symbols": ["string"], "postprocess": id}, {"name": "valueExpression", "symbols": ["boolean"], "postprocess": id}, {"name": "number", "symbols": [(lexer.has("number") ? {type: "number"} : number)], "postprocess": d => node.constant.create({value: +d[0].value})}, - {"name": "name", "symbols": [(lexer.has("name") ? {type: "name"} : name)], "postprocess": d => node.symbol.create({name: d[0].value})}, + {"name": "name", "symbols": [(lexer.has("name") ? {type: "name"} : name)], "postprocess": d => node.accessor.create({name: d[0].value})}, {"name": "string", "symbols": [(lexer.has("string") ? {type: "string"} : string)], "postprocess": d => node.constant.create({value: d[0].value})}, {"name": "boolean", "symbols": [{"literal":"true"}], "postprocess": d => node.constant.create({value: true})}, {"name": "boolean", "symbols": [{"literal":"false"}], "postprocess": d => node.constant.create({value: false})}, diff --git a/app/imports/parser/grammar.ne b/app/imports/parser/grammar.ne index 39407980..a276f8b6 100644 --- a/app/imports/parser/grammar.ne +++ b/app/imports/parser/grammar.ne @@ -159,7 +159,7 @@ number -> %number {% d => node.constant.create({value: +d[0].value}) %} name -> - %name {% d => node.symbol.create({name: d[0].value}) %} + %name {% d => node.accessor.create({name: d[0].value}) %} string -> %string {% d => node.constant.create({value: d[0].value}) %} diff --git a/app/imports/parser/parseTree/_index.js b/app/imports/parser/parseTree/_index.js index 9900c381..3ec39bb4 100644 --- a/app/imports/parser/parseTree/_index.js +++ b/app/imports/parser/parseTree/_index.js @@ -10,7 +10,6 @@ import operator from './operator.js'; import parenthesis from './parenthesis.js'; import roll from './roll.js'; import rollArray from './rollArray.js'; -import symbol from './symbol.js'; import unaryOperator from './unaryOperator.js'; export default Object.freeze({ @@ -26,6 +25,7 @@ export default Object.freeze({ parenthesis, roll, rollArray, - symbol, + // What used to be symbols are now just treated as accessors without a path + symbol: accessor, unaryOperator, }); diff --git a/app/imports/parser/parseTree/accessor.js b/app/imports/parser/parseTree/accessor.js index 51fbbcbf..3f7fe275 100644 --- a/app/imports/parser/parseTree/accessor.js +++ b/app/imports/parser/parseTree/accessor.js @@ -1,6 +1,7 @@ import constant from './constant.js'; -// import array from './array.js'; -import { toString } from '../resolve.js'; +import array from './array.js'; +import resolve from '../resolve.js'; +import { getFromScope } from '/imports/api/creature/creatures/CreatureVariables'; const accessor = { create({ name, path }) { @@ -11,16 +12,21 @@ const accessor = { }; }, compile(node, scope, context) { - let value = scope && scope[node.name]; - // For objects, get their value - node.path.forEach(name => { + let value = getFromScope(node.name, scope); + // Get the value from the given path + node.path?.forEach(name => { if (value === undefined) return; value = value[name]; }); let valueType = getType(value); - // If the accessor returns an objet, get the object's value instead + // If the accessor returns an object, get the object's value instead while (valueType === 'object') { - value = value.value; + // Prefer the valueNode over the value + if (value.valueNode) { + value = value.valueNode; + } else { + value = value.value; + } valueType = getType(value); } // Return a discovered parse node @@ -40,40 +46,44 @@ const accessor = { context, }; } - /* Can't access #object.tags until this is fixed - * If we activate this, the array node expects values to be an array of - * parse nodes, so it will break unless the values are coerced here or at - * in the array node's code to be parse nodes, not raw js - else if (valueType === 'array') { + // Return a parser array + if (valueType === 'array') { + // If the first value is a parse node, assume all the values are + if (getType(value[0]) === 'parseNode') { + return { + result: array.create({ + values: value, + }), + context, + }; + } + // Create the array from js primitives instead return { - result: array.create({ - values: value, - }), + result: array.fromConstantArray(value), context, }; } - */ - else if (valueType === 'undefined') { + if (valueType === 'undefined') { + // Undefined defaults to zero return { - result: accessor.create({ - name: node.name, - path: node.path, + result: constant.create({ + value: 0, }), - context, - }; - } else { - context.error(`Accessing ${accessor.toString(node)} is not supported yet`); - return { - result: accessor.create({ - name: node.name, - path: node.path, - }), - context, + context }; } + context.error(`Accessing ${accessor.toString(node)} is not supported yet`); + return { + result: accessor.create({ + name: node.name, + path: node.path, + }), + context, + }; }, reduce(node, scope, context) { let { result } = accessor.compile(node, scope, context); + ({ result } = resolve('reduce', result, scope, context)); if (result.parseType === 'accessor') { return { result: constant.create({ @@ -86,6 +96,7 @@ const accessor = { } }, toString(node) { + if (!node.path) return `${node.name}`; return `${node.name}.${node.path.join('.')}`; } } diff --git a/app/imports/parser/parseTree/symbol.js b/app/imports/parser/parseTree/symbol.js deleted file mode 100644 index cdad5757..00000000 --- a/app/imports/parser/parseTree/symbol.js +++ /dev/null @@ -1,57 +0,0 @@ -import resolve, { toString } from '../resolve.js'; -import constant from './constant.js'; - -const symbol = { - create({ name }) { - return { - parseType: 'symbol', - name, - }; - }, - toString(node) { - return `${node.name}` - }, - compile(node, scope, context, calledFromReduce = false) { - let value = scope && scope[node.name]; - let type = typeof value; - // For objects, default to their .value - if (type === 'object') { - value = value.value; - type = typeof value; - } - // For parse nodes, compile and return - if (value?.parseType) { - if (calledFromReduce) { - return resolve('reduce', value, scope, context); - } else { - return resolve('compile', value, scope, context); - } - } - if (type === 'string' || type === 'number' || type === 'boolean') { - return { - result: constant.create({ value }), - context, - }; - } else if (type === 'undefined') { - return { - result: symbol.create({ name: node.name }), - context, - }; - } else { - throw new Meteor.Error(`Unexpected case: ${node.name} resolved to ${value}`); - } - }, - reduce(node, scope, context) { - let { result } = symbol.compile(node, scope, context, true); - if (result.parseType === 'symbol') { - return { - result: constant.create({ value: 0 }), - context, - }; - } else { - return { result, context }; - } - } -} - -export default symbol;