fable 3.0.132 → 3.0.133

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/debug/Harness.js CHANGED
@@ -7,10 +7,12 @@ testFable.instantiateServiceProviderIfNotExists('ExpressionParser');
7
7
 
8
8
  let tmpExpression = '';
9
9
  //tmpExpression = 'Result = 5+3 - sqrt(75 / (3 + Depth) * Width)^ 3';
10
- tmpExpression = 'Result = (160 * PR * Z) / (C / 100) * PR * Z + (160 * (1 - C / 100))';
11
- //tmpExpression = "Result = (160 * PR * Z) / (C / 100) * PR * Z + (160 * (1 - C / 100))";
10
+ //tmpExpression = 'Result = (160 * PR * Z) / (C / 100) * PR * Z + (160 * (1 - C / 100))';
12
11
  //tmpExpression = '1.5 * sqrt(8 * 2.423782342^2) / 10';
12
+ //tmpExpression = 'Result = ((15000 * 2) / 4)^2 + 100 - 10 * (35 + 5)';
13
+ //tmpExpression = 'Result = 1 * sqrt(16)';
13
14
  //tmpExpression = 'Result = sqrt(100 * (C + 30)) + sin(Depth - Width) / 10';
15
+ tmpExpression = 'Result = 3.5 + 50 + 10 * 10 / 5 - 1.5';
14
16
  let tmpSimpleDataObject = { "PR": 1.5, "Z": "20.036237", "C": -13, Depth: 100.203, Width: 10.5};
15
17
 
16
18
  testFable.log.info(`tmpExpression: ${tmpExpression}`);
@@ -28,6 +30,7 @@ for (let i = 0; i < tmpResultsObject.PostfixSolveList.length; i++)
28
30
  let tmpResultValue = testFable.ExpressionParser.solvePostfixedExpression(tmpResultsObject.PostfixSolveList, tmpSimpleDataObject, tmpResultsObject);
29
31
  console.log(`Result: ${tmpResultValue}`);
30
32
  console.log('QED');
33
+ //41.32965489638783839821'
31
34
 
32
35
  function getTokenString(pToken)
33
36
  {
@@ -1549,7 +1549,7 @@ var tmpDescriptorAddresses=Object.keys(tmpSource);tmpDescriptorAddresses.forEach
1549
1549
  * @class Manyfest
1550
1550
  */var Manyfest=/*#__PURE__*/function(_libFableServiceProvi6){_inherits(Manyfest,_libFableServiceProvi6);function Manyfest(pFable,pManifest,pServiceHash){var _this15;_classCallCheck2(this,Manyfest);if(pFable===undefined){_this15=_callSuper(this,Manyfest,[{}]);}else{_this15=_callSuper(this,Manyfest,[pFable,pManifest,pServiceHash]);}_this15.serviceType='Manifest';// Wire in logging
1551
1551
  _this15.logInfo=libSimpleLog;_this15.logError=libSimpleLog;// Create an object address resolver and map in the functions
1552
- _this15.objectAddressCheckAddressExists=new libObjectAddressCheckAddressExists(_this15.logInfo,_this15.logError);_this15.objectAddressGetValue=new libObjectAddressGetValue(_this15.logInfo,_this15.logError);_this15.objectAddressSetValue=new libObjectAddressSetValue(_this15.logInfo,_this15.logError);_this15.objectAddressDeleteValue=new libObjectAddressDeleteValue(_this15.logInfo,_this15.logError);if(!('defaultValues'in _this15.options)){_this15.options.defaultValues={"String":"","Number":0,"Float":0.0,"Integer":0,"Boolean":false,"Binary":0,"DateTime":0,"Array":[],"Object":{},"Null":null};}if(!('strict'in _this15.options)){_this15.options.strict=false;}_this15.scope=undefined;_this15.elementAddresses=undefined;_this15.elementHashes=undefined;_this15.elementDescriptors=undefined;_this15.reset();if(_typeof(_this15.options)==='object'){_this15.loadManifest(_this15.options);}_this15.schemaManipulations=new libSchemaManipulation(_this15.logInfo,_this15.logError);_this15.objectAddressGeneration=new libObjectAddressGeneration(_this15.logInfo,_this15.logError);_this15.hashTranslations=new libHashTranslation(_this15.logInfo,_this15.logError);return _possibleConstructorReturn(_this15);}/*************************************************************************
1552
+ _this15.objectAddressCheckAddressExists=new libObjectAddressCheckAddressExists(_this15.logInfo,_this15.logError);_this15.objectAddressGetValue=new libObjectAddressGetValue(_this15.logInfo,_this15.logError);_this15.objectAddressSetValue=new libObjectAddressSetValue(_this15.logInfo,_this15.logError);_this15.objectAddressDeleteValue=new libObjectAddressDeleteValue(_this15.logInfo,_this15.logError);if(!('defaultValues'in _this15.options)){_this15.options.defaultValues={"String":"","Number":0,"Float":0.0,"Integer":0,"PreciseNumber":"0.0","Boolean":false,"Binary":0,"DateTime":0,"Array":[],"Object":{},"Null":null};}if(!('strict'in _this15.options)){_this15.options.strict=false;}_this15.scope=undefined;_this15.elementAddresses=undefined;_this15.elementHashes=undefined;_this15.elementDescriptors=undefined;_this15.reset();if(_typeof(_this15.options)==='object'){_this15.loadManifest(_this15.options);}_this15.schemaManipulations=new libSchemaManipulation(_this15.logInfo,_this15.logError);_this15.objectAddressGeneration=new libObjectAddressGeneration(_this15.logInfo,_this15.logError);_this15.hashTranslations=new libHashTranslation(_this15.logInfo,_this15.logError);_this15.numberRegex=/^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;return _possibleConstructorReturn(_this15);}/*************************************************************************
1553
1553
  * Schema Manifest Loading, Reading, Manipulation and Serialization Functions
1554
1554
  */ // Reset critical manifest properties
1555
1555
  _createClass2(Manyfest,[{key:"reset",value:function reset(){this.scope='DEFAULT';this.elementAddresses=[];this.elementHashes={};this.elementDescriptors={};}},{key:"clone",value:function clone(){// Make a copy of the options in-place
@@ -1589,8 +1589,8 @@ tmpValue=this.getDefaultValue(this.getDescriptor(pAddress));}return tmpValue;}//
1589
1589
  for(var i=0;i<this.elementAddresses.length;i++){var tmpDescriptor=this.getDescriptor(this.elementAddresses[i]);var tmpValueExists=this.checkAddressExists(pObject,tmpDescriptor.Address);var tmpValue=this.getValueAtAddress(pObject,tmpDescriptor.Address);if(typeof tmpValue=='undefined'||!tmpValueExists){// This will technically mean that `Object.Some.Value = undefined` will end up showing as "missing"
1590
1590
  // TODO: Do we want to do a different message based on if the property exists but is undefined?
1591
1591
  tmpValidationData.MissingElements.push(tmpDescriptor.Address);if(tmpDescriptor.Required||this.options.strict){addValidationError(tmpDescriptor.Address,'is flagged REQUIRED but is not set in the object');}}// Now see if there is a data type specified for this element
1592
- if(tmpDescriptor.DataType){var tmpElementType=_typeof(tmpValue);switch(tmpDescriptor.DataType.toString().trim().toLowerCase()){case'string':if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}break;case'number':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}break;case'integer':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}else{var tmpValueString=tmpValue.toString();if(tmpValueString.indexOf('.')>-1){// TODO: Is this an error?
1593
- addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but has a decimal point in the number."));}}break;case'float':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}break;case'DateTime':var tmpValueDate=new Date(tmpValue);if(tmpValueDate.toString()=='Invalid Date'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is not parsable as a Date by Javascript"));}default:// Check if this is a string, in the default case
1592
+ if(tmpDescriptor.DataType){var tmpElementType=_typeof(tmpValue);switch(tmpDescriptor.DataType.toString().trim().toLowerCase()){case'string':if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}break;case"precisenumber":if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}else if(!this.numberRegex.test(tmpValue)){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is not a valid number"));}break;case'number':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}break;case'integer':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}else{var tmpValueString=tmpValue.toString();if(tmpValueString.indexOf('.')>-1){// TODO: Is this an error?
1593
+ addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but has a decimal point in the number."));}}break;case'float':if(tmpElementType!='number'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is of the type ").concat(tmpElementType));}break;case'datetime':var tmpValueDate=new Date(tmpValue);if(tmpValueDate.toString()=='Invalid Date'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," but is not parsable as a Date by Javascript"));}default:// Check if this is a string, in the default case
1594
1594
  // Note this is only when a DataType is specified and it is an unrecognized data type.
1595
1595
  if(tmpElementType!='string'){addValidationError(tmpDescriptor.Address,"has a DataType ".concat(tmpDescriptor.DataType," (which auto-converted to String because it was unrecognized) but is of the type ").concat(tmpElementType));}break;}}}return tmpValidationData;}// Returns a default value, or, the default value for the data type (which is overridable with configuration)
1596
1596
  },{key:"getDefaultValue",value:function getDefaultValue(pDescriptor){if(_typeof(pDescriptor)!='object'){return undefined;}if('Default'in pDescriptor){return pDescriptor.Default;}else{// Default to a null if it doesn't have a type specified.
@@ -3448,88 +3448,44 @@ this.getTokenType(pTokenizedExpression[0])==='Token.StateAddress'||this.getToken
3448
3448
  ){tmpResults.ExpressionParserLog.push("WARNING: ExpressionParser.lintTokenizedExpression found a single equality assignment in the tokenized expression with no assignable address on the left side of the assignment.");tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}}}// 5. Check that there are no operators adjacent to each other
3449
3449
  // This is a simple lint check, not a full-blown syntax check
