JSFiddle - React, Tailwind, and code Playground
by francisfortier
HTML
<ul>
<li expected="2" func="evaluateAsNumber">1 + 1</li>
<li expected="6" func="evaluateAsNumber">1 + 2 + 3</li>
<li expected="7" func="evaluateAsNumber">1 + 2 * 3</li>
<li expected="9" func="evaluateAsNumber">(1 + 2) * 3</li>
<li expected="6" func="evaluateAsNumber">sqrt(9) * 2</li>
<li expected="2" func="evaluateAsNumber">3 + (-1)</li>
<li expected="4" define="a=2" func="evaluateAsNumber">a^2</li>
<li expected="5" define="a=2" func="evaluateAsNumber">3 + max(a, 1)</li>
<li expected="coco" func="evaluateAsString">"co" "co"</li>
<li expected="1 + 1 = 2" func="evaluateAsString">"1 + 1 = " 1 + 1</li>
<li expected="1 + 1 = 2" func="evaluateAsString">3 - 2 " + 1 = " 1 + 1</li>
<li expected="Bonjour Francis" define="ab$=Francis" func="evaluateAsString">"Bonjour " ab$</li>
<li expected="true" func="evaluateAsBoolean">1 <= 3</li>
</ul>
JavaScript
variables = {};
functions = {
sqrt: function(expr) {
return Math.sqrt(expr.evaluateAsNumber());
},
max: function(exprA, exprB) {
var a = exprA.evaluateAsNumber();
var b = exprB.evaluateAsNumber();
return a > b ? a : b;
}
};
Delimiter = function() {
var delimiters = [];
var t = this;
for (var i = 0; i < arguments.length; i++)
{
delimiters.push(arguments[i]);
}
this.check = function(token) {
for (var i = 0; i < delimiters.length; i++)
{
if (delimiters[i] === token)
{
t.found = token;
t.expectationFilled = true;
return true;
}
}
return false;
};
this.toString = function() {
return '[' + delimiters.toString() + ']';
};
this.expectationFilled = arguments.length === 0;
};
Delimiter.defaultDelimiter = new Delimiter();
Expression = function() { };
Expression.operatorPrecedences = [
['<', '>', '<=', '>=', '=', '<>'],
['+', '-'],
['*', '/', '^']
];
Expression.build = function(exprs, operators) {
if (exprs.length === 1)
return exprs[0];
// On parcourt les opérateurs dans l'ordre de précéance
for (var precedenceIndex = 0; precedenceIndex < Expression.operatorPrecedences.length; precedenceIndex++)
{
for (var operatorIndex = 0; operatorIndex < Expression.operatorPrecedences[precedenceIndex].length; operatorIndex++)
{
var op = Expression.operatorPrecedences[precedenceIndex][operatorIndex];
for (var i = 0; i < operators.length; i++)
{
if (operators[i] === op)
{
var leftExpr = arguments.callee(exprs.slice(0, i + 1), operators.slice(0, i));
var rightExpr = arguments.callee(exprs.slice(i + 1), operators.slice(i + 1));
...