lambdaspeech
::
lambdacode
1
[
pages
][
login
][
load
]
_h1 (lambda code) {sup (monodict)} _p (lambda code) is built on 4 special forms [{b lambda def if quote}] and a single dictionnary populated with an extendable set of primitives and user defined functions. Expressions are made of {b words} and nested forms {b (first rest)}. Words are not evaluated except those belonging to the dictionary. Words belonging to the dictionary must be quoted to prevent their evaluation, for instance you must write {b 'a} to display {b a} and prevent any unwanted evaluation. Functions arguments are added to the single dictionary and must be prefixed by a colon to avoid name conflicts, for instance {b :n}. Note that the HTML {b pre} function doesn't work as expected, carriage returns are lost, use {b (br)} instead. _h2 1. input {textarea {@ id="lc_input" onkeyup="display()" style="width:100%; height:200px; border:0; background:#eee; color:#000;"} (pre (+ 1 (* 2 3) 4) ) } {div {@ id="lc_infos" style="font:normal 1.0em courier; text-align:center;"}???} _h2 2. output {div {@ id="lc_output" style="box-shadow:0 0 8px black; padding:5px;"}} _h2 tests {pre hello world (h1 Hello World) (quote (+ 1 (* 2 3) 4)) => (+ 1 (* 2 3) 4) (hr) (div (@ style="font:bold 3.0em georgia; color:red;")Hello World) (def cons (lambda (x y) (lambda (z) (z x y)))) (def car (lambda (z) (z (lambda (x y) x)))) (def cdr (lambda (z) (z (lambda (x y) y)))) (car (cons '♥ '♠)) (cdr (cons '♥ '♠)) (def fac (lambda (:n) (if (< :n 1) 1 (* :n (fac (- :n 1)))))) (hr) (fac 6) (hr) (svg (@ width="100%" height="200px" style="background:#eee;") (polyline (@ points="10 10 100 190 100 10 580 10" stroke-width="1" stroke="#888" fill="transparent")) (path (@ d="M 10 10 C 100 190 100 10 580 10" stroke-width="3" stroke="#f00" fill="transparent")) ) (hr) (br)(def A (#.new 12 34 56 78 90)) (#.disp A) (br)(#.get A 0) (#.get A 1) (#.get A 2) (#.get A 3) (#.get A 4) (#.get A 5) (hr) (br)(#.slice A 1 3) (br)(#.reverse A) (br)(def B (#.new 3 1 -1 10 11 0)) (br)(#.sort B up) (br)(def C (#.new 3 1 -1 10 11 0)) (#.disp C) (br)(#.sort C 'down) (br)(#.concat (#.new 12 34) (#.new 56 78)) (hr) (br)(quote (def D (#.new 12 34 56 78))) (def D (#.new 12 34 56 78)) (br)(#.pop! D) -> (#.disp D) (br)(#.shift! D) -> (#.disp D) (br)(#.push! D 'yes) -> (#.disp D) (br)(#.unshift! D 'no) -> (#.disp D) (br)(#.set! D 1 90) -> (#.disp D) (hr) (def display (lambda (arr) (if (#.empty? arr) . (join (#.first arr) (display (#.rest arr)))))) (def mylength (lambda (arr) (if (#.empty? arr) 0 (+ 1 (mylength (#.rest arr)))))) (def squared (lambda (arr) (if (#.empty? arr) . (join (* (#.first arr) (#.first arr)) (squared (#.rest arr)))))) (hr) (br)(display A) (br)(mylength A) (br)(squared A) } _h2 code {pre °° var MICRO = (function() { var DICT = {}; var balance = function ( str ) { var l = str.match( /\(/g ); var r = str.match( /\)/g ); l = (l)? l.length : 0; r = (r)? r.length : 0; return [l,r]; }; var build_tree = function (tokens) { var token = tokens.shift(); if (token !== '(') return token; var arr = []; while (tokens[0] !== ')') arr.push( build_tree(tokens) ); tokens.shift(); return arr; }; var tokenize = function ( s ) { s = s.replace(/\(/g, ' ( ') .replace(/\)/g, ' ) ') .trim(); return s.split(/\s+/) }; var isWord = function (x) { return typeof x === 'string' && !DICT.hasOwnProperty(x) }; var isqWord = function (x) { return typeof x === 'string' && (x.charAt(0) === "'") }; var isOp = function (x) { return typeof x === 'string' && DICT.hasOwnProperty(x) }; var eval_word = function(x) { return x }; var eval_qword = function(x) { return x.substring(1) }; var eval_op = function(x) { return DICT[x] }; var eval_quote = function(x) { return JSON.stringify( x.slice(1)[0] ) .replace( /\[/g, '(' ) .replace( /\]/g, ')' ) .replace( /"/g, '' ) .replace( /,/g, ' ' ) }; var eval_if = function(x) { return evaluate( (evaluate( x[1] )? x[2] : x[3]) ) }; var eval_lambda = function(x) { return function() { var args = x[1], body = x[2]; for (var i=0; i < args.length; i++) DICT[args[i]] = arguments[i]; return evaluate( body ); } }; var eval_def = function(x) { DICT[x[1]] = evaluate( x[2] ); }; var eval_apply = function(x) { for (var xx=[], i=0; i< x.length; i++) xx[i] = evaluate(x[i]); var func = xx.shift(); return func.apply(null,xx); }; var evaluate = function(x) { if ( isqWord(x) ) return eval_qword(x); else if ( isWord(x) ) return eval_word(x); else if ( isOp(x) ) return eval_op(x); else if ( x[0] === 'quote' ) return eval_quote(x); else if ( x[0] === 'if' ) return eval_if(x); else if ( x[0] === 'lambda' ) return eval_lambda(x); else if ( x[0] === 'def' ) return eval_def(x); else return eval_apply(x); }; var preprocessing = function(s) { s = s.replace(/\;\;.*?\n/g, ''); s = "(root " + s + ")"; return s }; var postprocessing = function(s) { return s }; var parse = function( s ) { var val = s, bal = balance(s); if (bal[0] === bal[1]) { s = preprocessing( s ); s = evaluate( build_tree( tokenize( s ))); s = postprocessing( s ); } return {val:s,bal:bal} }; return {parse:parse, DICT:DICT} })(); °°} _h2 dictionary {pre {@ style="white-space:pre-wrap"} °° MICRO.DICT['lib'] = function() { var str = '', index = 0; for (var key in MICRO.DICT) { if(MICRO.DICT.hasOwnProperty(key)) { str += key + ', '; index++; } } return '
DICT:
('+ index+') [ '+ str.substring(0,str.length-2)+' ]
'; }; MICRO.DICT['root'] = function(){ return [].slice.call(arguments).join('\n') }; MICRO.DICT['join'] = function() { return [].slice.call(arguments).join(' ') }; MICRO.DICT['+'] = function () { for (var r=0, i=0; i < arguments.length; i++) { r += Number( arguments[i] ) } return r; }; MICRO.DICT['*'] = function () { for (var r=1, i=0; i < arguments.length; i++) { r *= arguments[i] } return r; }; MICRO.DICT['-'] = function () { var r = arguments[0]; if (arguments.length === 1) { r = -r; } else { for (var i=1; i < arguments.length; i++) { r -= arguments[i] } } return r; }; MICRO.DICT['/'] = function () { var r = arguments[0]; if (arguments.length === 1) { r = 1/r; } else { for (var i=1; i < arguments.length; i++) { r /= arguments[i] } } return r; }; MICRO.DICT['%'] = function () { return parseFloat(arguments[0]) % parseFloat(arguments[1]) }; MICRO.DICT['<'] = function(){ return parseFloat(arguments[0]) < parseFloat(arguments[1]) }; MICRO.DICT['>'] = function(){ return parseFloat(arguments[0]) > parseFloat(arguments[1]) }; MICRO.DICT['<='] = function(){ return parseFloat(arguments[0]) <= parseFloat(arguments[1]) }; MICRO.DICT['>='] = function(){ return parseFloat(arguments[0]) >= parseFloat(arguments[1]) }; MICRO.DICT['='] = function () { var a = parseFloat(arguments[0]), b = parseFloat(arguments[1]); return !(a < b) && !(b < a) }; MICRO.DICT['not'] = function () { return !arguments[0] }; MICRO.DICT['or'] = function () { for (var i=0; i< arguments.length; i++) { if (arguments[i]) return true } return false; }; MICRO.DICT['and'] = function () { for (var i=0; i< arguments.length; i++) { if (arguments[i]) return false } return true; }; MICRO.DICT['equal?'] = function(a, b){ return a === b }; var mathfns = ['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan']; for (var i=0; i < mathfns.length; i++) { MICRO.DICT[mathfns[i]] = Math[mathfns[i]] } MICRO.DICT['PI'] = function() { return Math.PI }; MICRO.DICT['E'] = function() { return Math.E }; MICRO.DICT['#.new'] = function() { return [].slice.call(arguments) }; MICRO.DICT['#.array?'] = function() { return Array.isArray( arguments[0] ) }; MICRO.DICT['#.disp'] = function() { var args = arguments[0]; return ( Array.isArray( args ) )? JSON.stringify( args ) : args }; MICRO.DICT['#.length'] = function() { return arguments[0].length }; MICRO.DICT['#.empty?'] = function() { return arguments[0].length === 0 }; MICRO.DICT['#.first'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args[0] : args }; MICRO.DICT['#.last'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args[args.length-1] : args }; MICRO.DICT['#.rest'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args.slice(1) : args }; MICRO.DICT['#.get'] = function() { var val = arguments[0][arguments[1]]; return (val !== undefined)? val : 'undefined' }; MICRO.DICT['#.slice'] = function() { return arguments[0].slice(arguments[1],arguments[2]) }; MICRO.DICT['#.concat'] = function() { return arguments[0].concat( arguments[1] ) }; MICRO.DICT['#.reverse'] = function() { return arguments[0].reverse() }; MICRO.DICT['#.sort'] = function() { return (arguments[1] === 'up')? arguments[0].sort( function(a,b) { return a - b } ) : arguments[0].sort( function(a,b) { return b - a } ) }; MICRO.DICT['#.set!'] = function() { arguments[0][arguments[1]] = arguments[2] return arguments[0] }; MICRO.DICT['#.pop!'] = function() { return arguments[0].pop() }; MICRO.DICT['#.shift!'] = function() { return arguments[0].shift() }; MICRO.DICT['#.push!'] = function() { arguments[0].push( arguments[1] ) return arguments[0]; }; MICRO.DICT['#.unshift!'] = function() { arguments[0].unshift( arguments[1] ) return arguments[0]; }; MICRO.DICT['@'] = function() { var attr = [].slice.call(arguments); return s = ["@@",attr] }; 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', 'hr', 'br', 'blockquote', 'sup', 'sub', 'del', 'code', 'img', 'pre', 'textarea', 'canvas', 'audio', 'video', 'source', 'select', 'option', 'object', 'svg', 'line', 'rect', 'circle', 'ellipse', 'polygon', 'polyline', 'path', 'text', 'g', 'mpath', 'use', 'textPath', 'pattern', 'image', 'clipPath', 'defs', 'animate', 'set', 'animateMotion', 'animateTransform' ]; for (var i=0; i < htmltags.length; i++) { MICRO.DICT[htmltags[i]] = function(tag) { return function() { var s = ''; if (arguments.length === 0) { s = "<" + tag + " />" } else { var arr = [].slice.call(arguments); if (arr[0][0] === '@@') { var attr = arr.shift()[1].join(' '); var txt = arr.join(' '); s = "<" + tag + " " + attr + ">" + txt + "" + tag + ">" } else { var txt = (arr)? arr.join(' ') : '' ; s = "<" + tag + ">" + txt + "" + tag + ">" } } return s } }(htmltags[i]); } °°} _h2 HTML INTERFACE {pre °° var display = function() { var start = new Date().getTime(); var code = document.getElementById('lc_input').value; var value = MICRO.parse( code ); var dt = new Date().getTime() - start; document.getElementById('lc_infos').innerHTML = '(' + value.bal + ') | [' + dt +'ms]'; if (value.bal[0] === value.bal[1]) document.getElementById('lc_output').innerHTML = value.val; }; °°} {script ;; var MICRO = (function() { var DICT = {}; var balance = function ( str ) { var l = str.match( /\(/g ); var r = str.match( /\)/g ); l = (l)? l.length : 0; r = (r)? r.length : 0; return [l,r]; }; var build_tree = function (tokens) { var token = tokens.shift(); if (token !== '(') return token; var arr = []; while (tokens[0] !== ')') arr.push( build_tree(tokens) ); tokens.shift(); return arr; }; var tokenize = function ( s ) { s = s.replace(/\(/g, ' ( ') .replace(/\)/g, ' ) ') .trim(); return s.split(/\s+/) }; var isWord = function (x) { return typeof x === 'string' && !DICT.hasOwnProperty(x) }; var isqWord = function (x) { return typeof x === 'string' && (x.charAt(0) === "'") }; var isOp = function (x) { return typeof x === 'string' && DICT.hasOwnProperty(x) }; var eval_word = function(x) { return x }; var eval_qword = function(x) { return x.substring(1) }; var eval_op = function(x) { return DICT[x] }; var eval_quote = function(x) { return JSON.stringify( x.slice(1)[0] ) .replace( /\[/g, '(' ) .replace( /\]/g, ')' ) .replace( /"/g, '' ) .replace( /,/g, ' ' ) }; var eval_if = function(x) { return evaluate( (evaluate( x[1] )? x[2] : x[3]) ) }; var eval_lambda = function(x) { return function() { var args = x[1], body = x[2]; for (var i=0; i < args.length; i++) DICT[args[i]] = arguments[i]; return evaluate( body ); } }; var eval_def = function(x) { DICT[x[1]] = evaluate( x[2] ); }; var eval_apply = function(x) { for (var xx=[], i=0; i< x.length; i++) xx[i] = evaluate(x[i]); var func = xx.shift(); return func.apply(null,xx); }; var evaluate = function(x) { if ( isqWord(x) ) return eval_qword(x); else if ( isWord(x) ) return eval_word(x); else if ( isOp(x) ) return eval_op(x); else if ( x[0] === 'quote' ) return eval_quote(x); else if ( x[0] === 'if' ) return eval_if(x); else if ( x[0] === 'lambda' ) return eval_lambda(x); else if ( x[0] === 'def' ) return eval_def(x); else return eval_apply(x); }; var preprocessing = function(s) { s = s.replace(/\;\;.*?\n/g, ''); s = "(root " + s + ")"; return s }; var postprocessing = function(s) { return s }; var parse = function( s ) { var val = s, bal = balance(s); if (bal[0] === bal[1]) { s = preprocessing( s ); s = evaluate( build_tree( tokenize( s ))); s = postprocessing( s ); } return {val:s,bal:bal} }; return {parse:parse, DICT:DICT} })(); MICRO.DICT['lib'] = function() { var str = '', index = 0; for (var key in MICRO.DICT) { if(MICRO.DICT.hasOwnProperty(key)) { str += key + ', '; index++; } } return '
DICT:
('+ index+') [ '+ str.substring(0,str.length-2)+' ]
'; }; MICRO.DICT['root'] = function(){ return [].slice.call(arguments).join('\n') }; MICRO.DICT['join'] = function() { return [].slice.call(arguments).join(' ') }; MICRO.DICT['+'] = function () { for (var r=0, i=0; i < arguments.length; i++) { r += Number( arguments[i] ) } return r; }; MICRO.DICT['*'] = function () { for (var r=1, i=0; i < arguments.length; i++) { r *= arguments[i] } return r; }; MICRO.DICT['-'] = function () { var r = arguments[0]; if (arguments.length === 1) { r = -r; } else { for (var i=1; i < arguments.length; i++) { r -= arguments[i] } } return r; }; MICRO.DICT['/'] = function () { var r = arguments[0]; if (arguments.length === 1) { r = 1/r; } else { for (var i=1; i < arguments.length; i++) { r /= arguments[i] } } return r; }; MICRO.DICT['%'] = function () { return parseFloat(arguments[0]) % parseFloat(arguments[1]) }; MICRO.DICT['<'] = function(){ return parseFloat(arguments[0]) < parseFloat(arguments[1]) }; MICRO.DICT['>'] = function(){ return parseFloat(arguments[0]) > parseFloat(arguments[1]) }; MICRO.DICT['<='] = function(){ return parseFloat(arguments[0]) <= parseFloat(arguments[1]) }; MICRO.DICT['>='] = function(){ return parseFloat(arguments[0]) >= parseFloat(arguments[1]) }; MICRO.DICT['='] = function () { var a = parseFloat(arguments[0]), b = parseFloat(arguments[1]); return !(a < b) && !(b < a) }; MICRO.DICT['not'] = function () { return !arguments[0] }; MICRO.DICT['or'] = function () { for (var i=0; i< arguments.length; i++) { if (arguments[i]) return true } return false; }; MICRO.DICT['and'] = function () { for (var i=0; i< arguments.length; i++) { if (arguments[i]) return false } return true; }; MICRO.DICT['equal?'] = function(a, b){ return a === b }; var mathfns = ['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan']; for (var i=0; i < mathfns.length; i++) { MICRO.DICT[mathfns[i]] = Math[mathfns[i]] } MICRO.DICT['PI'] = function() { return Math.PI }; MICRO.DICT['E'] = function() { return Math.E }; MICRO.DICT['#.new'] = function() { return [].slice.call(arguments) }; MICRO.DICT['#.array?'] = function() { return Array.isArray( arguments[0] ) }; MICRO.DICT['#.disp'] = function() { var args = arguments[0]; return ( Array.isArray( args ) )? JSON.stringify( args ) : args }; MICRO.DICT['#.length'] = function() { return arguments[0].length }; MICRO.DICT['#.empty?'] = function() { return arguments[0].length === 0 }; MICRO.DICT['#.first'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args[0] : args }; MICRO.DICT['#.last'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args[args.length-1] : args }; MICRO.DICT['#.rest'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args.slice(1) : args }; MICRO.DICT['#.get'] = function() { var val = arguments[0][arguments[1]]; return (val !== undefined)? val : 'undefined' }; MICRO.DICT['#.slice'] = function() { return arguments[0].slice(arguments[1],arguments[2]) }; MICRO.DICT['#.concat'] = function() { return arguments[0].concat( arguments[1] ) }; MICRO.DICT['#.reverse'] = function() { return arguments[0].reverse() }; MICRO.DICT['#.sort'] = function() { return (arguments[1] === 'up')? arguments[0].sort( function(a,b) { return a - b } ) : arguments[0].sort( function(a,b) { return b - a } ) }; MICRO.DICT['#.set!'] = function() { arguments[0][arguments[1]] = arguments[2] return arguments[0] }; MICRO.DICT['#.pop!'] = function() { return arguments[0].pop() }; MICRO.DICT['#.shift!'] = function() { return arguments[0].shift() }; MICRO.DICT['#.push!'] = function() { arguments[0].push( arguments[1] ) return arguments[0]; }; MICRO.DICT['#.unshift!'] = function() { arguments[0].unshift( arguments[1] ) return arguments[0]; }; MICRO.DICT['@'] = function() { var attr = [].slice.call(arguments); return s = ["@@",attr] }; 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', 'hr', 'br', 'blockquote', 'sup', 'sub', 'del', 'code', 'img', 'pre', 'textarea', 'canvas', 'audio', 'video', 'source', 'select', 'option', 'object', 'svg', 'line', 'rect', 'circle', 'ellipse', 'polygon', 'polyline', 'path', 'text', 'g', 'mpath', 'use', 'textPath', 'pattern', 'image', 'clipPath', 'defs', 'animate', 'set', 'animateMotion', 'animateTransform' ]; for (var i=0; i < htmltags.length; i++) { MICRO.DICT[htmltags[i]] = function(tag) { return function() { var s = ''; if (arguments.length === 0) { s = "<" + tag + " />" } else { var arr = [].slice.call(arguments); if (arr[0][0] === '@@') { var attr = arr.shift()[1].join(' '); var txt = arr.join(' '); s = "<" + tag + " " + attr + ">" + txt + "" + tag + ">" } else { var txt = (arr)? arr.join(' ') : '' ; s = "<" + tag + ">" + txt + "" + tag + ">" } } return s } }(htmltags[i]); } var display = function() { var start = new Date().getTime(); var code = document.getElementById('lc_input').value; var value = MICRO.parse( code ); var dt = new Date().getTime() - start; document.getElementById('lc_infos').innerHTML = '(' + value.bal + ') | [' + dt +'ms]'; if (value.bal[0] === value.bal[1]) document.getElementById('lc_output').innerHTML = value.val; }; setTimeout( display, 1 ) }
lambdaspeech v.20180812