<div id=examples>
<textarea class=ex>
</textarea>
<textarea class=ex>
# Fibonacci
let
fib(n) = begin
if n == 0 then
0
elif n == 1 then
1
else
fib(n - 1) + fib(n - 2)
end
end
in
fib(10)
end
</textarea>
<textarea class=ex>
# Arithmetic precedence
10 + 5 * 7 - 2^3^2
</textarea>
<textarea class=ex>
let
odd(x) = if x == 0 then false else even(x - 1) end
even(x) = if x == 0 then true else odd(x - 1) end
in
1..10 each i -> print(
i + " is " + if even(i) then "even" else "odd" end
)
true
end
</textarea>
<textarea class=ex>
let square(x) = x * x in
[1, 2, 3, 4, 5] each x -> begin
square(x)
end
end
</textarea>
<textarea class=ex>
# You can define arbitrary operators. They have high priority by default,
# but you can specify a different priority in the config object.
let x *** y = (x*x + y*y)^(1/2) in
3 *** 4
end
</textarea>
<textarea class=ex>
# This is a test for closures
let x = 1, f(y) = x + y in
let x = 2 in
[f(x), x]
end
end
</textarea>
</div>
<textarea id=expr>
</textarea>
<div><button id=evaluate>Evaluate</button></div>
<h3>Result</h3>
<div id=result>???</div>
<h3>AST</h3>
<div id=ast></div>
///////////////////
/// PARSER CORE ///
///////////////////
// There is an annotated configuration object in the GRAMMAR section below
function Parser(config) {
var prio = this.priorities = config.priorities;
prio["boundary:$"] = [-1, -1];
this.re = config.re;
this.toktypes = config.toktypes;
config.blocks.forEach(function (defs) {
var parts = defs.split(" ");
prio[parts.shift()] = [10000, 0];
prio[parts.pop()] = [0, 10001, true];
parts.forEach(function (part) {prio[part] = [0, 0];});
});
var level = 5;
config.tower.forEach(function (ops) {
ops[1].split(" ").forEach(function (op) {
var pfx = op.substring(0, 2) === "P:";
prio[op] = [pfx ? 10000 : level, level - ops[0]];
if (pfx && !prio[op.substring(2)])
prio[op.substring(2)] = prio[op];
});
level += 5;
});
}
// The return value of tokenize("a + 6 * 10") is:
// [{token: "$", type: "boundary"},
// {token: "a", type: "id"},
// {token: "+", type: "op"},
// {token: "6", type: "num"},
// {token: "*", type: "op"},
// {token: "10", type: "num"},
// {token: "$", type: "boundary"}]
// In everything that follows, tok(a) will stand for {token: "a", type: "id"},
// tok(*) for {token: "*", type: "op"}, and so on.
Parser.prototype.tokenize = function (text) {
var m; var last = "op";
var results = [{token: "$", type: "boundary"}];
while (m = this.re.exec(text)) {
var type = this.toktypes[m.slice(1).indexOf(m[0])];
if (type === "comment") continue;
var tok = {token: m[0], type: type};
// An "op" token followed by an "op" token makes the second prefix
// unless the first is marked as suffix.
if (last.type === "op" && type === "op" && !this.getPrio(last)[2])
tok.prefix = true;
results.push(tok);
last = tok;
}
results.push({token: "$", type: "boundary"});
return...
Please Whitelist JSFiddle in your content blocker.
Help keep JSFiddle free for always by one of two ways:
Whitelist JSFiddle in your content blocker (two clicks)
Go PRO and get access to additional PRO features →
Join the 4+ million users, and keep the JSFiddle dream alive.
Ad-free
All ads in the editor and listing pages are turned completely off.
Use pre-released features
You get to try and use features (like the Palette Color Generator) months before everyone else.
Fiddle collections
Sort and categorize your Fiddles into multiple collections.
Private collections and fiddles
You can make as many Private Fiddles, and Private Collections as you wish!
Console
Debug your Fiddle with a minimal built-in JavaScript console.