+
1
|
list
|
skin
|
login
|
editor
α-wwwiki
::
lisp_evaluator
user:none
(3232 bytes)
_h1 alphalisp evaluator {sup (4)} {div {@ style="text-align:center; color:red; background:#eee;box-shadow:0 0 8px black;"} [[basic evaluator|?view=basic_evaluator]] | [[extended eval|?view=extended_evaluator]] | [[regexp eval|?view=regexp_evaluator]] | alpha lisp | [[monodico lisp|?view=monodicolisp]] } _p This work is no more integrated in the wiki page and can be better analyzed and tested in the outside console : {div {@ style="text-align:center; color:red; background:#eee;box-shadow:0 0 8px black;font-size:3em;"}[[alphalisp console|data/alphalisp/]]} _p In this page will be soon analyzed the structure of the evaluator : {pre °° var evaluate = function (x, env) { env = env || global_e; if ( isNumber(x) ) { return x; } else if ( isSymbol(x) ) { return env.find(x)[x]; } else if ( x[0] === 'quote' ) { 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] === 'set!' ) { env.find(x[1])[x[1]] = evaluate( x[2], env); } else if (x[0] === 'define' ) { env[x[1]] = evaluate( x[2], env ); return '[' + x[1] + ']'; } 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] === 'begin' ) { for (var xx = '', i=1; i< x.length; i++) xx = evaluate( x[i], env ); return xx; } else { for (var xx = [], i=0; i< x.length; i++) xx[i] = evaluate( x[i], env ); var proc = xx.shift(); var val = proc.apply(null, xx); return jsFormat( val ); } }; // evaluate °°} _p The new file [[alphalisp.js|data/alphalisp/alphalisp.js]] (about 200 lines of code) can be compared to the previous one [[alphalisp_prev.js|data/alphalisp/alphalisp_old.js]] (about 250 lines of code). The new evaluator (30 lines) can be compared to the previous one (75 lines) written by Sreedathns or Sainamdar. The great difference comes from the fact that the structure mimics closely the Peter Norvig's Python code ; and there is only one anonymous function, where it is absolutely needed : {b in the lambda evaluation}. _h3 note _p Implementing the Ycombinator (with [[Yan Wang|http://fr.slideshare.net/yinwang0/reinventing-the-ycombinator]]) : {pre (((lambda (f) ((lambda (x) (f (lambda (v) ((x x) v)))) (lambda (x) (f (lambda (v) ((x x) v)))))) (lambda (length) (lambda (ls) (if (null? ls) 0 (+ 1 (length (cdr ls))))))) (cons 1 2 3)) -> 3 (((lambda (f) ((lambda (x) (f (lambda (v) ((x x) v)))) (lambda (x) (f (lambda (v) ((x x) v)))))) (lambda (fact) (lambda (n) (if (< n 1) 1 (* n (fact (- n 1))))))) 6) -> 720 } _p Implementing Church numerals as integers (with [[stackoverflow|http://stackoverflow.com/questions/2675566/how-can-i-make-church-numerals-more-human-readable-in-lisp]]) : {pre (define zero (lambda (f x) x)) (define succ (lambda (cn) (lambda (f x) (f (cn f x))))) (define cnToInt (lambda (cn) (cn (lambda (x) (+ x 1)) 0))) (cnToInt zero) -> 0 (cnToInt (succ zero)) -> 1 (cnToInt (succ (succ zero))) -> 2 }