fable 3.0.131 → 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 +5 -2
- package/dist/fable.compatible.js +86 -140
- package/dist/fable.compatible.min.js +2 -2
- package/dist/fable.compatible.min.js.map +1 -1
- package/dist/fable.js +56 -110
- package/dist/fable.min.js +2 -2
- package/dist/fable.min.js.map +1 -1
- package/package.json +3 -3
- package/source/services/Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-Postfix.js +218 -200
- package/source/services/Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-SolvePostfixedExpression.js +10 -0
- package/source/services/Fable-Service-MetaTemplate/MetaTemplate-StringParser.js +13 -64
- package/source/services/Fable-Service-MetaTemplate/MetaTemplate-WordTree.js +19 -35
- package/source/services/Fable-Service-MetaTemplate.js +0 -5
- package/test/ExpressionParser_tests.js +3 -1
- package/test/MetaTemplating_tests.js +6 -2
|
@@ -105,25 +105,17 @@ class StringParser
|
|
|
105
105
|
// Flush the output buffer.
|
|
106
106
|
this.appendOutputBuffer(pCharacter, pParserState);
|
|
107
107
|
// If this last character is the end of the pattern, parse it.
|
|
108
|
-
|
|
108
|
+
// Run the function
|
|
109
|
+
let tmpFunctionContext = ('ParserContext' in pParserState.Pattern) ? pParserState.Pattern.ParserContext : false;
|
|
110
|
+
if (tmpFunctionContext)
|
|
109
111
|
{
|
|
110
|
-
|
|
111
|
-
let tmpFunctionContext = ('ParserContext' in pParserState.Pattern) ? pParserState.Pattern.ParserContext : false;
|
|
112
|
-
if (tmpFunctionContext)
|
|
113
|
-
{
|
|
114
|
-
pParserState.OutputBuffer = pParserState.Pattern.Parse.call(tmpFunctionContext, pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData, pDataContext);
|
|
115
|
-
}
|
|
116
|
-
else
|
|
117
|
-
{
|
|
118
|
-
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData, pDataContext);
|
|
119
|
-
}
|
|
120
|
-
return this.resetOutputBuffer(pParserState);
|
|
112
|
+
pParserState.OutputBuffer = pParserState.Pattern.Parse.call(tmpFunctionContext, pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData, pDataContext);
|
|
121
113
|
}
|
|
122
114
|
else
|
|
123
115
|
{
|
|
124
|
-
|
|
125
|
-
return this.resetOutputBuffer(pParserState);
|
|
116
|
+
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData, pDataContext);
|
|
126
117
|
}
|
|
118
|
+
return this.resetOutputBuffer(pParserState);
|
|
127
119
|
}
|
|
128
120
|
else if (pCharacter in pParserState.PatternStartNode.PatternEnd)
|
|
129
121
|
{
|
|
@@ -156,25 +148,17 @@ class StringParser
|
|
|
156
148
|
// If this last character is the end of the pattern, parse it.
|
|
157
149
|
if ('Parse' in pParserState.Pattern)
|
|
158
150
|
{
|
|
159
|
-
|
|
151
|
+
// Run the t*mplate function
|
|
152
|
+
let tmpFunctionContext = ('ParserContext' in pParserState.Pattern) ? pParserState.Pattern.ParserContext : false;
|
|
153
|
+
if (tmpFunctionContext)
|
|
160
154
|
{
|
|
161
|
-
|
|
162
|
-
this.resetOutputBuffer(pParserState);
|
|
155
|
+
pParserState.OutputBuffer = pParserState.Pattern.Parse.call(tmpFunctionContext, pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData, pDataContext);
|
|
163
156
|
}
|
|
164
157
|
else
|
|
165
158
|
{
|
|
166
|
-
|
|
167
|
-
let tmpFunctionContext = ('ParserContext' in pParserState.Pattern) ? pParserState.Pattern.ParserContext : false;
|
|
168
|
-
if (tmpFunctionContext)
|
|
169
|
-
{
|
|
170
|
-
pParserState.OutputBuffer = pParserState.Pattern.Parse.call(tmpFunctionContext, pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData, pDataContext);
|
|
171
|
-
}
|
|
172
|
-
else
|
|
173
|
-
{
|
|
174
|
-
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData, pDataContext);
|
|
175
|
-
}
|
|
176
|
-
return this.resetOutputBuffer(pParserState);
|
|
159
|
+
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData, pDataContext);
|
|
177
160
|
}
|
|
161
|
+
return this.resetOutputBuffer(pParserState);
|
|
178
162
|
}
|
|
179
163
|
}
|
|
180
164
|
}
|
|
@@ -209,46 +193,11 @@ class StringParser
|
|
|
209
193
|
{
|
|
210
194
|
// ... this is the end of a pattern, cut off the end tag and parse it.
|
|
211
195
|
// Trim the start and end tags off the output buffer now
|
|
212
|
-
if (pParserState.Pattern.isAsync
|
|
196
|
+
if (pParserState.Pattern.isAsync)
|
|
213
197
|
{
|
|
214
198
|
// Run the function
|
|
215
199
|
let tmpFunctionContext = ('ParserContext' in pParserState.Pattern) ? pParserState.Pattern.ParserContext : false;
|
|
216
200
|
if (tmpFunctionContext)
|
|
217
|
-
{
|
|
218
|
-
return pParserState.Pattern.Parse.call(tmpFunctionContext, pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData,
|
|
219
|
-
(pError, pAsyncOutput) =>
|
|
220
|
-
{
|
|
221
|
-
if (pError)
|
|
222
|
-
{
|
|
223
|
-
this.fable.log.info(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
pParserState.OutputBuffer = pAsyncOutput;
|
|
227
|
-
this.resetOutputBuffer(pParserState);
|
|
228
|
-
return fCallback();
|
|
229
|
-
}, pDataContext);
|
|
230
|
-
}
|
|
231
|
-
else
|
|
232
|
-
{
|
|
233
|
-
return pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData,
|
|
234
|
-
(pError, pAsyncOutput) =>
|
|
235
|
-
{
|
|
236
|
-
if (pError)
|
|
237
|
-
{
|
|
238
|
-
this.fable.log.info(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
pParserState.OutputBuffer = pAsyncOutput;
|
|
242
|
-
this.resetOutputBuffer(pParserState);
|
|
243
|
-
return fCallback();
|
|
244
|
-
}, pDataContext);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
else if (pParserState.Pattern.isAsync && pParserState.Pattern.isBoth)
|
|
248
|
-
{
|
|
249
|
-
// Run the function when both async and non async were provided with the pattern
|
|
250
|
-
let tmpFunctionContext = ('ParserContext' in pParserState.Pattern) ? pParserState.Pattern.ParserContext : false;
|
|
251
|
-
if (tmpFunctionContext)
|
|
252
201
|
{
|
|
253
202
|
return pParserState.Pattern.ParseAsync.call(tmpFunctionContext, pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData,
|
|
254
203
|
(pError, pAsyncOutput) =>
|
|
@@ -52,14 +52,16 @@ class WordTree
|
|
|
52
52
|
return pTree.PatternEnd[pPattern];
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
/** Add a Pattern to the Parse Tree
|
|
56
|
-
* @method
|
|
55
|
+
/** Add a Pattern to the Parse Tree with both function parameter types
|
|
56
|
+
* @method addPatternAll
|
|
57
57
|
* @param {Object} pPatternStart - The starting string for the pattern (e.g. "${")
|
|
58
58
|
* @param {string} pPatternEnd - The ending string for the pattern (e.g. "}")
|
|
59
59
|
* @param {function} fParser - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.
|
|
60
|
-
* @
|
|
60
|
+
* @param {function} fParserAsync - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.
|
|
61
|
+
* @param {Object} pParserContext - The context to pass to the parser function
|
|
62
|
+
* @return {Object} The leaf parser from the tree
|
|
61
63
|
*/
|
|
62
|
-
|
|
64
|
+
addPatternBoth (pPatternStart, pPatternEnd, fParser, fParserAsync, pParserContext)
|
|
63
65
|
{
|
|
64
66
|
if (pPatternStart.length < 1)
|
|
65
67
|
{
|
|
@@ -93,8 +95,12 @@ class WordTree
|
|
|
93
95
|
tmpLeaf.PatternStartString = pPatternStart;
|
|
94
96
|
tmpLeaf.PatternEndString = tmpPatternEnd;
|
|
95
97
|
tmpLeaf.Parse = (typeof(fParser) === 'function') ? fParser :
|
|
96
|
-
(typeof(fParser) === 'string') ? () => { return fParser; } :
|
|
97
|
-
(pData) => { return
|
|
98
|
+
(typeof(fParser) === 'string') ? (pHash, pData) => { return fParser; } :
|
|
99
|
+
(pHash, pData) => { return pHash; };
|
|
100
|
+
|
|
101
|
+
tmpLeaf.ParseAsync = (typeof(fParserAsync) === 'function') ? fParserAsync :
|
|
102
|
+
(typeof(fParserAsync) === 'string') ? (pHash, pData, fCallback) => { return fCallback(null, fParserAsync); } :
|
|
103
|
+
(pHash, pData, fCallback) => { return fCallback(null, tmpLeaf.Parse(pHash, pData)); }
|
|
98
104
|
|
|
99
105
|
// A "this" for every object
|
|
100
106
|
if (pParserContext)
|
|
@@ -102,43 +108,21 @@ class WordTree
|
|
|
102
108
|
tmpLeaf.ParserContext = pParserContext;
|
|
103
109
|
}
|
|
104
110
|
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
111
|
+
tmpLeaf.isAsync = true;
|
|
108
112
|
|
|
109
|
-
|
|
110
|
-
* @method addPatternAsync
|
|
111
|
-
* @param {Object} pPatternStart - The starting string for the pattern (e.g. "${")
|
|
112
|
-
* @param {string} pPatternEnd - The ending string for the pattern (e.g. "}")
|
|
113
|
-
* @param {function} fParserAsync - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.
|
|
114
|
-
* @return {bool} True if adding the pattern was successful
|
|
115
|
-
*/
|
|
116
|
-
addPatternAsync (pPatternStart, pPatternEnd, fParserAsync, pParserContext)
|
|
117
|
-
{
|
|
118
|
-
let tmpLeaf = this.addPattern(pPatternStart, pPatternEnd, fParserAsync, pParserContext);
|
|
119
|
-
if (tmpLeaf)
|
|
120
|
-
{
|
|
121
|
-
tmpLeaf.isAsync = true;
|
|
122
|
-
}
|
|
113
|
+
return tmpLeaf;
|
|
123
114
|
}
|
|
124
115
|
|
|
125
|
-
/** Add a Pattern to the Parse Tree
|
|
126
|
-
* @method
|
|
116
|
+
/** Add a Pattern to the Parse Tree with both function parameter types
|
|
117
|
+
* @method addPatternAll
|
|
127
118
|
* @param {Object} pPatternStart - The starting string for the pattern (e.g. "${")
|
|
128
119
|
* @param {string} pPatternEnd - The ending string for the pattern (e.g. "}")
|
|
129
120
|
* @param {function} fParser - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.
|
|
130
|
-
* @
|
|
121
|
+
* @param {Object} pParserContext - The context to pass to the parser function
|
|
131
122
|
*/
|
|
132
|
-
|
|
123
|
+
addPattern (pPatternStart, pPatternEnd, fParser, pParserContext)
|
|
133
124
|
{
|
|
134
|
-
|
|
135
|
-
if (tmpLeaf)
|
|
136
|
-
{
|
|
137
|
-
tmpLeaf.isAsync = true;
|
|
138
|
-
tmpLeaf.isBoth = true;
|
|
139
|
-
// When a leaf has both async and non-async versions of the functions, we store the async in fParserAsync.
|
|
140
|
-
tmpLeaf.ParseAsync = fParserAsync;
|
|
141
|
-
}
|
|
125
|
+
return this.addPatternBoth(pPatternStart, pPatternEnd, fParser, null, pParserContext);
|
|
142
126
|
}
|
|
143
127
|
}
|
|
144
128
|
|
|
@@ -30,11 +30,6 @@ class FableServiceMetaTemplate extends libFableServiceBase
|
|
|
30
30
|
return this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser, pParserContext);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
addPatternAsync(pPatternStart, pPatternEnd, pParserPromise, pParserContext)
|
|
34
|
-
{
|
|
35
|
-
return this.WordTree.addPatternAsync(pPatternStart, pPatternEnd, pParserPromise, pParserContext);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
33
|
addPatternBoth(pPatternStart, pPatternEnd, pParser, pParserPromise, pParserContext)
|
|
39
34
|
{
|
|
40
35
|
return this.WordTree.addPatternBoth(pPatternStart, pPatternEnd, pParser, pParserPromise, pParserContext);
|
|
@@ -162,6 +162,8 @@ suite
|
|
|
162
162
|
|
|
163
163
|
Expect(_Parser.solve('5 ^ 2')).to.equal('25');
|
|
164
164
|
|
|
165
|
+
Expect(_Parser.solve('Result = sqrt(100 * (C + 30)) + sin(Depth - Width) / 10', { "PR": 1.5, "Z": "20.036237", "C": -13, Depth: 100.203, Width: 10.5})).to.equal('41.32965489638783839821');
|
|
166
|
+
|
|
165
167
|
Expect(_Parser.solve('((15000 * 2) / 4)^2 + 100 - 10 * (35 + 5)')).to.equal("56249700");
|
|
166
168
|
|
|
167
169
|
Expect(_Parser.solve('1.5 * sqrt(8 * 2.423782342^2) / 10')).to.equal('1.02832375808904701855')
|
|
@@ -170,7 +172,7 @@ suite
|
|
|
170
172
|
Expect(_Parser.solve('sin(rad(60))')).to.equal('0.8660254037844386');
|
|
171
173
|
|
|
172
174
|
Expect(_Parser.solve('Result = 5+3 - sqrt(75 / (3 + Depth) * Width)^ 3', { "PR": 1.5, "Z": "20.036237", "C": -13, Depth: 100.203, Width: 10.5}))
|
|
173
|
-
.to.equal('-
|
|
175
|
+
.to.equal('-13.078386362213538715906797395732300153182132216343566001917247')
|
|
174
176
|
|
|
175
177
|
let tmpResult = _Parser.solve('Result = (160 * PR * Z) / (C / 100) * PR * Z + (160 * (1 - C / 100))', {C:-13,PR:1.5,Z:20.03})
|
|
176
178
|
Expect(tmpResult).to.equal("-1110837.0769230769230769230307");
|
|
@@ -31,7 +31,11 @@ const configMetaTemplate = (pModule) =>
|
|
|
31
31
|
pModule.addPattern('<^', '^>', (pHash, pData)=>{return `hash of [${pHash}] from pData is ${pData[pHash]}`});
|
|
32
32
|
// This just escapes out pairs of $
|
|
33
33
|
pModule.addPattern('$');
|
|
34
|
-
pModule.
|
|
34
|
+
pModule.addPatternBoth('<%Async', '%>',
|
|
35
|
+
(pHash, pData) =>
|
|
36
|
+
{
|
|
37
|
+
return `NONASYNC DATA IS [${pHash}]`;
|
|
38
|
+
},
|
|
35
39
|
(pHash, pData, fCallback)=>
|
|
36
40
|
{
|
|
37
41
|
return fCallback(null, `ASYNC DATA IS [${pHash}]`);
|
|
@@ -207,7 +211,7 @@ suite
|
|
|
207
211
|
{
|
|
208
212
|
let tmpTestString = 'The <^SomeValue^> and <~JELLY FISH~> pData and Async <%AsyncThe Funny String%> up in here and a $comment$ as well.';
|
|
209
213
|
let tmpExpectedResultAsync = 'The hash of [SomeValue] from pData is AirbornLight and Async Jellyfish called for pData which is [[object Object]] with a hash of [JELLY FISH] pData and Async ASYNC DATA IS [The Funny String] up in here and a comment as well.';
|
|
210
|
-
let tmpExpectedResult = 'The hash of [SomeValue] from pData is AirbornLight and Non-Async Jellyfish called for pData which is [[object Object]] with a hash of [JELLY FISH] pData and Async
|
|
214
|
+
let tmpExpectedResult = 'The hash of [SomeValue] from pData is AirbornLight and Non-Async Jellyfish called for pData which is [[object Object]] with a hash of [JELLY FISH] pData and Async NONASYNC DATA IS [The Funny String] up in here and a comment as well.';
|
|
211
215
|
let testMetaTemplate = loadMetaTemplateModule();
|
|
212
216
|
configMetaTemplate(testMetaTemplate);
|
|
213
217
|
let tmpNonAsyncResult = testMetaTemplate.parseString(tmpTestString, {SomeValue:'AirbornLight'});
|