Merge branch 'develop' into feature-nested-sets

This commit is contained in:
ThaumRystra
2023-11-11 10:01:34 +02:00
40 changed files with 562 additions and 394 deletions

View File

@@ -10,7 +10,6 @@ import operator from './operator';
import parenthesis from './parenthesis';
import roll from './roll';
import rollArray from './rollArray';
import symbol from './symbol';
import unaryOperator from './unaryOperator';
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,
});

View File

@@ -1,6 +1,7 @@
import constant from './constant';
// import array from './array';
import { toString } from '../resolve';
import array from './array';
import resolve from '../resolve';
import { getFromScope } from '/imports/api/creature/creatures/CreatureVariables';
const accessor = {
create({ name, path }) {
@@ -11,62 +12,75 @@ 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 = Array.isArray(value) ? 'array' : typeof value;
// If the accessor returns an objet, get the object's value instead
let valueType = getType(value);
// If the accessor returns an object, get the object's value instead
while (valueType === 'object') {
value = value.value;
valueType = Array.isArray(value) ? 'array' : typeof value;
// Prefer the valueNode over the value
if (value.valueNode) {
value = value.valueNode;
} else {
value = value.value;
}
valueType = getType(value);
}
// Return a parse node based on the type returned
// Return a discovered parse node
if (valueType === 'parseNode') {
return {
result: value,
context,
};
}
// Return a parse node based on the constant type returned
if (valueType === 'string' || valueType === 'number' || valueType === 'boolean') {
return {
result: constant.create({ value }),
context,
};
}
// 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.fromConstantArray(value),
context,
};
}
if (valueType === 'undefined') {
// Undefined defaults to zero
return {
result: constant.create({
value,
valueType
value: 0,
}),
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 {
result: array.create({
values: value,
}),
context,
};
}
*/
else if (valueType === 'undefined') {
return {
result: accessor.create({
name: node.name,
path: node.path,
}),
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({
@@ -79,8 +93,16 @@ const accessor = {
}
},
toString(node) {
if (!node.path) return `${node.name}`;
return `${node.name}.${node.path.join('.')}`;
}
}
function getType(val) {
if (!val) return typeof val;
if (Array.isArray(val)) return 'array';
if (val.parseType) return 'parseNode';
return typeof val;
}
export default accessor;

View File

@@ -19,7 +19,9 @@ const array = {
) {
return constant.create({ value, valueType });
} else {
throw `Unexpected type in constant array: ${valueType}`
// Gracefully create an empty spot in the array for unsupported types
return undefined;
// throw `Unexpected type in constant array: ${valueType}`
}
});
return array.create({ values });

View File

@@ -1,16 +1,16 @@
const error = {
create({node, error}) {
create({ node, error }) {
return {
parseType: 'error',
node,
error,
}
},
compile(node, scope, context){
return {result: node, context};
compile(node, scope, context) {
return { result: node, context };
},
toString(node){
return node.error.toString();
toString(node) {
return `${node.error.type} error: ${node.error.message}`;
},
}

View File

@@ -2,13 +2,12 @@ import resolve, { toString, traverse, map } from '../resolve';
import constant from './constant';
const operator = {
create({ left, right, operator, fn }) {
create({ left, right, operator }) {
return {
parseType: 'operator',
left,
right,
operator,
fn
};
},
resolve(fn, node, scope, context) {
@@ -21,7 +20,6 @@ const operator = {
left: leftNode,
right: rightNode,
operator: node.operator,
fn: node.fn,
}),
context,
};

View File

@@ -1,57 +0,0 @@
import resolve, { toString } from '../resolve';
import constant from './constant';
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;