fable 3.0.132 → 3.0.134
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 +27 -36
- package/dist/fable.compatible.js +336 -165
- package/dist/fable.compatible.min.js +2 -2
- package/dist/fable.compatible.min.js.map +1 -1
- package/dist/fable.js +277 -106
- package/dist/fable.min.js +2 -2
- package/dist/fable.min.js.map +1 -1
- package/example_applications/data/Fruit-Data.json +694 -0
- package/example_applications/data/Fruit-Manyfest.json +56 -0
- package/example_applications/mathematical_playground/AppData.json +8 -0
- package/example_applications/mathematical_playground/Equations.json +12 -0
- package/example_applications/mathematical_playground/Math-Solver-Harness.js +89 -0
- package/package.json +3 -3
- package/source/services/Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-FunctionMap.json +80 -20
- package/source/services/Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-Postfix.js +218 -200
- package/source/services/Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-SolvePostfixedExpression.js +11 -1
- package/source/services/Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-TokenMap.json +1 -0
- package/source/services/Fable-Service-ExpressionParser.js +22 -3
- package/source/services/Fable-Service-Math.js +570 -19
- package/test/ExpressionParser_tests.js +20 -1
- package/test/Math_test.js +54 -3
- package/test/data/chocodata.json +248 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Scope": "FruitsOfTheWorld",
|
|
3
|
+
"Descriptors":
|
|
4
|
+
{
|
|
5
|
+
"FruityVice[].name":
|
|
6
|
+
{
|
|
7
|
+
"Name": "Fruit Name",
|
|
8
|
+
"Hash": "Name",
|
|
9
|
+
"DataType": "String",
|
|
10
|
+
"Default": "(unnamed fruit)"
|
|
11
|
+
},
|
|
12
|
+
"FruityVice[].family":
|
|
13
|
+
{
|
|
14
|
+
"Name": "Family",
|
|
15
|
+
"Hash": "Family",
|
|
16
|
+
"DataType": "String"
|
|
17
|
+
},
|
|
18
|
+
"FruityVice[].order":
|
|
19
|
+
{
|
|
20
|
+
"Name": "Order",
|
|
21
|
+
"Hash": "Order",
|
|
22
|
+
"DataType": "String"
|
|
23
|
+
},
|
|
24
|
+
"FruityVice[].genus":
|
|
25
|
+
{
|
|
26
|
+
"Name": "Genus",
|
|
27
|
+
"Hash": "Genus",
|
|
28
|
+
"DataType": "String"
|
|
29
|
+
},
|
|
30
|
+
"FruityVice[].nutritions.calories":
|
|
31
|
+
{
|
|
32
|
+
"Name": "Calories",
|
|
33
|
+
"Hash": "Calories"
|
|
34
|
+
},
|
|
35
|
+
"FruityVice[].nutritions.fat":
|
|
36
|
+
{
|
|
37
|
+
"Name": "Fat",
|
|
38
|
+
"Hash": "Fat"
|
|
39
|
+
},
|
|
40
|
+
"FruityVice[].nutritions.protein":
|
|
41
|
+
{
|
|
42
|
+
"Name": "Protein",
|
|
43
|
+
"Hash": "Protein"
|
|
44
|
+
},
|
|
45
|
+
"FruityVice[].nutritions.carbohydrates":
|
|
46
|
+
{
|
|
47
|
+
"Name": "Carbohydrates",
|
|
48
|
+
"Hash": "Carbohydrates"
|
|
49
|
+
},
|
|
50
|
+
"FruityVice[].nutritions.sugar":
|
|
51
|
+
{
|
|
52
|
+
"Name": "Sugar",
|
|
53
|
+
"Hash": "Sugar"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Expressions":
|
|
3
|
+
[
|
|
4
|
+
{ "Equation":"Result = 5+3 - sqrt(75 / (3 + Depth) * Width)^ 3", "ExpectedResult":"-13.078386362213538715906797395732300153182132216343566001917247" },
|
|
5
|
+
{ "Equation":"Result = (160 * PR * Z) / (C / 100) * PR * Z + (160 * (1 - C / 100))", "ExpectedResult":"-1111529.088640468" },
|
|
6
|
+
{ "Equation":"1.5 * sqrt(8 * 2.423782342^2) / 10", "ExpectedResult":"1.02832375808904701855" },
|
|
7
|
+
{ "Equation":"Result = ((15000 * 2) / 4)^2 + 100 - 10 * (35 + 5)", "ExpectedResult":"562500" },
|
|
8
|
+
{ "Equation":"Result = 1 * sqrt(16)", "ExpectedResult":"4" },
|
|
9
|
+
{ "Equation":"Result = sqrt(100 * (C + 30)) + sin(Depth - Width) / 10", "ExpectedResult":"41.32965489638783839821" },
|
|
10
|
+
{ "Equation":"Result = 3.5 + 50 + 10 * 10 / 5 - 1.5", "ExpectedResult":"72" }
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const libFable = require('../../source/Fable.js');
|
|
2
|
+
|
|
3
|
+
const _Fable = new libFable({"Product": "Ti"});
|
|
4
|
+
// This instantiates the ExpressionParser service provider
|
|
5
|
+
_Fable.instantiateServiceProviderIfNotExists('ExpressionParser');
|
|
6
|
+
|
|
7
|
+
/* * * * * * * * * * * * * * * * *
|
|
8
|
+
*
|
|
9
|
+
* Solve a basic math problem.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
_Fable.log.info(`Beginning Basic Math Exercises....`);
|
|
13
|
+
// Just type numbers and watch it go brrr
|
|
14
|
+
_Fable.log.info(`One-liner solve is: ${_Fable.ExpressionParser.solve("Result = 73.5 * 28.8 * 200.5")}`);
|
|
15
|
+
// Let's put it in a variable for easier exercises
|
|
16
|
+
const _ExpressionParser = _Fable.ExpressionParser;
|
|
17
|
+
// Look up somoe variables in an object
|
|
18
|
+
_Fable.log.info(`One-liner solve with variables is: ${_ExpressionParser.solve("Volume = Width * Height * Depth", {"Width": 73.5, "Height": 28.8, "Depth": 200.5})}`);
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
/* * * * * * * * * * * * * * * * *
|
|
22
|
+
*
|
|
23
|
+
* A simple run through of some mathematical expressions
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
_Fable.log.info(`Beginning Run-through for Set of Test Expressions....`);
|
|
27
|
+
// An array of equations with expected values
|
|
28
|
+
let _Equations = require(`./Equations.json`);
|
|
29
|
+
// The application state is a plain javascript object we pass into the solver to pull variables from
|
|
30
|
+
let _AppData = require(`./AppData.json`);
|
|
31
|
+
// The manifest is a Manyfest which describes hashes for complex addresses in the application state object
|
|
32
|
+
// For example you can't use "Student[0].Age" as a variable in the expression
|
|
33
|
+
// ...but you can use "Student[0].Age" as an address in the manifest with a hash of "StudentAge"
|
|
34
|
+
// ...and then reference "StudentAge" in the expression.
|
|
35
|
+
let tmpManifestConfiguration = { "Scope":"None", "Descriptors":[] };
|
|
36
|
+
let tmpManifest = _Fable.newManyfest(tmpManifestConfiguration);
|
|
37
|
+
// Run each expression in the Equations.json file through the expression parser.
|
|
38
|
+
for (let i = 0; i < _Equations.Expressions.length; i++)
|
|
39
|
+
{
|
|
40
|
+
let tmpResultValue = _ExpressionParser.solve(_Equations.Expressions[i].Equation, _AppData, {}, tmpManifest);
|
|
41
|
+
console.log(`Expression [${i}]: [${_Equations.Expressions[i].Equation}] ==> ${tmpResultValue}`);
|
|
42
|
+
if (tmpResultValue !== _Equations.Expressions[i].ExpectedResult)
|
|
43
|
+
{
|
|
44
|
+
console.log(`Error: Equation ${_Equations.Expressions[i].Equation} expected [${_Equations.Expressions[i].ExpectedResult}] but got [${tmpResultValue}]`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/* * * * * * * * * * * * * * * * *
|
|
50
|
+
*
|
|
51
|
+
* A manual run through of each phase of the expression parser
|
|
52
|
+
*
|
|
53
|
+
*/
|
|
54
|
+
// Load up some fruit data to play around with
|
|
55
|
+
let _FruitData = require(`../data/Fruit-Data.json`);
|
|
56
|
+
let _FruitManifestDescription = require(`../data/Fruit-Manyfest.json`);
|
|
57
|
+
let _FruitManifest = _Fable.newManyfest(_FruitManifestDescription);
|
|
58
|
+
|
|
59
|
+
_Fable.log.info(`Beginning Manual Solve with Embedded Fruit Data....`);
|
|
60
|
+
|
|
61
|
+
// The expression we pass into the solver is just a string
|
|
62
|
+
let tmpExpression = 'HyperMax.HealthIndex = (SUM(Calories) / SUM(Sugar)) * MEDIAN(Fat) + (SQRT(AVG(Protein)) - (PI() + 99)';
|
|
63
|
+
_Fable.log.info(`Solving tmpExpression: [${tmpExpression}]`);
|
|
64
|
+
|
|
65
|
+
// This is an object where the parser will write out the results of each phase of the compiler/parser/solver
|
|
66
|
+
let tmpExpressionParseOutcome = {};
|
|
67
|
+
let tmpSolverResultsObject = {};
|
|
68
|
+
|
|
69
|
+
// Step 1: Tokenize the expression
|
|
70
|
+
let complexTokenizedResults = _ExpressionParser.tokenize(tmpExpression, tmpExpressionParseOutcome);
|
|
71
|
+
// Step 2: Lint the tokenized expression (this is optional but very helpful for user feedback)
|
|
72
|
+
let complexLintedResults = _ExpressionParser.lintTokenizedExpression(complexTokenizedResults, tmpExpressionParseOutcome);
|
|
73
|
+
// Step 3: Parse the tokenized expression (this generates a postfix expression)
|
|
74
|
+
let complexPostfixedResults = _ExpressionParser.buildPostfixedSolveList(complexTokenizedResults, tmpExpressionParseOutcome);
|
|
75
|
+
// Step 4: Substitute the values references in the tokenized objects representing data within the postfixed expression
|
|
76
|
+
_ExpressionParser.substituteValuesInTokenizedObjects(tmpExpressionParseOutcome.PostfixTokenObjects, _FruitData, tmpExpressionParseOutcome, _FruitManifest);
|
|
77
|
+
// Now that we have a postfixed expression and the mapped-in values, show the user what the solution steps look like
|
|
78
|
+
for (let i = 0; i < tmpExpressionParseOutcome.PostfixSolveList.length; i++)
|
|
79
|
+
{
|
|
80
|
+
let tmpToken = tmpExpressionParseOutcome.PostfixSolveList[i];
|
|
81
|
+
console.log(`${i}: ${tmpToken.VirtualSymbolName} = (${tmpToken.LeftValue.Token}::${tmpToken.LeftValue.Value}) ${tmpToken.Operation.Token} (${tmpToken.RightValue.Token}::${tmpToken.RightValue.Value}) `)
|
|
82
|
+
}
|
|
83
|
+
// Step 5: Solve the postfixed expression
|
|
84
|
+
let tmpResultValue = _ExpressionParser.solvePostfixedExpression(tmpExpressionParseOutcome.PostfixSolveList, tmpSolverResultsObject, tmpExpressionParseOutcome, _FruitManifest);
|
|
85
|
+
|
|
86
|
+
// Step 6: Look at the results.
|
|
87
|
+
console.log(`Outcome object: ${JSON.stringify(tmpSolverResultsObject)}`);
|
|
88
|
+
console.log(`Result of ${tmpExpression} solve: ${tmpResultValue}`);
|
|
89
|
+
console.log('QED');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fable",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.134",
|
|
4
4
|
"description": "A service dependency injection, configuration and logging library.",
|
|
5
5
|
"main": "source/Fable.js",
|
|
6
6
|
"scripts": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"homepage": "https://github.com/stevenvelozo/fable",
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"quackage": "^1.0.
|
|
53
|
+
"quackage": "^1.0.30"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"async.eachlimit": "^0.5.2",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"fable-serviceproviderbase": "^3.0.13",
|
|
65
65
|
"fable-settings": "^3.0.10",
|
|
66
66
|
"fable-uuid": "^3.0.7",
|
|
67
|
-
"manyfest": "^1.0.
|
|
67
|
+
"manyfest": "^1.0.35",
|
|
68
68
|
"simple-get": "^4.0.1"
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -1,22 +1,82 @@
|
|
|
1
1
|
{
|
|
2
|
-
"sqrt":
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"abs":
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"rad":
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
2
|
+
"sqrt": {
|
|
3
|
+
"Name": "Square Root",
|
|
4
|
+
"Address": "fable.Math.sqrtPrecise"
|
|
5
|
+
},
|
|
6
|
+
|
|
7
|
+
"abs": {
|
|
8
|
+
"Name": "Absolute Value",
|
|
9
|
+
"Address": "fable.Math.absPrecise"
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
"rad": {
|
|
13
|
+
"Name": "Degrees to Radians",
|
|
14
|
+
"Address": "fable.Math.radPrecise"
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
"pi": {
|
|
18
|
+
"Name": "Pi",
|
|
19
|
+
"Address": "fable.Math.piPrecise"
|
|
20
|
+
},
|
|
21
|
+
"sin": {
|
|
22
|
+
"Name": "Sine",
|
|
23
|
+
"Address": "fable.Math.sin"
|
|
24
|
+
},
|
|
25
|
+
"cos": {
|
|
26
|
+
"Name": "Cosine",
|
|
27
|
+
"Address": "fable.Math.cos"
|
|
28
|
+
},
|
|
29
|
+
"tan": {
|
|
30
|
+
"Name": "Tangent",
|
|
31
|
+
"Address": "fable.Math.tan"
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
"count": {
|
|
35
|
+
"Name": "Count Set Elements",
|
|
36
|
+
"Address": "fable.Math.countSetElements"
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
"sortset": {
|
|
40
|
+
"Name": "Sort Set",
|
|
41
|
+
"Address": "fable.Math.sortSetPrecise"
|
|
42
|
+
},
|
|
43
|
+
"bucketset": {
|
|
44
|
+
"Name": "Bucket Set",
|
|
45
|
+
"Address": "fable.Math.bucketSetPrecise"
|
|
46
|
+
},
|
|
47
|
+
"sorthistogram": {
|
|
48
|
+
"Name": "Sort Histogram",
|
|
49
|
+
"Address": "fable.Math.sortHistogramPrecise"
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
"max": {
|
|
53
|
+
"Name": "Maximum",
|
|
54
|
+
"Address": "fable.Math.maxPrecise"
|
|
55
|
+
},
|
|
56
|
+
"min": {
|
|
57
|
+
"Name": "Minimum",
|
|
58
|
+
"Address": "fable.Math.minPrecise"
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
"sum": {
|
|
62
|
+
"Name": "Sum",
|
|
63
|
+
"Address": "fable.Math.sumPrecise"
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
"avg": {
|
|
67
|
+
"Name": "Average",
|
|
68
|
+
"Address": "fable.Math.averagePrecise"
|
|
69
|
+
},
|
|
70
|
+
"mean": {
|
|
71
|
+
"Name": "Mean",
|
|
72
|
+
"Address": "fable.Math.meanPrecise"
|
|
73
|
+
},
|
|
74
|
+
"median": {
|
|
75
|
+
"Name": "Median",
|
|
76
|
+
"Address": "fable.Math.medianPrecise"
|
|
77
|
+
},
|
|
78
|
+
"mode": {
|
|
79
|
+
"Name": "Mode",
|
|
80
|
+
"Address": "fable.Math.modePrecise"
|
|
81
|
+
}
|
|
22
82
|
}
|