3450
3450
  var tmpTokenPrevious=false;for(var _i17=0;_i17<pTokenizedExpression.length-1;_i17++){if(pTokenizedExpression[_i17]in this.ExpressionParser.tokenMap&&this.ExpressionParser.tokenMap[pTokenizedExpression[_i17]].Type!='Parenthesis'&&!tmpTokenPrevious){tmpTokenPrevious=true;}else if(pTokenizedExpression[_i17]in this.ExpressionParser.tokenMap&&this.ExpressionParser.tokenMap[pTokenizedExpression[_i17]].Type!='Parenthesis'){// If this isn't a + or - positivity/negativity multiplier, it's an error.
3451
- if(pTokenizedExpression[_i17]!=='+'&&pTokenizedExpression[_i17]!=='-'){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.lintTokenizedExpression found an ".concat(pTokenizedExpression[_i17]," operator adjacent to another operator in the tokenized expression at token index ").concat(_i17));tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}}else{tmpTokenPrevious=false;}}return tmpResults.LinterResults;}}]);return ExpressionParserLinter;}(libExpressionParserOperationBase);module.exports=ExpressionParserLinter;},{"./Fable-Service-ExpressionParser-Base.js":136}],140:[function(require,module,exports){var libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');var ExpressionParserPostfix=/*#__PURE__*/function(_libExpressionParserO3){_inherits(ExpressionParserPostfix,_libExpressionParserO3);function ExpressionParserPostfix(pFable,pOptions,pServiceHash){var _this28;_classCallCheck2(this,ExpressionParserPostfix);_this28=_callSuper(this,ExpressionParserPostfix,[pFable,pOptions,pServiceHash]);_this28.serviceType='ExpressionParser-Postfix';return _this28;}_createClass2(ExpressionParserPostfix,[{key:"getPosfixSolveListOperation",value:function getPosfixSolveListOperation(pOperation,pLeftValue,pRightValue,pDepthSolveList,pDepthSolveIndex){var tmpOperation={VirtualSymbolName:pOperation.VirtualSymbolName,Operation:pOperation,LeftValue:pLeftValue,RightValue:pRightValue};var tmpDepthSolveList=Array.isArray(pDepthSolveList)?pDepthSolveList:false;// // Although we have a `Token.Type == "Parenthesis"` option to check on, keeping these explicit means the solver won't
3452
- // // allow users to pass in parenthesis in the wrong order.
3453
- // // The linter does blow up as does the postfix, but, just in case we'll leave these explicit.
3454
- // // It really doesn't hurt anything.
3455
- // if (pLeftValue.Token === ')')
3456
- // {
3457
- // // We have found a close parenthesis which needs to pull the proper virtual symbol for the last operation on this stack.
3458
- // // This ensures we are not expressing the parenthesis virtual symbols to the solver.
3459
- // pLeftValue.VirtualSymbolName = pLayerStackMap[pLeftValue.SolveLayerStack];
3460
- // this.log.error(`ERROR: ExpressionParser.getPosfixSolveListOperation found a close parenthesis in the left value of an operation.`);
3461
- // }
3462
- // else if (pRightValue.Token === '(')
3463
- // {
3464
- // // We have found a close parenthesis which needs to pull the proper virtual symbol for the last operation on this stack.
3465
- // // This ensures we are not expressing the parenthesis virtual symbols to the solver.
3466
- // pRightValue.VirtualSymbolName = pLayerStackMap[pRightValue.SolveLayerStack];
3467
- // this.log.error(`ERROR: ExpressionParser.getPosfixSolveListOperation found a close parenthesis in the left value of an operation.`);
3468
- // }
3469
- // // Set the layer stack map virtual symbol name to the last operation performed on this stack.
3470
- // pLayerStackMap[pOperation.SolveLayerStack] = pOperation.VirtualSymbolName;
3471
- /* These two if blocks are very complex -- they basically provide a
3451
+ if(pTokenizedExpression[_i17]!=='+'&&pTokenizedExpression[_i17]!=='-'){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.lintTokenizedExpression found an ".concat(pTokenizedExpression[_i17]," operator adjacent to another operator in the tokenized expression at token index ").concat(_i17));tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}}else{tmpTokenPrevious=false;}}return tmpResults.LinterResults;}}]);return ExpressionParserLinter;}(libExpressionParserOperationBase);module.exports=ExpressionParserLinter;},{"./Fable-Service-ExpressionParser-Base.js":136}],140:[function(require,module,exports){var libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');var ExpressionParserPostfix=/*#__PURE__*/function(_libExpressionParserO3){_inherits(ExpressionParserPostfix,_libExpressionParserO3);function ExpressionParserPostfix(pFable,pOptions,pServiceHash){var _this28;_classCallCheck2(this,ExpressionParserPostfix);_this28=_callSuper(this,ExpressionParserPostfix,[pFable,pOptions,pServiceHash]);_this28.serviceType='ExpressionParser-Postfix';return _this28;}_createClass2(ExpressionParserPostfix,[{key:"getPosfixSolveListOperation",value:function getPosfixSolveListOperation(pOperation,pLeftValue,pRightValue,pDepthSolveList,pDepthSolveIndex){var tmpOperation={VirtualSymbolName:pOperation.VirtualSymbolName,Operation:pOperation,LeftValue:pLeftValue,RightValue:pRightValue};var tmpDepthSolveList=Array.isArray(pDepthSolveList)?pDepthSolveList:false;/* These two if blocks are very complex -- they basically provide a
3472
3452
  * way to deal with recursion that can be expressed to the user in
3473
3453
  * a meaningful way.
3474
3454
  *
3475
3455
  * The reason we are doing it as such is to show exactly how the
3476
3456
  * solver resolves the passed-in tokens into a solvable expression.
3477
3457
  */if(!tmpOperation.LeftValue.VirtualSymbolName){tmpOperation.LeftValue.VirtualSymbolName=tmpOperation.VirtualSymbolName;}else{// We need to set the left value to a virtual symbol instead of the looked up value if it's already used in another operation
3478
- tmpOperation.LeftValue=this.getTokenContainerObject(tmpOperation.LeftValue.VirtualSymbolName,'Token.VirtualSymbol');// Now walk backwards and see if we need to update a previous symbol for a previously unparsed operator
3479
- if(tmpDepthSolveList){for(var i=pDepthSolveIndex-1;i>=0;i--){if(tmpDepthSolveList[i].Type==='Token.Operator'&&!tmpDepthSolveList[i].Parsed&&// When walking backward, we only want to mutate if the .
3480
- 'Descriptor'in tmpDepthSolveList[i]&&'Descriptor'in tmpOperation.Operation&&// Anything >3 does not have commutative properties
3481
- tmpDepthSolveList[i].Descriptor.Precedence>3){// If the symbol to its right is not the same as this operation
3482
- if(tmpDepthSolveList[i+1].VirtualSymbolName!==tmpOperation.VirtualSymbolName){// This is the recursive "shunting" being simulated
3483
- tmpDepthSolveList[i+1].VirtualSymbolName=tmpOperation.VirtualSymbolName;}break;}}}}if(!tmpOperation.RightValue.VirtualSymbolName){tmpOperation.RightValue.VirtualSymbolName=tmpOperation.VirtualSymbolName;}else{// We need to set the right value to a virtual symbol instead of the looked up value if it's already used in another operation
3484
- tmpOperation.RightValue=this.getTokenContainerObject(tmpOperation.RightValue.VirtualSymbolName,'Token.VirtualSymbol');// Now walk forwards and see if we need to update an upcoming symbol for a previously unparsed operator
3485
- if(tmpDepthSolveList){for(var _i18=pDepthSolveIndex+1;_i18<tmpDepthSolveList.length;_i18++){if(tmpDepthSolveList[_i18].Type==='Token.Operator'&&!tmpDepthSolveList[_i18].Parsed&&// When walking forward, we only want to mutate if the precedence hasn't been solved.
3486
- 'Descriptor'in tmpDepthSolveList[_i18]&&'Descriptor'in tmpOperation.Operation&&// Anything >3 does not have commutative properties
3487
- tmpDepthSolveList[_i18].Descriptor.Precedence>3){// If the symbol to its right is not the same as this operation
3488
- if(tmpDepthSolveList[_i18-1].VirtualSymbolName!==tmpOperation.VirtualSymbolName){// This is the recursive "shunting" being simulated
3489
- tmpDepthSolveList[_i18-1].VirtualSymbolName=tmpOperation.VirtualSymbolName;}break;}else if(tmpDepthSolveList[_i18].Type==='Token.Operator'&&!tmpDepthSolveList[_i18].Parsed){break;}}}}tmpOperation.Operation.Parsed=true;return tmpOperation;}},{key:"buildPostfixedSolveList",value:function buildPostfixedSolveList(pTokenizedExpression,pResultObject){var tmpResults=_typeof(pResultObject)==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.PostfixedAssignmentAddress='Result';tmpResults.PostfixTokenObjects=[];tmpResults.PostfixSolveList=[];if(pTokenizedExpression.length<3){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList was passed a tokenized expression with less than three tokens.");this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixTokenObjects;}// 1. Figure out the Equality Assignment
3458
+ if('LeftVirtualSymbolName'in tmpOperation.Operation){tmpOperation.LeftValue=this.getTokenContainerObject(tmpOperation.Operation.LeftVirtualSymbolName,'Token.VirtualSymbol');}else{tmpOperation.LeftValue=this.getTokenContainerObject(tmpOperation.LeftValue.VirtualSymbolName,'Token.VirtualSymbol');}}if(!tmpOperation.RightValue.VirtualSymbolName){tmpOperation.RightValue.VirtualSymbolName=tmpOperation.VirtualSymbolName;}else{// We need to set the right value to a virtual symbol instead of the looked up value if it's already used in another operation
3459
+ //if ('LeftVirtualSymbolName' in tmpOperation.RightValue)
3460
+ if('RightVirtualSymbolName'in tmpOperation.Operation){tmpOperation.RightValue=this.getTokenContainerObject(tmpOperation.Operation.RightVirtualSymbolName,'Token.VirtualSymbol');}else{tmpOperation.RightValue=this.getTokenContainerObject(tmpOperation.RightValue.VirtualSymbolName,'Token.VirtualSymbol');}}tmpOperation.Operation.Parsed=true;return tmpOperation;}},{key:"buildPostfixedSolveList",value:function buildPostfixedSolveList(pTokenizedExpression,pResultObject){var tmpResults=_typeof(pResultObject)==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.PostfixedAssignmentAddress='Result';tmpResults.PostfixTokenObjects=[];tmpResults.PostfixSolveList=[];if(pTokenizedExpression.length<3){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList was passed a tokenized expression with less than three tokens.");this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixTokenObjects;}// 1. Figure out the Equality Assignment
3490
3461
  var tmpEqualsIndex=-1;for(var i=0;i<pTokenizedExpression.length;i++){if(pTokenizedExpression[i]==='='&&tmpEqualsIndex<0){tmpEqualsIndex=i;}// If there are two equality assignments, error and bail out.
3491
3462
  else if(pTokenizedExpression[i]==='='){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found multiple equality assignments in the tokenized expression; equality assignment #".concat(tmpEqualsIndex," at token index ").concat(i,"."));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixTokenObjects;}}if(tmpEqualsIndex==-1){tmpResults.ExpressionParserLog.push("WARNING: ExpressionParser.buildPostfixedSolveList found no equality assignment in the tokenized expression; defaulting to Result");this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}else if(tmpEqualsIndex>1){tmpResults.ExpressionParserLog.push("WARNING: ExpressionParser.buildPostfixedSolveList found an equality assignment in the tokenized expression at an unexpected location (token index ".concat(tmpEqualsIndex,"); the expression cannot be parsed."));this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}else if(tmpEqualsIndex===0){// This is an implicit function -- just go to result and return the value.
3492
3463
  // That is... the user entered something like "= 5 + 3" so we should just return 8, and use the default Result quietly.
3493
3464
  }else{tmpResults.PostfixedAssignmentAddress=pTokenizedExpression[0];}// 2. Categorize tokens in the expression, put them in the "expression list" as a token object
3494
- for(var _i19=tmpEqualsIndex+1;_i19<pTokenizedExpression.length;_i19++){tmpResults.PostfixTokenObjects.push(this.getTokenContainerObject(pTokenizedExpression[_i19]));}// 3. Decorate mathematical parsing depth and detect functions at the same time
3465
+ for(var _i18=tmpEqualsIndex+1;_i18<pTokenizedExpression.length;_i18++){tmpResults.PostfixTokenObjects.push(this.getTokenContainerObject(pTokenizedExpression[_i18]));}// 3. Decorate mathematical parsing depth and detect functions at the same time
3495
3466
  // Having written this a few times now, it's easier to detect functions *while* parsing depth.
3496
3467
  // Especially if we want our system to be able to communicate with the user when there is an issue.
3497
3468
  var tmpDepth=0;// The virtual symbol index is used for the abstract interim values that are generated at each step of the solve
3498
3469
  var tmpVirtualParenthesisIndex=0;var tmpSolveLayerStack=[];// Kick off the solve layer stack with the first solve set identifier
3499
- tmpSolveLayerStack.push("SolveSet_".concat(tmpVirtualParenthesisIndex,"_D_").concat(tmpDepth));for(var _i20=0;_i20<tmpResults.PostfixTokenObjects.length;_i20++){// 1. If it's an open parenthesis, set the parenthesis at the current depth and increment the depth
3500
- if(tmpResults.PostfixTokenObjects[_i20].Token==='('){// Set the depth of the open parenthesis to the current solution depth
3501
- tmpResults.PostfixTokenObjects[_i20].Depth=tmpDepth;// Generate the virtual symbol name for user output
3502
- tmpResults.PostfixTokenObjects[_i20].VirtualSymbolName="Pr_".concat(tmpVirtualParenthesisIndex,"_D_").concat(tmpDepth);// 1a. Detect if this parenthesis is signaling a function
3470
+ tmpSolveLayerStack.push("SolveSet_".concat(tmpVirtualParenthesisIndex,"_D_").concat(tmpDepth));for(var _i19=0;_i19<tmpResults.PostfixTokenObjects.length;_i19++){// 1. If it's an open parenthesis, set the parenthesis at the current depth and increment the depth
3471
+ if(tmpResults.PostfixTokenObjects[_i19].Token==='('){// Set the depth of the open parenthesis to the current solution depth
3472
+ tmpResults.PostfixTokenObjects[_i19].Depth=tmpDepth;// Generate the virtual symbol name for user output
3473
+ tmpResults.PostfixTokenObjects[_i19].VirtualSymbolName="Pr_".concat(tmpVirtualParenthesisIndex,"_D_").concat(tmpDepth);// 1a. Detect if this parenthesis is signaling a function
3503
3474
  // If the previous token is a Symbol (e.g. it say sin(x) or sqrt(3+5) or something) then the parser will interpret it as a function
3504
- if(_i20>0){if(tmpResults.PostfixTokenObjects[_i20-1].Type==='Token.Symbol'){// Set the type of this to be a function
3505
- tmpResults.PostfixTokenObjects[_i20-1].Type='Token.Function';// tmpResults.PostfixTokenObjects[i-1].Descriptor = this.ExpressionParser.tokenMap[pTokenizedExpression[i-1]];
3506
- // Rename the virtual symbol n ame to include the function
3507
- // tmpResults.PostfixTokenObjects[i].VirtualSymbolName = `Fn_${tmpVirtualParenthesisIndex}_D_${tmpDepth}_${this.fable.DataFormat.cleanNonAlphaCharacters(tmpResults.PostfixTokenObjects[i-1].Token)}`;
3508
- // The function and the parenthesis are at the same depth and virtual symbol
3509
- // tmpResults.PostfixTokenObjects[i-1].VirtualSymbolName = tmpResults.PostfixTokenObjects[i].VirtualSymbolName;
3510
- }}// Parenthesis manage the solve layer stack
3475
+ if(_i19>0){if(tmpResults.PostfixTokenObjects[_i19-1].Type==='Token.Symbol'){// Set the type of this to be a function
3476
+ tmpResults.PostfixTokenObjects[_i19-1].Type='Token.Function';}}// Parenthesis manage the solve layer stack
3511
3477
  // For adding a new parenthesis solve layer, we put the parenthesis in the stack we are in and then make all the contained tokens be within the stack of the parenthesis
3512
- tmpResults.PostfixTokenObjects[_i20].SolveLayerStack=tmpSolveLayerStack[tmpSolveLayerStack.length-1];tmpSolveLayerStack.push(tmpResults.PostfixTokenObjects[_i20].VirtualSymbolName);tmpVirtualParenthesisIndex++;tmpDepth++;}// 2. If it's a closed parenthesis, decrease the depth
3513
- else if(tmpResults.PostfixTokenObjects[_i20].Token===')'){tmpDepth--;tmpResults.PostfixTokenObjects[_i20].Depth=tmpDepth;// Check to see that the depth of the closed parenthesis is greater than 0
3514
- if(tmpDepth<0){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found a closing parenthesis at token index ".concat(_i20," with no corresponding opening parenthesis."));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}// Parenthesis manage the solve layer stack
3478
+ tmpResults.PostfixTokenObjects[_i19].SolveLayerStack=tmpSolveLayerStack[tmpSolveLayerStack.length-1];tmpSolveLayerStack.push(tmpResults.PostfixTokenObjects[_i19].VirtualSymbolName);tmpVirtualParenthesisIndex++;tmpDepth++;}// 2. If it's a closed parenthesis, decrease the depth
3479
+ else if(tmpResults.PostfixTokenObjects[_i19].Token===')'){tmpDepth--;tmpResults.PostfixTokenObjects[_i19].Depth=tmpDepth;// Check to see that the depth of the closed parenthesis is greater than 0
3480
+ if(tmpDepth<0){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found a closing parenthesis at token index ".concat(_i19," with no corresponding opening parenthesis."));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}// Parenthesis manage the solve layer stack
3515
3481
  // For closing parenthesis solve layer with a close paren, we put it in the same stack as the opening parenthesis.
3516
3482
  // Give the closing parenthesis the same virtual symbol name as the opening parenthesis
3517
3483
  // (do the both above at the same time)
3518
- tmpResults.PostfixTokenObjects[_i20].VirtualSymbolName=tmpSolveLayerStack.pop();tmpResults.PostfixTokenObjects[_i20].SolveLayerStack=tmpSolveLayerStack[tmpSolveLayerStack.length-1];}// 3. If it's a state address or Symbol, set depth
3519
- // It was much more complex later on solving these as virtual symbols of their own.
3520
- // We are saving the value resolution for the very end.
3521
- else if(tmpResults.PostfixTokenObjects[_i20].Type==='Token.Symbol'){// Set the depth of the current solution depth
3522
- tmpResults.PostfixTokenObjects[_i20].Depth=tmpDepth;tmpResults.PostfixTokenObjects[_i20].SolveLayerStack=tmpSolveLayerStack[tmpSolveLayerStack.length-1];// Generate a virtual symbol name that's somewhat human readable
3523
- //tmpResults.PostfixTokenObjects[i].VirtualSymbolName = `Sm_${tmpVirtualParenthesisIndex}_D_${tmpDepth}_${this.fable.DataFormat.cleanNonAlphaCharacters(tmpResults.PostfixTokenObjects[i].Token)}`;
3524
- // We've used up this virtual symbol index so increment it
3525
- // The reason we only use these once is to make sure if we use, say, sin(x) twice at the same depth we still have unique names for each virtual solution
3526
- //tmpVirtualParenthesisIndex++;
3527
- }// 4. If it's an operator or constant or comment, just set the depth
3528
- else{tmpResults.PostfixTokenObjects[_i20].Depth=tmpDepth;tmpResults.PostfixTokenObjects[_i20].SolveLayerStack=tmpSolveLayerStack[tmpSolveLayerStack.length-1];}}// 4. Walk through the decorated symbols and generate the postfix solve list
3484
+ tmpResults.PostfixTokenObjects[_i19].VirtualSymbolName=tmpSolveLayerStack.pop();tmpResults.PostfixTokenObjects[_i19].SolveLayerStack=tmpSolveLayerStack[tmpSolveLayerStack.length-1];}else{tmpResults.PostfixTokenObjects[_i19].Depth=tmpDepth;tmpResults.PostfixTokenObjects[_i19].SolveLayerStack=tmpSolveLayerStack[tmpSolveLayerStack.length-1];}}// 4. Walk through the decorated symbols and generate the postfix solve list
3529
3485
  // We are going to start by creating a map of the solve layers:
3530
- var tmpSolveLayerMap={};var tmpSolveLayerMaxDepth=0;for(var _i21=0;_i21<tmpResults.PostfixTokenObjects.length;_i21++){if(!(tmpResults.PostfixTokenObjects[_i21].SolveLayerStack in tmpSolveLayerMap)){tmpSolveLayerMap[tmpResults.PostfixTokenObjects[_i21].SolveLayerStack]=[];}tmpSolveLayerMap[tmpResults.PostfixTokenObjects[_i21].SolveLayerStack].push(tmpResults.PostfixTokenObjects[_i21]);// See what our max depth is. This is super important to the postfix operation
3486
+ var tmpSolveLayerMap={};var tmpSolveLayerMaxDepth=0;for(var _i20=0;_i20<tmpResults.PostfixTokenObjects.length;_i20++){if(!(tmpResults.PostfixTokenObjects[_i20].SolveLayerStack in tmpSolveLayerMap)){tmpSolveLayerMap[tmpResults.PostfixTokenObjects[_i20].SolveLayerStack]=[];}tmpSolveLayerMap[tmpResults.PostfixTokenObjects[_i20].SolveLayerStack].push(tmpResults.PostfixTokenObjects[_i20]);// See what our max depth is. This is super important to the postfix operation
3531
3487
  // The programmer in me thinks it would be funny to not track this and just use the map key length as the max size, which would work (logically impossible to have a depth > key length) but it would be quite a bit more confusing to grok the algorithm.
3532
- if(tmpResults.PostfixTokenObjects[_i21].Depth>tmpSolveLayerMaxDepth){tmpSolveLayerMaxDepth=tmpResults.PostfixTokenObjects[_i21].Depth;}}var tmpSolveLayerKeys=Object.keys(tmpSolveLayerMap);// Reset the virtual symbol index -- it was used above for uniquenes when creating abstract symbols for parenthesis and layer stacks.
3488
+ if(tmpResults.PostfixTokenObjects[_i20].Depth>tmpSolveLayerMaxDepth){tmpSolveLayerMaxDepth=tmpResults.PostfixTokenObjects[_i20].Depth;}}var tmpSolveLayerKeys=Object.keys(tmpSolveLayerMap);// Reset the virtual symbol index -- it was used above for uniquenes when creating abstract symbols for parenthesis and layer stacks.
3533
3489
  var tmpVirtualSymbolIndex=0;tmpSolveLayerKeys.sort(// Sort the solve layers by depth.
3534
3490
  function(pLeftLayer,pRightLayer){// It is impossible to have a layer with no entries in it.
3535
3491
  // If that ever happens, the bug is actually above and we actively want this to blow up.
@@ -3543,68 +3499,64 @@ if(tmpSolveLayerMap[pLeftLayer][0].Depth<tmpSolveLayerMap[pRightLayer][0].Depth)
3543
3499
  tmpResults.PostfixLayerstackMap={};for(var tmpSolveLayerIndex=0;tmpSolveLayerIndex<tmpSolveLayerKeys.length;tmpSolveLayerIndex++){var tmpSolveLayerTokens=tmpSolveLayerMap[tmpSolveLayerKeys[tmpSolveLayerIndex]];// For each precedence (this isn't strictly required here but makes the outcome for the user more readable)
3544
3500
  for(var tmpPrecedence=0;tmpPrecedence<=this.ExpressionParser.tokenMaxPrecedence;tmpPrecedence++){// Enumerate all tokens in a layer's expression.
3545
3501
  // There is a recursive way to do this, but given the short length of even the most complex equations we're favoring readability.
3546
- for(var _i22=0;_i22<tmpSolveLayerTokens.length;_i22++){// If the token is an operator and at the current precedence, add it to the postfix solve list and mutate the array.
3547
- if(tmpSolveLayerTokens[_i22].Type==='Token.Operator'&&tmpSolveLayerTokens[_i22].Descriptor.Precedence===tmpPrecedence){var tmpToken=tmpSolveLayerTokens[_i22];// If there is a token and nothing else in this layer, then it's an error.
3548
- if(tmpSolveLayerTokens.length===1){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found a single operator in a solve layer expression at token index ".concat(_i22));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixSolveList;}// If the token is at the beginning of the expression and not a number line orientation modifier, it's an error.
3549
- else if(_i22==0&&(tmpToken.Token!='+'||tmpToken.Token!='-')){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found an operator at the beginning of a solve layer expression at token index ".concat(_i22));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixSolveList;}// If the token is at the end of the expression, it is an error.
3550
- else if(_i22==tmpSolveLayerTokens.length-1){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found an operator at the end of a solve layer expression at token index ".concat(_i22));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixSolveList;}// The - at the beginning of an expression is a number line orientation modifier
3551
- else if(_i22==0&&tmpToken.Token=='-'){tmpToken.VirtualSymbolName="V_".concat(tmpVirtualSymbolIndex);tmpResults.PostfixLayerstackMap[tmpToken.SolveLayerStack]=tmpToken.VirtualSymbolName;tmpVirtualSymbolIndex++;}// The - after an operator or an open parenthesis is also a number line orientation modifier
3552
- else if(_i22>0&&tmpToken.Token=='-'&&(tmpSolveLayerTokens[_i22-1].Type==='Token.Operator'||tmpSolveLayerTokens[_i22-1].Token==='(')){// The number line negation operator is a special case that generates a virtual constant (-1.0) and multiplies it by the next token
3553
- tmpToken.VirtualSymbolName="V_".concat(tmpVirtualSymbolIndex);tmpVirtualSymbolIndex++;}// The + at the beginning is also a number line orientation modifier ... THAT WE IGNORE
3554
- else if(_i22==0&&tmpToken.Token=='+'){continue;}// The + after an operator or a parenthesis is also a number line orientation modifier ... THAT WE IGNORE
3555
- else if(_i22>0&&tmpToken.Token=='+'&&(tmpSolveLayerTokens[_i22-1].Type==='Token.Operator'||tmpSolveLayerTokens[_i22-1].Token==='(')){continue;}// If the token is next to another operator it's a parsing error
3556
- else if(tmpSolveLayerTokens[_i22-1].Type==='Token.Operator'||tmpSolveLayerTokens[_i22+1].Type==='Token.Operator'){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found an operator at token index ".concat(_i22," that is not surrounded by two values."));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixSolveList;}// Finally add a virtual symbol name to the dang thing.
3557
- else{tmpToken.VirtualSymbolName="V_".concat(tmpVirtualSymbolIndex);tmpResults.PostfixLayerstackMap[tmpToken.SolveLayerStack]=tmpToken.VirtualSymbolName;tmpVirtualSymbolIndex++;}}else if(tmpSolveLayerTokens[_i22].Type==='Token.Function'&&tmpPrecedence===0){var _tmpToken=tmpSolveLayerTokens[_i22];_tmpToken.VirtualSymbolName="V_".concat(tmpVirtualSymbolIndex);tmpVirtualSymbolIndex++;tmpResults.PostfixLayerstackMap[_tmpToken.SolveLayerStack]=_tmpToken.VirtualSymbolName;}}}}// 5.2: Decorate the Parenthesis with Virtual Symbol Names
3502
+ for(var _i21=0;_i21<tmpSolveLayerTokens.length;_i21++){// If the token is an operator and at the current precedence, add it to the postfix solve list and mutate the array.
3503
+ if(tmpSolveLayerTokens[_i21].Type==='Token.Operator'&&tmpSolveLayerTokens[_i21].Descriptor.Precedence===tmpPrecedence){var tmpToken=tmpSolveLayerTokens[_i21];// If there is a token and nothing else in this layer, then it's an error.
3504
+ if(tmpSolveLayerTokens.length===1){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found a single operator in a solve layer expression at token index ".concat(_i21));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixSolveList;}// If the token is at the beginning of the expression and not a number line orientation modifier, it's an error.
3505
+ else if(_i21==0&&(tmpToken.Token!='+'||tmpToken.Token!='-')){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found an operator at the beginning of a solve layer expression at token index ".concat(_i21));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixSolveList;}// If the token is at the end of the expression, it is an error.
3506
+ else if(_i21==tmpSolveLayerTokens.length-1){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found an operator at the end of a solve layer expression at token index ".concat(_i21));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixSolveList;}// The - at the beginning of an expression is a number line orientation modifier
3507
+ else if(_i21==0&&tmpToken.Token=='-'){tmpToken.VirtualSymbolName="VNLO_".concat(tmpVirtualSymbolIndex);tmpResults.PostfixLayerstackMap[tmpToken.SolveLayerStack]=tmpToken.VirtualSymbolName;tmpVirtualSymbolIndex++;}// The - after an operator or an open parenthesis is also a number line orientation modifier
3508
+ else if(_i21>0&&tmpToken.Token=='-'&&(tmpSolveLayerTokens[_i21-1].Type==='Token.Operator'||tmpSolveLayerTokens[_i21-1].Token==='(')){// The number line negation operator is a special case that generates a virtual constant (-1.0) and multiplies it by the next token
3509
+ tmpToken.VirtualSymbolName="VNLO_".concat(tmpVirtualSymbolIndex);tmpVirtualSymbolIndex++;}// The + at the beginning is also a number line orientation modifier ... THAT WE IGNORE
3510
+ else if(_i21==0&&tmpToken.Token=='+'){continue;}// The + after an operator or a parenthesis is also a number line orientation modifier ... THAT WE IGNORE
3511
+ else if(_i21>0&&tmpToken.Token=='+'&&(tmpSolveLayerTokens[_i21-1].Type==='Token.Operator'||tmpSolveLayerTokens[_i21-1].Token==='(')){continue;}// If the token is next to another operator it's a parsing error
3512
+ else if(tmpSolveLayerTokens[_i21-1].Type==='Token.Operator'||tmpSolveLayerTokens[_i21+1].Type==='Token.Operator'){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.buildPostfixedSolveList found an operator at token index ".concat(_i21," that is not surrounded by two values."));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixSolveList;}// Finally add a virtual symbol name to the dang thing.
3513
+ else{tmpToken.VirtualSymbolName="V_".concat(tmpVirtualSymbolIndex);tmpResults.PostfixLayerstackMap[tmpToken.SolveLayerStack]=tmpToken.VirtualSymbolName;tmpVirtualSymbolIndex++;}}else if(tmpSolveLayerTokens[_i21].Type==='Token.Function'&&tmpPrecedence===0){var _tmpToken=tmpSolveLayerTokens[_i21];_tmpToken.VirtualSymbolName="VFE_".concat(tmpVirtualSymbolIndex);tmpVirtualSymbolIndex++;tmpResults.PostfixLayerstackMap[_tmpToken.SolveLayerStack]=_tmpToken.VirtualSymbolName;}}}}// 5.15 Generate Virtual Symbol Clusters for Functions and Parenthesis
3558
3514
  // ... this gets funny because of precedence of operations surrounding them, parenthesis and functions.
3559
- var tmpParenthesisCacheLIFOStack=[];for(var _i23=0;_i23<tmpResults.PostfixTokenObjects.length;_i23++){var tmpPostfixTokenObject=tmpResults.PostfixTokenObjects[_i23];if(tmpPostfixTokenObject.Type==='Token.Parenthesis'){// This is just to track the parenthesis stack level in User feedback
3560
- tmpPostfixTokenObject.ParenthesisStack=tmpPostfixTokenObject.VirtualSymbolName;if(tmpPostfixTokenObject.Token==='('){// It's an open parenthesis. If the previous token was an operator, get its precedence.
3561
- if(_i23>0){if(tmpResults.PostfixTokenObjects[_i23-1].Type==='Token.Operator'){tmpPostfixTokenObject.PreviousPrecedence=tmpResults.PostfixTokenObjects[_i23-1].Descriptor.Precedence;tmpPostfixTokenObject.IsFunction=false;tmpPostfixTokenObject.PreviousVirtualSymbolName=tmpResults.PostfixTokenObjects[_i23-1].VirtualSymbolName;tmpPostfixTokenObject.VirtualSymbolName=tmpResults.PostfixLayerstackMap[tmpPostfixTokenObject.VirtualSymbolName];}// This is a function, we will create a virtual symbol for the discrete parenthesis
3562
- else if(tmpResults.PostfixTokenObjects[_i23-1].Type==='Token.Function'){tmpPostfixTokenObject.PreviousPrecedence=0;tmpPostfixTokenObject.IsFunction=true;tmpPostfixTokenObject.PreviousVirtualSymbolName=tmpResults.PostfixTokenObjects[_i23-1].VirtualSymbolName;var tmpVirtualSymbolName=tmpResults.PostfixLayerstackMap[tmpPostfixTokenObject.VirtualSymbolName];if(!tmpVirtualSymbolName){// This is a parenthesis group with no operators in it; make a virtual symbol name.
3563
- tmpVirtualSymbolName="V_".concat(tmpVirtualSymbolIndex);tmpVirtualSymbolIndex++;}tmpPostfixTokenObject.VirtualSymbolName=tmpVirtualSymbolName;if(_i23>1){// Todo: This needs to be enhanced to deal with negations
3564
- var tmpTokenBeforeFunction=tmpResults.PostfixTokenObjects[_i23-2];if(tmpTokenBeforeFunction.Type==='Token.Operator'){tmpPostfixTokenObject.PreviousVirtualSymbolName=tmpResults.PostfixTokenObjects[_i23-2].VirtualSymbolName;tmpPostfixTokenObject.PreviousPrecedence=tmpResults.PostfixTokenObjects[_i23-2].Descriptor.Precedence;}}}}else{tmpPostfixTokenObject.VirtualSymbolName=tmpResults.PostfixLayerstackMap[tmpPostfixTokenObject.VirtualSymbolName];}tmpParenthesisCacheLIFOStack.push(tmpPostfixTokenObject);}if(tmpPostfixTokenObject.Token===')'){// There are three options for assigning this:
3565
- var tmpOpenParenthesis=tmpParenthesisCacheLIFOStack.pop();// It's at the end of the tokens -- use the stack's identifier
3566
- if(_i23>=tmpResults.PostfixTokenObjects.length-1){if(tmpOpenParenthesis.IsFunction){tmpPostfixTokenObject.VirtualSymbolName=tmpOpenParenthesis.PreviousVirtualSymbolName;}else{tmpPostfixTokenObject.VirtualSymbolName=tmpOpenParenthesis.VirtualSymbolName;}}else{// The next token is an operator and we're a function
3567
- var tmpPeekedNextToken=tmpResults.PostfixTokenObjects[_i23+1];if(tmpPeekedNextToken.Type=='Token.Operator'&&tmpOpenParenthesis.IsFunction){// This is the most complex case -- the next token is an operator AND this is a function.
3568
- // The following is just pointer math.
3569
- // If the operater is at the same precedence or higher than the open parenthesis previous operator, use the previous operator's identifier
3570
- // NOTE: This line of code is insanely complex
3571
- //tmpPostfixTokenObject.VirtualSymbolName = tmpOpenParenthesis.PreviousVirtualSymbolName;
3572
- // If the next token has higher precedence than what's before the open parenthesis, use it for the open as well
3573
- if(tmpPeekedNextToken.Descriptor.Precedence<tmpOpenParenthesis.PreviousPrecedence){tmpOpenParenthesis.VirtualSymbolName=tmpPeekedNextToken.VirtualSymbolName;tmpPostfixTokenObject.VirtualSymbolName=tmpResults.PostfixLayerstackMap[tmpPostfixTokenObject.VirtualSymbolName];}// Otherwise use this one -- it is the higher precedence. And update the previous parenthesis operator's virtual symbol to be the peeked token's virtual symbol.
3574
- else{tmpPostfixTokenObject.VirtualSymbolName=tmpOpenParenthesis.PreviousVirtualSymbolName;}}// The next token is an operator and it isn't a function
3575
- else if(tmpPeekedNextToken.Type=='Token.Operator'&&'PreviousPrecedence'in tmpOpenParenthesis){// This is the second most complex case -- the next token is an operator.
3576
- // If the operater is at the same precedence or higher than the open parenthesis previous operator, use the previous operator's identifier
3577
- // NOTE: This line of code is insanely complex
3578
- if(tmpPeekedNextToken.Descriptor.Precedence<=tmpOpenParenthesis.PreviousPrecedence){tmpPostfixTokenObject.VirtualSymbolName=tmpOpenParenthesis.PreviousVirtualSymbolName;}// Otherwise use this one -- it is the higher precedence. And update the previous parenthesis operator's virtual symbol to be the peeked token's virtual symbol.
3579
- else{tmpPostfixTokenObject.VirtualSymbolName=tmpResults.PostfixLayerstackMap[tmpPostfixTokenObject.VirtualSymbolName];tmpOpenParenthesis.VirtualSymbolName=tmpPeekedNextToken.VirtualSymbolName;}}else{// If this is a function, dereference the function's previous virtual symbol name
3580
- if(tmpOpenParenthesis.IsFunction){tmpPostfixTokenObject.VirtualSymbolName=tmpOpenParenthesis.PreviousVirtualSymbolName;}else{tmpPostfixTokenObject.VirtualSymbolName=tmpResults.PostfixLayerstackMap[tmpPostfixTokenObject.VirtualSymbolName];}}}// If there isn't an operator in the layer stack, push forward the assignment
3581
- if(!tmpResults.PostfixLayerstackMap[tmpOpenParenthesis.ParenthesisStack]){tmpResults.PostfixLayerstackMap[tmpOpenParenthesis.ParenthesisStack]=tmpOpenParenthesis.VirtualSymbolName;}}}}for(var _tmpSolveLayerIndex=0;_tmpSolveLayerIndex<tmpSolveLayerKeys.length;_tmpSolveLayerIndex++){var _tmpSolveLayerTokens=tmpSolveLayerMap[tmpSolveLayerKeys[_tmpSolveLayerIndex]];if(_tmpSolveLayerTokens.length===1){// This is just a simple value assignment -- use a simple addition virtual operation.
3582
- // We often see these inside functions.
3583
- var tmpAbstractAddToken=this.getTokenContainerObject('+');//let tmpVirtualSymbolName = tmpResults.PostfixLayerstackMap[tmpSolveLayerTokens[0].SolveLayerStack];
3584
- tmpAbstractAddToken.VirtualSymbolName=tmpResults.PostfixLayerstackMap[_tmpSolveLayerTokens[0].SolveLayerStack];tmpResults.PostfixSolveList.push(this.getPosfixSolveListOperation(tmpAbstractAddToken,this.getTokenContainerObject('0.0'),_tmpSolveLayerTokens[0]));}}// 5.3: Generate the Postfix Solve List
3585
- for(var _tmpSolveLayerIndex2=0;_tmpSolveLayerIndex2<tmpSolveLayerKeys.length;_tmpSolveLayerIndex2++){var _tmpSolveLayerTokens2=tmpSolveLayerMap[tmpSolveLayerKeys[_tmpSolveLayerIndex2]];// For each precedence level in the layer
3515
+ var tmpFunctionCacheLIFOStack=[];for(var _i22=0;_i22<tmpResults.PostfixTokenObjects.length;_i22++){var tmpPostfixTokenObject=tmpResults.PostfixTokenObjects[_i22];if(tmpPostfixTokenObject.Type==='Token.Parenthesis'){// This is just to track the parenthesis stack level for User feedback
3516
+ tmpPostfixTokenObject.ParenthesisStack=tmpPostfixTokenObject.VirtualSymbolName;// At the beginning of the expression, this must be an open parenthesis to be legal.
3517
+ if(_i22==0){tmpPostfixTokenObject.IsFunction=false;var tmpVirtualSymbolName=tmpResults.PostfixLayerstackMap[tmpPostfixTokenObject.VirtualSymbolName];if(!tmpVirtualSymbolName){// ... this parenthesis group has no operators in it; make a virtual symbol name.
3518
+ tmpVirtualSymbolName="VP_".concat(tmpVirtualSymbolIndex);tmpVirtualSymbolIndex++;}tmpPostfixTokenObject.VirtualSymbolName=tmpVirtualSymbolName;tmpFunctionCacheLIFOStack.push(tmpPostfixTokenObject);}// If it's an open parenthesis
3519
+ else if(tmpPostfixTokenObject.Token==='('){// ... supporting a function
3520
+ if(tmpResults.PostfixTokenObjects[_i22-1].Type==='Token.Function'){tmpPostfixTokenObject.IsFunction=true;tmpPostfixTokenObject.Function=tmpResults.PostfixTokenObjects[_i22-1];var _tmpVirtualSymbolName=tmpResults.PostfixLayerstackMap[tmpPostfixTokenObject.VirtualSymbolName];if(!_tmpVirtualSymbolName){// ... this parenthesis group has no operators in it; make a virtual symbol name.
3521
+ _tmpVirtualSymbolName="VFP_".concat(tmpVirtualSymbolIndex);tmpVirtualSymbolIndex++;}tmpPostfixTokenObject.VirtualSymbolName=_tmpVirtualSymbolName;}else{tmpPostfixTokenObject.IsFunction=false;var _tmpVirtualSymbolName2=tmpResults.PostfixLayerstackMap[tmpPostfixTokenObject.VirtualSymbolName];if(!_tmpVirtualSymbolName2){// This is a parenthesis group with no operators in it; make a virtual symbol name.
3522
+ _tmpVirtualSymbolName2="VP_".concat(tmpVirtualSymbolIndex);tmpVirtualSymbolIndex++;}tmpPostfixTokenObject.VirtualSymbolName=_tmpVirtualSymbolName2;}tmpFunctionCacheLIFOStack.push(tmpPostfixTokenObject);}if(tmpPostfixTokenObject.Token===')'){var tmpOpenParenthesis=tmpFunctionCacheLIFOStack.pop();if(tmpOpenParenthesis.IsFunction){tmpPostfixTokenObject.IsFunction=true;tmpPostfixTokenObject.VirtualSymbolName=tmpOpenParenthesis.Function.VirtualSymbolName;}else{tmpPostfixTokenObject.IsFunction=false;tmpPostfixTokenObject.VirtualSymbolName=tmpOpenParenthesis.VirtualSymbolName;}}}}// X. Postprocess the parenthesis groups to ensure they respect the order of operations for their boundaries
3523
+ for(var _tmpSolveLayerIndex=0;_tmpSolveLayerIndex<tmpSolveLayerKeys.length;_tmpSolveLayerIndex++){var tmpParenthesisStack=[];var tmpLastOperator=false;var _tmpSolveLayerTokens=tmpSolveLayerMap[tmpSolveLayerKeys[_tmpSolveLayerIndex]];for(var _i23=0;_i23<_tmpSolveLayerTokens.length;_i23++){var _tmpPostfixTokenObject=_tmpSolveLayerTokens[_i23];// Keep track of the last operator
3524
+ if(_tmpPostfixTokenObject.Type==='Token.Operator'){tmpLastOperator=_tmpPostfixTokenObject;}// This is only important to do at the close parenthesis.
3525
+ if(_tmpPostfixTokenObject.Type==='Token.Function'){_tmpPostfixTokenObject.PreviousOperator=tmpLastOperator;}else if(_tmpPostfixTokenObject.Type==='Token.Parenthesis'&&_tmpPostfixTokenObject.Token==='('&&_tmpPostfixTokenObject.IsFunction){tmpParenthesisStack.push(_tmpPostfixTokenObject);if(_tmpPostfixTokenObject.Function.PreviousOperator){_tmpPostfixTokenObject.PreviousOperator=_tmpPostfixTokenObject.Function.PreviousOperator;}}else if(_tmpPostfixTokenObject.Type==='Token.Parenthesis'&&_tmpPostfixTokenObject.Token==='('){_tmpPostfixTokenObject.PreviousOperator=tmpLastOperator;tmpParenthesisStack.push(_tmpPostfixTokenObject);}else if(_tmpPostfixTokenObject.Type==='Token.Parenthesis'&&_tmpPostfixTokenObject.Token===')'){// This is ultra complex, and binds the order of operations logic to the open parenthesis for the group
3526
+ var _tmpOpenParenthesis=tmpParenthesisStack.pop();if(_i23<_tmpSolveLayerTokens.length-1){for(var j=_i23+1;j<_tmpSolveLayerTokens.length;j++){if(_tmpSolveLayerTokens[j].Type==='Token.Operator'){_tmpOpenParenthesis.NextOperator=_tmpSolveLayerTokens[j];break;}}}if(_tmpOpenParenthesis.PreviousOperator&&_tmpOpenParenthesis.NextOperator){if(_tmpOpenParenthesis.PreviousOperator.Descriptor.Precedence<=_tmpOpenParenthesis.NextOperator.Descriptor.Precedence){_tmpOpenParenthesis.NextOperator.LeftVirtualSymbolName=_tmpOpenParenthesis.PreviousOperator.VirtualSymbolName;}else{_tmpOpenParenthesis.PreviousOperator.RightVirtualSymbolName=_tmpOpenParenthesis.NextOperator.VirtualSymbolName;}}}else{if(!('SolveLayerStack'in _tmpPostfixTokenObject)){// Decorate the solve layer stack for the token
3527
+ if(tmpParenthesisStack.length>0){_tmpPostfixTokenObject.SolveLayerStack=tmpParenthesisStack[tmpParenthesisStack.length-1].SolveLayerStack;}else{_tmpPostfixTokenObject.SolveLayerStack='Expression_Root';}}}}}// 5.2.9: Make sure the affinity of operators is respecting order of operations.
3528
+ // Walk backwards and forwards, hoisting same value precedence backwards/forwards
3529
+ // across each layer... the precedence change needs to be decreasing to matter
3530
+ for(var _tmpSolveLayerIndex2=0;_tmpSolveLayerIndex2<tmpSolveLayerKeys.length;_tmpSolveLayerIndex2++){var tmpLastPrecedence=false;var tmpFinalChainToken=false;var _tmpSolveLayerTokens2=tmpSolveLayerMap[tmpSolveLayerKeys[_tmpSolveLayerIndex2]];for(var _i24=_tmpSolveLayerTokens2.length-1;_i24>=0;_i24--){var _tmpToken2=_tmpSolveLayerTokens2[_i24];if(_tmpToken2.Type==='Token.Operator'){if(!tmpFinalChainToken){tmpFinalChainToken=_tmpToken2;}else if(_tmpToken2.Descriptor.Precedence>tmpLastPrecedence){// This is less imporant than the last precedence, so hoist back the virtual value
3531
+ _tmpToken2.RightVirtualSymbolName=tmpFinalChainToken.VirtualSymbolName;//console.log(`Hoisting ${tmpToken.Token} back to ${tmpFinalChainToken.Token}`);
3532
+ tmpFinalChainToken=_tmpToken2;}else if(_tmpToken2.Descriptor.Precedence<tmpLastPrecedence){tmpFinalChainToken=_tmpToken2;}tmpLastPrecedence=_tmpToken2.Descriptor.Precedence;}}var tmpDecreasingPrecedenceStack=[];var tmpLastToken=false;for(var _i25=_tmpSolveLayerTokens2.length-1;_i25>=0;_i25--){var _tmpToken3=_tmpSolveLayerTokens2[_i25];if(_tmpToken3.Type==='Token.Operator'){if(!tmpLastToken){tmpLastToken=_tmpToken3;}else if(_tmpToken3.Descriptor.Precedence>tmpLastPrecedence){// Check and see if this needs to be resolved in the stack
3533
+ if(tmpDecreasingPrecedenceStack.length>0){for(var _j=tmpDecreasingPrecedenceStack.length-1;_j>=0;_j--){if(tmpDecreasingPrecedenceStack[_j].Descriptor.Precedence>=_tmpToken3.Descriptor.Precedence){//console.log(`Hoisting ${tmpDecreasingPrecedenceStack[j].Token} up to ${tmpToken.Token}`);
3534
+ tmpDecreasingPrecedenceStack[_j].LeftVirtualSymbolName=_tmpToken3.VirtualSymbolName;tmpDecreasingPrecedenceStack.slice(_j,1);break;}}}tmpLastToken=_tmpToken3;}else if(_tmpToken3.Descriptor.Precedence<tmpLastPrecedence){tmpDecreasingPrecedenceStack.push(tmpLastToken);tmpLastToken=_tmpToken3;}tmpLastPrecedence=_tmpToken3.Descriptor.Precedence;}}}// 5.3: Generate the Postfix Solve List
3535
+ for(var _tmpSolveLayerIndex3=0;_tmpSolveLayerIndex3<tmpSolveLayerKeys.length;_tmpSolveLayerIndex3++){var _tmpSolveLayerTokens3=tmpSolveLayerMap[tmpSolveLayerKeys[_tmpSolveLayerIndex3]];// If this is a layer with one value, presume it's an assignment.
3536
+ if(_tmpSolveLayerTokens3.length===1){var tmpAbstractMultiplyToken=this.getTokenContainerObject('*');tmpAbstractMultiplyToken.VirtualSymbolName=tmpResults.PostfixLayerstackMap[_tmpSolveLayerTokens3[0].SolveLayerStack];// If this doesn't have a matching solvelayerstack, get the virtual symbol name from the parenthesis group it's in
3537
+ if(!tmpAbstractMultiplyToken.VirtualSymbolName){for(var _i26=0;_i26<tmpResults.PostfixTokenObjects.length;_i26++){if(tmpResults.PostfixTokenObjects[_i26].ParenthesisStack===_tmpSolveLayerTokens3[0].SolveLayerStack){tmpAbstractMultiplyToken.VirtualSymbolName=tmpResults.PostfixTokenObjects[_i26].VirtualSymbolName;break;}}}tmpResults.PostfixSolveList.push(this.getPosfixSolveListOperation(tmpAbstractMultiplyToken,this.getTokenContainerObject('1.0'),_tmpSolveLayerTokens3[0]));continue;}// For each precedence level in the layer
3586
3538
  for(var _tmpPrecedence=0;_tmpPrecedence<=this.ExpressionParser.tokenMaxPrecedence;_tmpPrecedence++){// Enumerate all tokens in a layer's expression.
3587
3539
  // There is a recursive way to do this, but given the short length of even the most complex equations we're favoring readability.
3588
- for(var _i24=0;_i24<_tmpSolveLayerTokens2.length;_i24++){// If the token is an operator and at the current precedence, add it to the postfix solve list and mutate the array.
3589
- if(_tmpSolveLayerTokens2[_i24].Type==='Token.Operator'&&_tmpSolveLayerTokens2[_i24].Descriptor.Precedence===_tmpPrecedence){var _tmpToken2=_tmpSolveLayerTokens2[_i24];// The - at the beginning of an expression is a number line orientation modifier
3590
- if(_i24==0&&_tmpToken2.Token=='-'){// The number line negation operator is a special case that generates a virtual constant (-1.0) and multiplies it by the next token
3540
+ for(var _i27=0;_i27<_tmpSolveLayerTokens3.length;_i27++){// If the token is an operator and at the current precedence, add it to the postfix solve list and mutate the array.
3541
+ if(_tmpSolveLayerTokens3[_i27].Type==='Token.Operator'&&_tmpSolveLayerTokens3[_i27].Descriptor.Precedence===_tmpPrecedence){var _tmpToken4=_tmpSolveLayerTokens3[_i27];// The - at the beginning of an expression is a number line orientation modifier
3542
+ if(_i27==0&&_tmpToken4.Token=='-'){// The number line negation operator is a special case that generates a virtual constant (-1.0) and multiplies it by the next token
3591
3543
  // This is an abstract operation that isn't in the expression.
3592
- var tmpAbstractMultiplyToken=this.getTokenContianerObject('*');tmpAbstractMultiplyToken.VirtualSymbolName=_tmpToken2.VirtualSymbolName;tmpResults.PostfixSolveList.push(this.getPosfixSolveListOperation(tmpAbstractMultiplyToken,this.getTokenContainerObject('-1.0'),_tmpSolveLayerTokens2[_i24+1]));}// The - after an operator or an open parenthesis is also a number line orientation modifier
3593
- else if(_i24>0&&_tmpToken2.Token=='-'&&(_tmpSolveLayerTokens2[_i24-1].Type==='Token.Operator'||_tmpSolveLayerTokens2[_i24-1].Token==='(')){// The number line negation operator is a special case that generates a virtual constant (-1.0) and multiplies it by the next token
3594
- var _tmpAbstractMultiplyToken=this.getTokenContianerObject('*');_tmpAbstractMultiplyToken.VirtualSymbolName=_tmpToken2.VirtualSymbolName;tmpResults.PostfixSolveList.push(this.getPosfixSolveListOperation(_tmpAbstractMultiplyToken,this.getTokenContainerObject('-1.0'),_tmpSolveLayerTokens2[_i24+1]));}// The + at the beginning is also a number line orientation modifier ... THAT WE IGNORE
3595
- else if(_i24==0&&_tmpToken2.Token=='+'){continue;}// The + after an operator or a parenthesis is also a number line orientation modifier ... THAT WE IGNORE
3596
- else if(_i24>0&&_tmpToken2.Token=='+'&&(_tmpSolveLayerTokens2[_i24-1].Type==='Token.Operator'||_tmpSolveLayerTokens2[_i24-1].Token==='(')){continue;}// Finally add the dang thing.
3597
- else{tmpResults.PostfixSolveList.push(this.getPosfixSolveListOperation(_tmpToken2,_tmpSolveLayerTokens2[_i24-1],_tmpSolveLayerTokens2[_i24+1],_tmpSolveLayerTokens2,_i24));}}else if(_tmpSolveLayerTokens2[_i24].Type==='Token.Function'&&_tmpPrecedence===0){var _tmpToken3=_tmpSolveLayerTokens2[_i24];// Not sure what to do with the other token.
3598
- tmpResults.PostfixSolveList.push(this.getPosfixSolveListOperation(_tmpToken3,_tmpSolveLayerTokens2[_i24+1],this.getTokenContainerObject('0.0')));}}}}// Now set the assignment address.
3544
+ var _tmpAbstractMultiplyToken=this.getTokenContainerObject('*');_tmpAbstractMultiplyToken.VirtualSymbolName=_tmpToken4.VirtualSymbolName;tmpResults.PostfixSolveList.push(this.getPosfixSolveListOperation(_tmpAbstractMultiplyToken,this.getTokenContainerObject('-1.0'),_tmpSolveLayerTokens3[_i27+1]));}// The - after an operator or an open parenthesis is also a number line orientation modifier
3545
+ else if(_i27>0&&_tmpToken4.Token=='-'&&(_tmpSolveLayerTokens3[_i27-1].Type==='Token.Operator'||_tmpSolveLayerTokens3[_i27-1].Token==='(')){// The number line negation operator is a special case that generates a virtual constant (-1.0) and multiplies it by the next token
3546
+ var _tmpAbstractMultiplyToken2=this.getTokenContainerObject('*');_tmpAbstractMultiplyToken2.VirtualSymbolName=_tmpToken4.VirtualSymbolName;tmpResults.PostfixSolveList.push(this.getPosfixSolveListOperation(_tmpAbstractMultiplyToken2,this.getTokenContainerObject('-1.0'),_tmpSolveLayerTokens3[_i27+1]));}// The + at the beginning is also a number line orientation modifier ... THAT WE IGNORE
3547
+ else if(_i27==0&&_tmpToken4.Token=='+'){continue;}// The + after an operator or a parenthesis is also a number line orientation modifier ... THAT WE IGNORE
3548
+ else if(_i27>0&&_tmpToken4.Token=='+'&&(_tmpSolveLayerTokens3[_i27-1].Type==='Token.Operator'||_tmpSolveLayerTokens3[_i27-1].Token==='(')){continue;}// Finally add the dang thing.
3549
+ else{tmpResults.PostfixSolveList.push(this.getPosfixSolveListOperation(_tmpToken4,_tmpSolveLayerTokens3[_i27-1],_tmpSolveLayerTokens3[_i27+1],_tmpSolveLayerTokens3,_i27));}}else if(_tmpSolveLayerTokens3[_i27].Type==='Token.Function'&&_tmpPrecedence===0){var _tmpToken5=_tmpSolveLayerTokens3[_i27];tmpResults.PostfixSolveList.push(this.getPosfixSolveListOperation(_tmpToken5,_tmpSolveLayerTokens3[_i27+1],this.getTokenContainerObject('0.0')));}}}}// 7. Lastly set the assignment address.
3599
3550
  var tmpAssignmentInstruction=this.getPosfixSolveListOperation(this.getTokenContainerObject('Assign','Token.SolverInstruction'),this.getTokenContainerObject('DestinationHash','Token.SolverInstruction'),this.getTokenContainerObject('Resulting','Token.SolverInstruction'));tmpAssignmentInstruction.VirtualSymbolName=tmpResults.PostfixedAssignmentAddress;tmpResults.PostfixSolveList.push(tmpAssignmentInstruction);return tmpResults.PostfixSolveList;}}]);return ExpressionParserPostfix;}(libExpressionParserOperationBase);module.exports=ExpressionParserPostfix;},{"./Fable-Service-ExpressionParser-Base.js":136}],141:[function(require,module,exports){var libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');var ExpressionParserSolver=/*#__PURE__*/function(_libExpressionParserO4){_inherits(ExpressionParserSolver,_libExpressionParserO4);function ExpressionParserSolver(pFable,pOptions,pServiceHash){var _this29;_classCallCheck2(this,ExpressionParserSolver);_this29=_callSuper(this,ExpressionParserSolver,[pFable,pOptions,pServiceHash]);_this29.serviceType='ExpressionParser-Solver';return _this29;}_createClass2(ExpressionParserSolver,[{key:"solvePostfixedExpression",value:function solvePostfixedExpression(pPostfixedExpression,pDataDestinationObject,pResultObject,pManifest){var tmpResults=_typeof(pResultObject)==='object'?pResultObject:{ExpressionParserLog:[]};var tmpManifest=_typeof(pManifest)==='object'?pManifest:this.fable.newManyfest();var tmpDataDestinationObject=_typeof(pDataDestinationObject)==='object'?pDataDestinationObject:{};// If there was a fable passed in (e.g. the results object was a service or such), we won't decorate
3600
3551
  var tmpPassedInFable=('fable'in tmpResults);if(!tmpPassedInFable){tmpResults.fable=this.fable;}if(!Array.isArray(pPostfixedExpression)){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.solvePostfixedExpression was passed a non-array postfixed expression.");this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return false;}if(pPostfixedExpression.length<1){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.solvePostfixedExpression was passed an empty postfixed expression.");this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return false;}// This is how the user communication magic happens.
3601
3552
  tmpResults.VirtualSymbols={};for(var i=0;i<pPostfixedExpression.length;i++){if(pPostfixedExpression[i].Operation.Type==='Token.SolverInstruction'){continue;}var tmpStepResultObject={ExpressionStep:pPostfixedExpression[i],ExpressionStepIndex:i,ResultsObject:tmpResults,Manifest:tmpManifest};// Resolve the virtual symbols to their actual values
3602
3553
  if(tmpStepResultObject.ExpressionStep.LeftValue.Type==='Token.VirtualSymbol'){tmpStepResultObject.ExpressionStep.LeftValue.Value=tmpManifest.getValueAtAddress(tmpResults.VirtualSymbols,tmpStepResultObject.ExpressionStep.LeftValue.Token);}if(tmpStepResultObject.ExpressionStep.RightValue.Type==='Token.VirtualSymbol'){tmpStepResultObject.ExpressionStep.RightValue.Value=tmpManifest.getValueAtAddress(tmpResults.VirtualSymbols,tmpStepResultObject.ExpressionStep.RightValue.Token);}// Resolve the parenthesis to their actual values
3603
- if(tmpStepResultObject.ExpressionStep.LeftValue.Type==='Token.Parenthesis'){tmpStepResultObject.ExpressionStep.LeftValue.Value=tmpManifest.getValueAtAddress(tmpResults.VirtualSymbols,tmpStepResultObject.ExpressionStep.LeftValue.VirtualSymbolName);}if(tmpStepResultObject.ExpressionStep.RightValue.Type==='Token.Parenthesis'){tmpStepResultObject.ExpressionStep.RightValue.Value=tmpManifest.getValueAtAddress(tmpResults.VirtualSymbols,tmpStepResultObject.ExpressionStep.RightValue.VirtualSymbolName);}if(tmpStepResultObject.ExpressionStep.Operation.Type='Operator'){// TODO: This can be optimized. A lot. If necessary. Seems pretty fast honestly for even thousands of operations. Slowest part is arbitrary precision.
3554
+ if(tmpStepResultObject.ExpressionStep.LeftValue.Type==='Token.Parenthesis'){tmpStepResultObject.ExpressionStep.LeftValue.Value=tmpManifest.getValueAtAddress(tmpResults.VirtualSymbols,tmpStepResultObject.ExpressionStep.LeftValue.VirtualSymbolName);}if(tmpStepResultObject.ExpressionStep.RightValue.Type==='Token.Parenthesis'){tmpStepResultObject.ExpressionStep.RightValue.Value=tmpManifest.getValueAtAddress(tmpResults.VirtualSymbols,tmpStepResultObject.ExpressionStep.RightValue.VirtualSymbolName);}// Virtual Constants
3555
+ if(tmpStepResultObject.ExpressionStep.LeftValue.Type==='Token.Constant'&&!('Value'in tmpStepResultObject.ExpressionStep.LeftValue)){tmpStepResultObject.ExpressionStep.LeftValue.Value=tmpStepResultObject.ExpressionStep.LeftValue.Token;}if(tmpStepResultObject.ExpressionStep.RightValue.Type==='Token.Constant'&&!('Value'in tmpStepResultObject.ExpressionStep.RightValue)){tmpStepResultObject.ExpressionStep.RightValue.Value=tmpStepResultObject.ExpressionStep.RightValue.Token;}if(tmpStepResultObject.ExpressionStep.Operation.Type='Operator'){// TODO: This can be optimized. A lot. If necessary. Seems pretty fast honestly for even thousands of operations. Slowest part is arbitrary precision.
3604
3556
  // An operator always has a left and right value.
3605
3557
  var tmpFunctionAddress=false;if(tmpStepResultObject.ExpressionStep.Operation.Token in this.ExpressionParser.tokenMap){tmpFunctionAddress="ResultsObject.".concat(tmpStepResultObject.ExpressionStep.Operation.Descriptor.Function);}else if(tmpStepResultObject.ExpressionStep.Operation.Token.toLowerCase()in this.ExpressionParser.functionMap){tmpFunctionAddress="ResultsObject.".concat(this.ExpressionParser.functionMap[tmpStepResultObject.ExpressionStep.Operation.Token.toLowerCase()].Address);}try{this.log.trace("Solving Step ".concat(i," [").concat(tmpStepResultObject.ExpressionStep.VirtualSymbolName,"] --> [").concat(tmpStepResultObject.ExpressionStep.Operation.Token,"]: ( ").concat(tmpStepResultObject.ExpressionStep.LeftValue.Value," , ").concat(tmpStepResultObject.ExpressionStep.RightValue.Value," )"));tmpResults.VirtualSymbols[tmpStepResultObject.ExpressionStep.VirtualSymbolName]=tmpManifest.getValueAtAddress(tmpStepResultObject,"".concat(tmpFunctionAddress,"(ExpressionStep.LeftValue.Value,ExpressionStep.RightValue.Value)"));this.log.trace(" ---> Step ".concat(i,": ").concat(tmpResults.VirtualSymbols[tmpStepResultObject.ExpressionStep.VirtualSymbolName]));}catch(pError){tmpResults.ExpressionParserLog.push("ERROR: ExpressionParser.solvePostfixedExpression failed to solve step ".concat(i," with function ").concat(tmpStepResultObject.ExpressionStep.Operation.Token,"."));this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return false;}// Equations don't always solve in virtual symbol order.
3606
3558
  tmpResults.SolverFinalVirtualSymbol=tmpStepResultObject.ExpressionStep.VirtualSymbolName;}}var tmpSolverResultValue=tmpManifest.getValueAtAddress(tmpResults,"VirtualSymbols.".concat(tmpResults.SolverFinalVirtualSymbol));// Now deal with final assignment
3607
- for(var _i25=0;_i25<pPostfixedExpression.length;_i25++){if(pPostfixedExpression[_i25].Operation.Type==='Token.SolverInstruction'&&pPostfixedExpression[_i25].Operation.Token=='Assign'){tmpManifest.setValueAtAddress(tmpResults.VirtualSymbols,pPostfixedExpression[_i25].VirtualSymbolName,tmpSolverResultValue);tmpManifest.setValueByHash(tmpDataDestinationObject,pPostfixedExpression[_i25].VirtualSymbolName,tmpSolverResultValue);}}// Clean up the reference if we added it to the object.
3559
+ for(var _i28=0;_i28<pPostfixedExpression.length;_i28++){if(pPostfixedExpression[_i28].Operation.Type==='Token.SolverInstruction'&&pPostfixedExpression[_i28].Operation.Token=='Assign'){tmpManifest.setValueAtAddress(tmpResults.VirtualSymbols,pPostfixedExpression[_i28].VirtualSymbolName,tmpSolverResultValue);tmpManifest.setValueByHash(tmpDataDestinationObject,pPostfixedExpression[_i28].VirtualSymbolName,tmpSolverResultValue);}}// Clean up the reference if we added it to the object.
3608
3560
  if(!tmpPassedInFable){delete tmpResults.fable;}return tmpSolverResultValue.toString();}}]);return ExpressionParserSolver;}(libExpressionParserOperationBase);module.exports=ExpressionParserSolver;},{"./Fable-Service-ExpressionParser-Base.js":136}],142:[function(require,module,exports){module.exports={"=":{"Name":"Equals","Token":"=","Precedence":0,"Type":"Assignment"},"(":{"Name":"Left Parenthesis","Token":"(","Precedence":0,"Type":"Parenthesis"},")":{"Name":"Right Parenthesis","Token":")","Precedence":0,"Type":"Parenthesis"},"*":{"Name":"Multiply","Token":"*","Function":"fable.Math.multiplyPrecise","Precedence":3,"Type":"Operator"},"/":{"Name":"Divide","Token":"/","Function":"fable.Math.dividePrecise","Precedence":3,"Type":"Operator"},"^":{"Name":"Exponent","Token":"^","Function":"fable.Math.powerPrecise","Precedence":1,"Type":"Operator"},"%":{"Name":"Modulus","Token":"%","Function":"fable.Math.modPrecise","Precedence":3,"Type":"Operator"},"+":{"Name":"Add","Token":"+","Function":"fable.Math.addPrecise","Precedence":4,"Type":"Operator"},"-":{"Name":"Subtract","Token":"-","Function":"fable.Math.subtractPrecise","Precedence":4,"Type":"Operator"}};},{}],143:[function(require,module,exports){(function(process){(function(){var libFableServiceBase=require('fable-serviceproviderbase');var libFS=require('fs');var libPath=require('path');var libReadline=require('readline');var FableServiceFilePersistence=/*#__PURE__*/function(_libFableServiceBase5){_inherits(FableServiceFilePersistence,_libFableServiceBase5);function FableServiceFilePersistence(pFable,pOptions,pServiceHash){var _this30;_classCallCheck2(this,FableServiceFilePersistence);_this30=_callSuper(this,FableServiceFilePersistence,[pFable,pOptions,pServiceHash]);_this30.serviceType='FilePersistence';if(!('Mode'in _this30.options)){_this30.options.Mode=parseInt('0777',8)&~process.umask();}_this30.libFS=libFS;_this30.libPath=libPath;_this30.libReadline=libReadline;return _this30;}_createClass2(FableServiceFilePersistence,[{key:"joinPath",value:function joinPath(){return libPath.resolve.apply(libPath,arguments);}},{key:"existsSync",value:function existsSync(pPath){return libFS.existsSync(pPath);}},{key:"exists",value:function exists(pPath,fCallback){var tmpFileExists=this.existsSync(pPath);;return fCallback(null,tmpFileExists);}},{key:"appendFileSync",value:function appendFileSync(pFileName,pAppendContent,pOptions){var tmpOptions=typeof pOptions==='undefined'?'utf8':pOptions;return libFS.appendFileSync(pFileName,pAppendContent,tmpOptions);}},{key:"deleteFileSync",value:function deleteFileSync(pFileName){return libFS.unlinkSync(pFileName);}},{key:"deleteFolderSync",value:function deleteFolderSync(pFileName){return libFS.rmdirSync(pFileName);}},{key:"readFileSync",value:function readFileSync(pFilePath,pOptions){var tmpOptions=typeof pOptions==='undefined'?'utf8':pOptions;return libFS.readFileSync(pFilePath,tmpOptions);}},{key:"readFile",value:function readFile(pFilePath,pOptions,fCallback){var tmpOptions=typeof pOptions==='undefined'?'utf8':pOptions;return libFS.readFile(pFilePath,tmpOptions,fCallback);}},{key:"writeFileSync",value:function writeFileSync(pFileName,pFileContent,pOptions){var tmpOptions=typeof pOptions==='undefined'?'utf8':pOptions;return libFS.writeFileSync(pFileName,pFileContent,tmpOptions);}},{key:"writeFileSyncFromObject",value:function writeFileSyncFromObject(pFileName,pObject){return this.writeFileSync(pFileName,JSON.stringify(pObject,null,4));}},{key:"writeFileSyncFromArray",value:function writeFileSyncFromArray(pFileName,pFileArray){if(!Array.isArray(pFileArray)){this.log.error("File Persistence Service attempted to write ".concat(pFileName," from array but the expected array was not an array (it was a ").concat(_typeof(pFileArray),")."));return Error('Attempted to write ${pFileName} from array but the expected array was not an array (it was a ${typeof(pFileArray)}).');}else{for(var i=0;i<pFileArray.length;i++){return this.appendFileSync(pFileName,"".concat(pFileArray[i],"\n"));}}}},{key:"writeFile",value:function writeFile(pFileName,pFileContent,pOptions,fCallback){var tmpOptions=typeof pOptions==='undefined'?'utf8':pOptions;return libFS.writeFile(pFileName,pFileContent,tmpOptions,fCallback);}},{key:"lineReaderFactory",value:function lineReaderFactory(pFilePath,fOnLine,fOnComplete,fOnError){var tmpLineReader={};if(typeof pFilePath!='string'){return false;}tmpLineReader.filePath=pFilePath;tmpLineReader.fileStream=libFS.createReadStream(tmpLineReader.filePath);tmpLineReader.reader=libReadline.createInterface({input:tmpLineReader.fileStream,crlfDelay:Infinity});if(typeof fOnError==='function'){tmpLineReader.reader.on('error',fOnError);}tmpLineReader.reader.on('line',typeof fOnLine==='function'?fOnLine:function(){});if(typeof fOnComplete==='function'){tmpLineReader.reader.on('close',fOnComplete);}return tmpLineReader;}// Folder management
3609
3561
  },{key:"makeFolderRecursive",value:function makeFolderRecursive(pParameters,fCallback){var _this31=this;var tmpParameters=pParameters;if(typeof pParameters=='string'){tmpParameters={Path:pParameters};}else if(_typeof(pParameters)!=='object'){fCallback(new Error('Parameters object or string not properly passed to recursive folder create.'));return false;}if(typeof tmpParameters.Path!=='string'){fCallback(new Error('Parameters object needs a path to run the folder create operation.'));return false;}if(!('Mode'in tmpParameters)){tmpParameters.Mode=this.options.Mode;}// Check if we are just starting .. if so, build the initial state for our recursive function
3610
3562
  if(typeof tmpParameters.CurrentPathIndex==='undefined'){// Build the tools to start recursing
@@ -3730,7 +3682,7 @@ return fCallback();}/**
3730
3682
  */},{key:"parseString",value:function parseString(pString,pParseTree,pData,fCallback,pDataContext){var _this35=this;// TODO: There is danger here if a template function attempts to functionally recurse and doesn't pass this in.
3731
3683
  var tmpPreviousDataContext=Array.isArray(pDataContext)?pDataContext:[];var tmpDataContext=Array.from(tmpPreviousDataContext);tmpDataContext.push(pData);if(typeof fCallback!=='function'){var tmpParserState=this.newParserState(pParseTree);for(var i=0;i<pString.length;i++){// TODO: This is not fast.
3732
3684
  this.parseCharacter(pString[i],tmpParserState,pData,tmpDataContext);}this.flushOutputBuffer(tmpParserState);return tmpParserState.Output;}else{// This is the async mode
3733
- var _tmpParserState=this.newParserState(pParseTree);_tmpParserState.Asynchronous=true;var tmpAnticipate=this.fable.instantiateServiceProviderWithoutRegistration('Anticipate');var _loop=function _loop(_i26){tmpAnticipate.anticipate(function(fCallback){_this35.parseCharacterAsync(pString[_i26],_tmpParserState,pData,fCallback,tmpDataContext);});};for(var _i26=0;_i26<pString.length;_i26++){_loop(_i26);}tmpAnticipate.wait(function(pError){// Flush the remaining data
3685
+ var _tmpParserState=this.newParserState(pParseTree);_tmpParserState.Asynchronous=true;var tmpAnticipate=this.fable.instantiateServiceProviderWithoutRegistration('Anticipate');var _loop=function _loop(_i29){tmpAnticipate.anticipate(function(fCallback){_this35.parseCharacterAsync(pString[_i29],_tmpParserState,pData,fCallback,tmpDataContext);});};for(var _i29=0;_i29<pString.length;_i29++){_loop(_i29);}tmpAnticipate.wait(function(pError){// Flush the remaining data
3734
3686
  _this35.flushOutputBuffer(_tmpParserState);return fCallback(pError,_tmpParserState.Output);});}}}]);return StringParser;}();module.exports=StringParser;},{}],147:[function(require,module,exports){/**
3735
3687
  * Word Tree
3736
3688
  * @author Steven Velozo <steven@velozo.com>
@@ -3760,7 +3712,7 @@ _this35.flushOutputBuffer(_tmpParserState);return fCallback(pError,_tmpParserSta
3760
3712
  * @param {Object} pParserContext - The context to pass to the parser function
3761
3713
  * @return {Object} The leaf parser from the tree
3762
3714
  */},{key:"addPatternBoth",value:function addPatternBoth(pPatternStart,pPatternEnd,fParser,fParserAsync,pParserContext){if(pPatternStart.length<1){return false;}if(typeof pPatternEnd==='string'&&pPatternEnd.length<1){return false;}var tmpLeaf=this.ParseTree;// Add the tree of leaves iteratively
3763
- for(var i=0;i<pPatternStart.length;i++){tmpLeaf=this.addChild(tmpLeaf,pPatternStart[i],i);}if(!('PatternEnd'in tmpLeaf)){tmpLeaf.PatternEnd={};}var tmpPatternEnd=typeof pPatternEnd==='string'?pPatternEnd:pPatternStart;for(var _i27=0;_i27<tmpPatternEnd.length;_i27++){tmpLeaf=this.addEndChild(tmpLeaf,tmpPatternEnd[_i27],_i27);}tmpLeaf.PatternStartString=pPatternStart;tmpLeaf.PatternEndString=tmpPatternEnd;tmpLeaf.Parse=typeof fParser==='function'?fParser:typeof fParser==='string'?function(pHash,pData){return fParser;}:function(pHash,pData){return pHash;};tmpLeaf.ParseAsync=typeof fParserAsync==='function'?fParserAsync:typeof fParserAsync==='string'?function(pHash,pData,fCallback){return fCallback(null,fParserAsync);}:function(pHash,pData,fCallback){return fCallback(null,tmpLeaf.Parse(pHash,pData));};// A "this" for every object
3715
+ for(var i=0;i<pPatternStart.length;i++){tmpLeaf=this.addChild(tmpLeaf,pPatternStart[i],i);}if(!('PatternEnd'in tmpLeaf)){tmpLeaf.PatternEnd={};}var tmpPatternEnd=typeof pPatternEnd==='string'?pPatternEnd:pPatternStart;for(var _i30=0;_i30<tmpPatternEnd.length;_i30++){tmpLeaf=this.addEndChild(tmpLeaf,tmpPatternEnd[_i30],_i30);}tmpLeaf.PatternStartString=pPatternStart;tmpLeaf.PatternEndString=tmpPatternEnd;tmpLeaf.Parse=typeof fParser==='function'?fParser:typeof fParser==='string'?function(pHash,pData){return fParser;}:function(pHash,pData){return pHash;};tmpLeaf.ParseAsync=typeof fParserAsync==='function'?fParserAsync:typeof fParserAsync==='string'?function(pHash,pData,fCallback){return fCallback(null,fParserAsync);}:function(pHash,pData,fCallback){return fCallback(null,tmpLeaf.Parse(pHash,pData));};// A "this" for every object
3764
3716
  if(pParserContext){tmpLeaf.ParserContext=pParserContext;}tmpLeaf.isAsync=true;return tmpLeaf;}/** Add a Pattern to the Parse Tree with both function parameter types
3765
3717
  * @method addPatternAll
3766
3718
  * @param {Object} pPatternStart - The starting string for the pattern (e.g. "${")