lambdaway
::
meta2
3
|
list
|
login
|
load
|
|
_h2 [[meta]] | meta2 | [[meta3]] | [[meta4]] | [[meta5]] _ul See [[http://ward.asia.wiki.org/view/sweet-little-language|http://ward.asia.wiki.org/view/sweet-little-language]]. _p {b '{meta talk}} is a very reduced version of lambdatalk (see [[JS.js|meca/JS.js]] for the full version), which can work outside of the wiki: _ul valid S-expressions are any sequences of words or well balanced nested prefixed parenthesized forms {code (first rest)}. _ul There are {b no lambda, def, if, let} special forms, just a small set of MATH and HTML/CSS primitives: {prewrap ['+', '*', 'sqrt', ..., fac, 'div', 'span', 'a', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'table', 'tr', 'td', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'b', 'i', 'u', 'center', 'br', 'hr', 'blockquote', 'del', 'sup', 'sub', 'code', 'img', 'pre']} _ul The dictionary can be extended on demand, using the javascript syntax, see for instance the {code fac} function. _ul {b caution}: S_expressions use rounded parentheses to trigger evaluations. Don't use rounded parentheses for other purposes, for instance to write {code (this is a comment inside parentheses)} or CSS rules containing round parentheses, for instance {code color:rgb(255,0,0)}. That explains why curly braces instead of round braces have been chosen for lambdatalk. _h2 1) input {textarea {@ id="input" onkeyup="meta_evaluate()"} (center Welcome in (b metatalk), an S-expressions evaluator working in a console hosted in a tiny wiki, (b lambda tank), and its (i amazingly simple) language, (b lambdatalk). ) (div (@ style="font:italic 4.0em optima; text-align:center; color:#f00;") (sqrt (+ (* 3 3) (* 4 4))) ) (h1 fac[21] = (fac 21)) (pre a ab abc abcd ) (img (@ src="data/amelie_poulain.jpg" width="100%")) Writing (foo bar) is an error, (i because foo is not in the dictionary.) } {center {@ id="infos"}...} _h2 2) output {div {@ id="output" style="padding:10px; box-shadow:0 0 8px #000;"}...} _h2 3) javascript code _h3 3.1) the evaluator {pre °° var META = (function() { var DICT = {}; var regexp = /\(([^\s()]*)(?:[\s]*)([^()]*)\)/g; // iterative form: var __eval_forms__ = function(s) { while (s !== (s = s.replace(regexp, eval_form))); return s; }; // recursive form: var eval_forms = function(s) { return (s !== (s = s.replace(regexp, eval_form)) )? eval_forms(s) : s; }; var eval_form = function() { var f = arguments[1] || "", r = arguments[2] || ""; return DICT.hasOwnProperty(f) ? DICT[f].apply(null, [r]) : "[" + f + " " + r + "]"; }; var balance = function(s) { var strt = s.match(/\(/g), stop = s.match(/\)/g); strt = strt ? strt.length : 0; stop = stop ? stop.length : 0; return { left: strt, right: stop }; }; return { // public functions balance:balance, // valid expressions eval:eval_forms, // eval expressions DICT:DICT // to add functions on demand } })(); // end META °°} _h3 3.2) the dictionary, populated on demand {prewrap °° //// 1) MATH META.DICT["+"] = function() { var a = arguments[0].split(" "), r; if (a.length === 0) r = 0; else if (a.length === 1) r = a[0]; else if (a.length === 2) r = Number(a[0]) + Number(a[1]); else for (var r = 0, i = 0; i < a.length; i++) r += Number(a[i]); return r; }; META.DICT["*"] = function() { var a = arguments[0].split(" "), r; if (a.length === 0) r = 1; else if (a.length === 1) r = a[0]; else if (a.length === 2) r = a[0] * a[1]; else for (var r = 1, i = 0; i < a.length; i++) r *= a[i]; return r; }; META.DICT["sqrt"] = function() { return Math.sqrt( arguments[0] ); }; META.DICT["fac"] = function() { var fac = function(n) { return (n<1) ? 1 : n*fac(n-1); }; return fac( arguments[0].trim() ) }; // ... and so on. //// 2) HTML var htmltags = [ 'div', 'span', 'a', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'table', 'tr', 'td', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'b', 'i', 'u', 'center', 'br', 'hr', 'blockquote', 'del', 'sup', 'sub', 'code', 'img', 'pre']; // catch HTML attributes: META.DICT['@'] = function() { return '@@' + arguments[0] + '@@' }; // translate HTML tags to META tags: for (var i=0; i< htmltags.length; i++) { META.DICT[htmltags[i]] = function(tag) { return function() { var args = arguments[0].trim(); // save spaces for pre var attr = args.match( /@@[\s\S]*?@@/ ); if (attr == null) { return '<'+tag+'>'+args+'< /'+tag+'>'; } else { args = args.replace( attr[0], '' ).trim(); attr = attr[0].replace(/^@@/, '').replace(/@@$/, ''); return '<'+tag+' '+attr+'>'+args+'< /'+tag+'>'; } } }(htmltags[i]); } °°} _h3 3.3) the HTML interface {prewrap °° var meta_evaluate = function() { var input = document.getElementById('input').value; var output = '...'; var bal = META.balance( input ); document.getElementById('infos').innerHTML = '('+bal.left+'|'+bal.right+')'; if (bal.left === bal.right) document.getElementById('output').innerHTML = META.eval( input ); }; setTimeout( meta_evaluate, 1 ); °°} _h3 3.4) the console {prewrap °° {textarea {@ id="input" onkeyup="meta_evaluate()"} ... meta code ... } {center {@ id="infos"}...} {div {@ id="output"}...} °°} {script var META = (function() { //// EVALUATOR var DICT = {}; var regexp = /\(([^\s()]*)(?:[\s]*)([^()]*)\)/g; // iterative form var __eval_forms = function(s) { while (s !== (s = s.replace(regexp, eval_form))); return s; }; // recursive form var eval_forms = function(s) { return ( s !== (s = s.replace(regexp, eval_form)) ) ? eval_forms(s) : s; }; var eval_form = function() { var f = arguments[1] || "", r = arguments[2] || ""; return DICT.hasOwnProperty(f) ? DICT[f].apply(null, [r]) : "[" + f + " " + r + "]"; }; var balance = function(s) { var strt = s.match(/\(/g), stop = s.match(/\)/g); strt = strt ? strt.length : 0; stop = stop ? stop.length : 0; return { left: strt, right: stop }; }; return { // public functions balance:balance, // valid expressions eval:eval_forms, // eval expressions DICT:DICT // to add functions on demand } })(); // end META //// DICTIONARY (populated on demand) //// MATH META.DICT["+"] = function() { var a = arguments[0].split(" "), r; if (a.length === 0) r = 0; else if (a.length === 1) r = a[0]; else if (a.length === 2) r = Number(a[0]) + Number(a[1]); else for (var r = 0, i = 0; i < a.length; i++) r += Number(a[i]); return r; }; META.DICT["*"] = function() { var a = arguments[0].split(" "), r; if (a.length === 0) r = 1; else if (a.length === 1) r = a[0]; else if (a.length === 2) r = a[0] * a[1]; else for (var r = 1, i = 0; i < a.length; i++) r *= a[i]; return r; }; META.DICT["sqrt"] = function() { return Math.sqrt( arguments[0] ); }; META.DICT["fac"] = function() { var fac = function(n) { return (n<1) ? 1 : n*fac(n-1); }; return fac( arguments[0].trim() ) }; // ... and so on. //// HTML var htmltags = [ 'div', 'span', 'a', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'table', 'tr', 'td', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'b', 'i', 'u', 'center', 'br', 'hr', 'blockquote', 'del', 'sup', 'sub', 'code', 'img', 'pre']; // catch HTML attributes: META.DICT['@'] = function() { return '@@' + arguments[0] + '@@' }; // translate HTML tags to META tags: for (var i=0; i< htmltags.length; i++) { META.DICT[htmltags[i]] = function(tag) { return function() { var args = arguments[0].trim(); // save spaces for pre var attr = args.match( /@@[\s\S]*?@@/ ); if (attr == null) { return '<'+tag+'>'+args+''+tag+'>'; } else { args = args.replace( attr[0], '' ).trim(); attr = attr[0].replace(/^@@/, '').replace(/@@$/, ''); return '<'+tag+' '+attr+'>'+args+''+tag+'>'; } } }(htmltags[i]); } //// HTML INTERFACE var meta_evaluate = function() { var input = document.getElementById('input').value; var output = '...'; var bal = META.balance( input ); document.getElementById('infos').innerHTML = '('+bal.left+'|'+bal.right+')'; if (bal.left === bal.right) document.getElementById('output').innerHTML = META.eval( input ); }; //// INSIDE THE WIKI PAGE /* {textarea {@ id="input" onkeyup="meta_evaluate()"} ... meta code ... } {center {@ id="infos"}...} {div {@ id="output"}...} */ setTimeout( meta_evaluate, 1 ); } {style pre { background:#eee; } textarea { background:#ccc; color:#000; width:98%; height:600px; border:0; font:normal 1.1em courier; padding:1%; } }
lambdaway v.20211111