lambdaway
::
lambdacode
4
|
list
|
login
|
load
|
|
_img http://lambdaway.free.fr/workshop/data/mies_pav.jpg _h1 lambdacode {sup ( 1 | [[2|?view=lambdacode2]] | [[3|?view=lambdacode3]] | [[4|?view=lambdacode4]] | [[5|?view=lambdacode5]]) } _p Everything in the {b LISP} world began with the initial code of John McCarthy on which worked a lot of good people, Abelson & Sussman, Paul Graham, and several others. {b Peter Norvig} wrote a smart and well documented LISP interpreter in the PYTHON language, [[lispy|http://norvig.com/lispy.html]]. A few young coders, {b Sreedathns, Sainamdar} and others, proposed their own translations in Javascript which inspired me greatly. {b (lambda code)} is my (last) translation of the Peter Norvig's LISP engine, replacing pairs and lists by arrays and adding strings and HTML/CSS capabilities. _p This is a standard {b AST} evaluator, {b tokenizing} the input string, building an {b abstract syntaxic tree} and {b parsing} it, whose kernel is built in less than 100 JS lines. A first set of primitives is given for HTML/CSS/SVG/JS and a small linrary on big numbers. _p Just write in the wiki page {pre '{AST ... any valid code ... } } _p to get its evaluation done in real time. Currently this is a first example: {AST (@ 1. evaluation) ' '(div (@ style="font:italic 3.0em papyrus") (@ hello world)) ' (div (@ style="font:italic 3.0em papyrus") (@ hello world)) '(sqrt (+ (* 3 3) (* 4 4))) (sqrt (+ (* 3 3) (* 4 4))) ' (@ 2. IIFE: Immediately Invoked Function Expression) ' '((lambda (x y) (sqrt (+ (* x x) (* y y)))) 3 4) ((lambda (x y) (sqrt (+ (* x x) (* y y)))) 3 4) ' (@ 3. abstraction and application) ' '(def hypo (lambda (x y) (sqrt (+ (* x x) (* y y))))) (def hypo (lambda (x y) (sqrt (+ (* x x) (* y y))))) ' '(hypo 3 4) (hypo 3 4) ' '(hypo 1 1) (hypo 1 1) ' (@ 4. quoting) ' ''hello 'hello ' '(@ hello world) (@ hello world) ' '(join '1+2 '= (+ 1 2)) (join '1+2 '= (+ 1 2)) ' (@ 5. closure) ' '(def closure (lambda (a) (lambda (b) (* a b)))) (def closure (lambda (a) (lambda (b) (* a b)))) ' '((closure 3) 4) ((closure 3) 4) ' '(def triangle (lambda (a b c) ((lambda (s) (sqrt (* s (- s a) (- s b) (- s c))) ) (/ (+ a b c) 2)) )) (def triangle (lambda (a b c) ((lambda (s) (sqrt (* s (- s a) (- s b) (- s c)))) (/ (+ a b c) 2)))) ' '(triangle 3 4 5) (triangle 3 4 5) ' (@ 6. recursion) ' (def fac (lambda (n) (if (< n 1) 1 (* n (fac (- n 1)))))) '(def fac (lambda (n) (if (< n 1) 1 (* n (fac (- n 1)))))) ' '(fac 100) (fac 100) ' '(FAC 100) (FAC 100) ' '(lib) (lib) } _h2 notes _ul 1) During the tokenization line returns are broken leading to a bad display of these code {prewrap (def fac (lambda (n) (if (< n 1) 1 (* n (fac (- n 1)))))) (def triangle (lambda (a b c) ((lambda (s) (sqrt (* s (- s a) (- s b) (- s c)))) (/ (+ a b c) 2)))) } _p These code should be displayed like this {pre (def fac (lambda (n) (if (< n 1) 1 (* n (fac (- n 1)))))) (def triangle (lambda (a b c) ((lambda (s) (sqrt (* s (- s a) (- s b) (- s c)))) (/ (+ a b c) 2)))) } _ul 2) ... _p Any help is welcome. _h2 other examples _p The following examples can be copied and pasted in the AST container. {pre (@ 1. evaluation) (sqrt (+ (* 3 3) (* 4 4))) ' (@ 2. IIFE: Immediately Invoked Function Expression) ((lambda (x y) (sqrt (+ (* x x) (* y y)))) 3 4) ' (@ 3. abstraction) (def hypo (lambda (x y) (sqrt (+ (* x x) (* y y))))) ' (@ 4. application) (hypo 3 4) (hypo 1 1) ' (@ 5. protection) 'hello (@ hello world) (@ hello (+ 1 2)) (join 'hello (+ 1 2)) ' (@ 6. primitives) (lib) ========= A) first tests 'hello 'world (@ hello world) (+ 1 (* 2 3) 4) (sqrt (+ (* 3 3) (* 4 4))) (def hypo (lambda (x y) (sqrt (+ (* x x) (* y y))))) (hypo 3 4) (hypo 1 1) (def triangle (lambda (:a :b :c) ((lambda (:s) (sqrt (* :s (- :s :a) (- :s :b) (- :s :c))) ) (/ (+ :a :b :c) 2)) )) (triangle 3 4 5) (def fac (lambda (n) (if (< n 1) 1 (* n (fac (- n 1)))))) (fac 100) (def closure (lambda (a) (lambda (b) (* a b)))) (closure 3) ((closure 3) 4) B) booleans, pairs, lists & recursion exclusively built on lambdas (def TRUE (lambda (x y) x)) (def FALSE (lambda (x y) y)) (def IF (lambda (x y z) (x y z))) (def PAIR (lambda (x y) (lambda (z) (z x y)))) (def LEFT (lambda (z) (z TRUE))) (def RIGHT (lambda (z) (z FALSE))) (def NIL (lambda (s z) z)) (def ISNIL (lambda (n) (n (lambda (x) FALSE) TRUE))) '--- (def DISP (lambda (list) ((IF (ISNIL list) (lambda (list) '.) (lambda (list) (join (LEFT list) (DISP (RIGHT list)) )) ) list))) '--- (def FRUITS (PAIR 'apple (PAIR 'banana (PAIR 'lemon (PAIR 'grapes (PAIR 'orange NIL)))))) (DISP FRUITS) C) arrays for everything (def A (#.new 1 2 3 4 5)) A (#.length A) (def map (lambda (f x y) (if (#.empty? x) y (map f (#.rest x) (#.push! y (f (#.first x))))))) (map (lambda(x) (* x x)) A (#.new)) ... D) HTML/CSS (center (@ hello world)) (div (@ style="font-size:3.0em;") (@ hello world)) (img (@ src="data/amelie_poulain.jpg" width="100px") '.) (p (a (@ href="http://www.pixar.com") 'PIXAR)) (svg (@ width="100%" height="200px" style="background:#eee;") (join (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") '.) )) } _h2 javscript code _h3 1) the function AST {pre °° LAMBDATALK.DICT['AST'] = function() { var cod = arguments[0]; var val = LC.parser( cod ); var infos = '(' + val.bal[0] + '|' + val.bal[1] + ') ' + val.time + ' ms'; var evaluation = ( val.bal[0] !== val.bal[1] ) ? cod : val.val; return '< center>' + infos + '< /center>' + '< pre>' + evaluation + '< /pre>' }; °°} _h3 2) the kernel {pre °° var LC = (function () { var DICT = create_env([],[]); var parser = function ( str ) { var t0 = new Date().getTime(); str = '(console ' + str + ')'; str = pre_processing( str ); var bal = balance( str ); if (bal[0] == bal[1]) { str = tokenize( str ); // 1) a flat array str = build_tree( tokenize( str ); // 2) a nested array str = evaluate( str ); // 3) evaluation } var t1 = new Date().getTime(); return { val:str, bal:bal, time:t1-t0 }; }; var evaluate = function (x, env) { // the magic function env = env || DICT; if ( isNumber(x) ) { return x; } else if ( isWord(x) ) { return x.substring(1); } else if ( isOp(x) ) { return env.find(x)[x]; } else if ( x[0] === 'quote' ) { return array2string( x.slice(1) ); } else if ( x[0] === '@' ) { return x.slice(1).join(' '); } else if ( x[0] === 'if' ) { return evaluate( (evaluate( x[1], env)? x[2] : x[3]), env ); } else if ( x[0] === 'lambda' ) { return function () { var new_env = create_env( x[1], arguments, env ); return evaluate( x[2], new_env ); } } else if ( x[0] === 'def' ) { env[x[1]] = evaluate( x[2], env ); return '#: ' + x[1]; } else { for (var xx = [], i=0; i < x.length; i++) xx[i] = evaluate( x[i], env ); var proc = xx.shift(); return proc.apply(null, xx); } }; var tokenize = function ( s ) { return s.replace(/\(/g, ' ( ') .replace(/\)/g, ' ) ') .trim().split(/\s+/); }; 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 isNumber = function (x) { return !isNaN(parseFloat(x)) && isFinite(x) }; var isWord = function (x) { return typeof x === 'string' && x.charAt(0) === '\'' }; var isOp = function (x) { return typeof x === 'string' }; var array2string = function(x) { return JSON.stringify( x ).replace( /\[/g, '(' ) .replace( /\]/g, ')' ) .replace( /"/g, '' ) .replace( /,/g, ' ' ) }; var balance = function ( str ) { var acc_open = str.match( /\(/g ); var acc_close = str.match( /\)/g ); var nb_acc_open = (acc_open)? acc_open.length : 0; var nb_acc_close = (acc_close)? acc_close.length : 0; return [nb_acc_open , nb_acc_close]; }; var pre_processing = function( str ) { str = str.replace( /'\(/g, "(quote " ); return str }; var create_env = function (args,vals,out) { var env = {}, outer = out || {}; if (args.length !== 0) for (var i=0; i < args.length; i++) env[args[i]] = vals[i]; env.find = function (op) { return (env.hasOwnProperty(op))? env : outer.find(op) }; return env; } return { parser, DICT } }()); °°} _h3 3) populating the dictionary {prewrap °° LC.DICT['lib'] = function() { var str = '', index = 0; for (var key in LC.DICT) { if(LC.DICT.hasOwnProperty(key)) { str += key + ', '; index++; } } return '
DICT:
('+ index+') [ '+ str.substring(0,str.length-2)+' ]
'; }; LC.DICT['console'] = function(){ return [].slice.call(arguments).join('\n') }; LC.DICT['join'] = function() { return [].slice.call(arguments).join(' ') }; LC.DICT['+'] = function () { for (var r=0, i=0; i < arguments.length; i++) { r += Number( arguments[i] ) } return r; }; LC.DICT['*'] = function () { for (var r=1, i=0; i < arguments.length; i++) { r *= arguments[i] } return r; }; LC.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; }; LC.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; }; LC.DICT['%'] = function () { return parseFloat(arguments[0]) % parseFloat(arguments[1]) }; LC.DICT['<'] = function(){ return parseFloat(arguments[0]) < parseFloat(arguments[1]) }; LC.DICT['>'] = function(){ return parseFloat(arguments[0]) > parseFloat(arguments[1]) }; LC.DICT['<='] = function(){ return parseFloat(arguments[0]) <= parseFloat(arguments[1]) }; LC.DICT['>='] = function(){ return parseFloat(arguments[0]) >= parseFloat(arguments[1]) }; LC.DICT['='] = function () { var a = parseFloat(arguments[0]), b = parseFloat(arguments[1]); return !(a < b) && !(b < a) }; LC.DICT['not'] = function () { return !arguments[0] }; LC.DICT['or'] = function () { for (var i=0; i< arguments.length; i++) { if (arguments[i]) return true } return false; }; LC.DICT['and'] = function () { for (var i=0; i< arguments.length; i++) { if (arguments[i]) return false } return true; }; LC.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++) { LC.DICT[mathfns[i]] = Math[mathfns[i]] } LC.DICT['PI'] = function() { return Math.PI }; LC.DICT['E'] = function() { return Math.E }; LC.DICT['#.new'] = function() { return [].slice.call(arguments) }; LC.DICT['#.array?'] = function() { return Array.isArray( arguments[0] ) }; LC.DICT['#.disp'] = function() { var args = arguments[0]; return ( Array.isArray( args ) )? JSON.stringify( args ) : args }; LC.DICT['#.length'] = function() { return arguments[0].length }; LC.DICT['#.empty?'] = function() { return arguments[0].length === 0 }; LC.DICT['#.first'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args[0] : args }; LC.DICT['#.last'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args[args.length-1] : args }; LC.DICT['#.rest'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args.slice(1) : args }; LC.DICT['#.get'] = function() { var val = arguments[0][arguments[1]]; return (val !== undefined)? val : 'undefined' }; LC.DICT['#.slice'] = function() { return arguments[0].slice(arguments[1],arguments[2]) }; LC.DICT['#.concat'] = function() { return arguments[0].concat( arguments[1] ) }; LC.DICT['#.reverse'] = function() { return arguments[0].reverse() }; LC.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 } ) }; LC.DICT['#.set!'] = function() { arguments[0][arguments[1]] = arguments[2] return arguments[0] }; LC.DICT['#.pop!'] = function() { return arguments[0].pop() }; LC.DICT['#.shift!'] = function() { return arguments[0].shift() }; LC.DICT['#.push!'] = function() { arguments[0].push( arguments[1] ) return arguments[0]; }; LC.DICT['#.unshift!'] = function() { arguments[0].unshift( arguments[1] ) return arguments[0]; }; 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++) { LC.DICT[htmltags[i]] = function(tag) { return function() { var html = (arguments.length === 2)? "{"+tag+' {@ '+arguments[0]+'}'+arguments[1]+'}' : "{"+tag+' '+arguments[0]+'}'; return LAMBDATALK.eval_forms( html ); } }(htmltags[i]); } °°} {style body, #page_frame, #page_content, .page_menu, pre { background:#444; color:#fff; border:0 #444; box-shadow:0 0 0 #444; } pre { box-shadow:0 0 8px #000; padding:10px; } textarea {width:99%; height:1500px; background:#444; color:#fff; box-shadow:0 0 8px #000; border:0 #444; font:normal 1.0em courier; } } {script LAMBDATALK.DICT['AST'] = function() { var cod = arguments[0]; var val = LC.parser( cod ); var infos = '(' + val.bal[0] + '|' + val.bal[1] + ') ' + val.time + ' ms'; var evaluation = ( val.bal[0] !== val.bal[1] ) ? cod : val.val; return '
' + infos + '
' + '
' + evaluation + '
' }; var LC = (function () { var create_env = function (args,vals,out) { var env = {}, outer = out || {}; if (args.length !== 0) for (var i=0; i < args.length; i++) env[args[i]] = vals[i]; env.find = function (op) { return (env.hasOwnProperty(op))? env : outer.find(op) }; return env; } var DICT = create_env([],[]); var isNumber = function (x) { return !isNaN(parseFloat(x)) && isFinite(x) }; var isWord = function (x) { return typeof x === 'string' && x.charAt(0) === '\'' }; var isOp = function (x) { return typeof x === 'string' }; var array2string = function(x) { return JSON.stringify( x ).replace( /\[/g, '(' ) .replace( /\]/g, ')' ) .replace( /"/g, '' ) .replace( /,/g, ' ' ) // .replace( /^\(/g, '' ) // .replace( /\)$/g, '' ) }; var evaluate = function (x, env) { env = env || DICT; if ( isNumber(x) ) { return x; } else if ( isWord(x) ) { return x.substring(1); } else if ( isOp(x) ) { return env.find(x)[x]; } else if ( x[0] === 'quote' ) { return array2string( x.slice(1) ); } else if ( x[0] === '@' ) { return x.slice(1).join(' '); } else if ( x[0] === 'if' ) { return evaluate( (evaluate( x[1], env)? x[2] : x[3]), env ); } else if ( x[0] === 'lambda' ) { return function () { var new_env = create_env( x[1], arguments, env ); return evaluate( x[2], new_env ); } } else if ( x[0] === 'def' ) { env[x[1]] = evaluate( x[2], env ); return '#: ' + x[1]; } else { for (var xx = [], i=0; i < x.length; i++) xx[i] = evaluate( x[i], env ); var proc = xx.shift(); return proc.apply(null, xx); } }; var balance = function ( str ) { var acc_open = str.match( /\(/g ); var acc_close = str.match( /\)/g ); var nb_acc_open = (acc_open)? acc_open.length : 0; var nb_acc_close = (acc_close)? acc_close.length : 0; return [nb_acc_open , nb_acc_close]; }; var tokenize = function ( s ) { return s.replace(/\(/g, ' ( ') .replace(/\)/g, ' ) ') .trim().split(/\s+/); }; 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 pre_processing = function( str ) { // str = str.replace( /\;\;.*?\n/g, "" ); // error regexp str = str.replace( /'\(/g, "(quote " ); return str }; var parser = function ( str ) { var t0 = new Date().getTime(); str = pre_processing( str ); var bal = balance( str ); if (bal[0] == bal[1]) { str = str.replace( /\n/g, " " ) str = '(console ' + str + ')'; str = evaluate( build_tree( tokenize( str ) ) ); } var t1 = new Date().getTime(); return { val:str, bal:bal, time:t1-t0 }; }; return { parser, DICT } }()); LC.DICT['lib'] = function() { var str = '', index = 0; for (var key in LC.DICT) { if(LC.DICT.hasOwnProperty(key)) { str += key + ', '; index++; } } return '
DICT:
('+ index+') [ '+ str.substring(0,str.length-2)+' ]
'; }; LC.DICT['console'] = function(){ return [].slice.call(arguments).join('\n') }; LC.DICT['join'] = function() { return [].slice.call(arguments).join(' ') }; LC.DICT['+'] = function () { for (var r=0, i=0; i < arguments.length; i++) { r += Number( arguments[i] ) } return r; }; LC.DICT['*'] = function () { for (var r=1, i=0; i < arguments.length; i++) { r *= arguments[i] } return r; }; LC.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; }; LC.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; }; LC.DICT['%'] = function () { return parseFloat(arguments[0]) % parseFloat(arguments[1]) }; LC.DICT['<'] = function(){ return parseFloat(arguments[0]) < parseFloat(arguments[1]) }; LC.DICT['>'] = function(){ return parseFloat(arguments[0]) > parseFloat(arguments[1]) }; LC.DICT['<='] = function(){ return parseFloat(arguments[0]) <= parseFloat(arguments[1]) }; LC.DICT['>='] = function(){ return parseFloat(arguments[0]) >= parseFloat(arguments[1]) }; LC.DICT['='] = function () { var a = parseFloat(arguments[0]), b = parseFloat(arguments[1]); return !(a < b) && !(b < a) }; LC.DICT['not'] = function () { return !arguments[0] }; LC.DICT['or'] = function () { for (var i=0; i< arguments.length; i++) { if (arguments[i]) return true } return false; }; LC.DICT['and'] = function () { for (var i=0; i< arguments.length; i++) { if (arguments[i]) return false } return true; }; LC.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++) { LC.DICT[mathfns[i]] = Math[mathfns[i]] } LC.DICT['PI'] = function() { return Math.PI }; LC.DICT['E'] = function() { return Math.E }; LC.DICT['#.new'] = function() { return [].slice.call(arguments) }; LC.DICT['#.array?'] = function() { return Array.isArray( arguments[0] ) }; LC.DICT['#.disp'] = function() { var args = arguments[0]; return ( Array.isArray( args ) )? JSON.stringify( args ) : args }; LC.DICT['#.length'] = function() { return arguments[0].length }; LC.DICT['#.empty?'] = function() { return arguments[0].length === 0 }; LC.DICT['#.first'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args[0] : args }; LC.DICT['#.last'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args[args.length-1] : args }; LC.DICT['#.rest'] = function() { var args = arguments[0]; return (Array.isArray( args ))? args.slice(1) : args }; LC.DICT['#.get'] = function() { var val = arguments[0][arguments[1]]; return (val !== undefined)? val : 'undefined' }; LC.DICT['#.slice'] = function() { return arguments[0].slice(arguments[1],arguments[2]) }; LC.DICT['#.concat'] = function() { return arguments[0].concat( arguments[1] ) }; LC.DICT['#.reverse'] = function() { return arguments[0].reverse() }; LC.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 } ) }; LC.DICT['#.set!'] = function() { arguments[0][arguments[1]] = arguments[2] return arguments[0] }; LC.DICT['#.pop!'] = function() { return arguments[0].pop() }; LC.DICT['#.shift!'] = function() { return arguments[0].shift() }; LC.DICT['#.push!'] = function() { arguments[0].push( arguments[1] ) return arguments[0]; }; LC.DICT['#.unshift!'] = function() { arguments[0].unshift( arguments[1] ) return arguments[0]; }; 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++) { LC.DICT[htmltags[i]] = function(tag) { return function() { var html = (arguments.length === 2)? "{"+tag+' {@ '+arguments[0]+'}'+arguments[1]+'}' : "{"+tag+' '+arguments[0]+'}'; return LAMBDATALK.eval_forms( html ); } }(htmltags[i]); } } {script var BI = (function() { var N2A = function(n) { return n.toString().split('').reverse() }; var A2N = function(a) { return a.reverse().join('') }; var ADD = function(a,b) { var n = Math.max(a.length, b.length), c = []; for (var i=0; i < n; i++) { // equalizing to max length a[i] = (a[i])? parseInt(a[i]) : 0; b[i] = (b[i])? parseInt(b[i]) : 0; c[i] = a[i] + b[i]; // adding digits } for (var i=0; i < n; i++) { // carrying if (c[i] > 9) { c[i] -= 10; c[i+1] = (c[i+1])? c[i+1] + 1 : 1; } } return c }; var MUL = function(a,b) { var c = []; for (var i=0; i < b.length; i++ ) { // c = a * b var d = [], e = []; for (var j=0; j < b[i]; j++) { d = ADD(a,d) } // d = a * b[i] for (var j=0; j < i; j++) { e[j] = 0 } // delta i c = ADD(c,e.concat(d)); } return c }; return { N2A, A2N, ADD, MUL } })(); LC.DICT['N2A'] = function() { return BI.N2A(arguments[0]) }; LC.DICT['A2N'] = function() { return BI.A2N(JSON.parse(arguments[0])) }; LC.DICT['ADD'] = function() { return BI.A2N(BI.ADD(BI.N2A(arguments[0]),BI.N2A(arguments[1]))) }; LC.DICT['MUL'] = function() { return BI.A2N(BI.MUL(BI.N2A(arguments[0]),BI.N2A(arguments[1]))) }; LC.DICT['FAC'] = function() { var fac_r = function(a,b) { return (b < 1)? a : fac_r(BI.MUL(a, BI.N2A(b)), b-1) }; return BI.A2N(fac_r( BI.N2A(1), parseInt(arguments[0]) )) }; }
lambdaway v.20211111