+*Abbreviations*: In an earlier version, you couldn't use abbreviations. `\x y. y x x` had to be written `(\x (\y ((y x) x)))`. We've upgraded the parser though, so now it should be able to understand any lambda term that you can.
+
+*Constants*: The combinators `S`, `K`, `I`, `C`, `B`, `W`, and `T` are pre-defined to their standard values. Also, integers will automatically be converted to Church numerals. (`0` is `\s z. z`, `1` is `\s z. s z`, and so on.)
+
+
+
+<textarea id="INPUT" style="border: 2px solid black; color: black; font-family: monospace; height: 3in; overflow: auto; padding: 0.5em; width: 100%;">
+let true = \x y. x in
+let false = \x y. y in
+let and = \l r. l r false in
+(
+ (and true true yes no)
+ (and true false yes no)
+ (and false true yes no)
+ (and false false yes no)
+)
+</textarea>
+<input id="PARSE" value="Normalize" type="button">
+<input id="ETA" type="checkbox">do eta-reductions too
+<noscript><p>You may not see it because you have JavaScript turned off. Uffff!</p></noscript>
+<script src="/code/lambda.js"></script>
+<script src="/code/tokens.js"></script>
+<script src="/code/parse.js"></script>
+<script src="/code/json2.js"></script>
+<pre id="OUTPUT">
+</pre>
+<script>
+/*jslint evil: true */
+
+/*members create, error, message, name, prototype, stringify, toSource,
+ toString, write
+*/
+
+/*global JSON, make_parse, parse, source, tree */
+
+// Make a new object that inherits members from an existing object.
+
+if (typeof Object.create !== 'function') {
+ Object.create = function (o) {
+ function F() {}
+ F.prototype = o;
+ return new F();
+ };
+}
+
+// Transform a token object into an exception object and throw it.
+
+Object.prototype.error = function (message, t) {
+ t = t || this;
+ t.name = "SyntaxError";
+ t.message = message;
+ throw t;
+};
+
+
+(function () {
+ var parse = make_parse();
+
+ function go(source) {
+ var string, tree, expr, eta;
+ try {
+ tree = parse(source);
+ // string = JSON.stringify(tree, ['key', 'name', 'message', 'value', 'arity', 'first', 'second', 'third', 'fourth'], 4);
+ expr = tree.handler();
+ // string = JSON.stringify(expr, ['key', 'name', 'message', 'value', 'arity', 'first', 'second', 'tag', 'variable', 'left', 'right', 'bound', 'body' ], 4);
+// string = expr.to_string() + "\n\n~~>\n\n";
+ string = '';
+ eta = document.getElementById('ETA').checked;
+ string = string + reduce(expr, eta, false).to_string();
+ } catch (e) {
+ string = JSON.stringify(e, ['name', 'message', 'from', 'to', 'key',
+ 'value', 'arity', 'first', 'second', 'third', 'fourth'], 4);
+ }
+ document.getElementById('OUTPUT').innerHTML = string
+ .replace(/&/g, '&')
+ .replace(/[<]/g, '<');
+ }
+
+ document.getElementById('PARSE').onclick = function (e) {
+ go(document.getElementById('INPUT').value);
+ };
+}());
+
+</script>
+
+
+