Created
          January 26, 2012 03:32 
        
      - 
      
 - 
        
Save fogus/1680795 to your computer and use it in GitHub Desktop.  
    *psil, pocket lisp interpreter
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | var cx = new env; | |
| console.log(leval(['set','a',42],cx)); | |
| console.log(leval('a',cx)); | |
| console.log(leval(['eq',42,'a'],cx)); | |
| console.log(leval(['quote',[1,2]],cx)); | |
| console.log(leval(['fst',['quote',[1,2]]],cx)); | |
| console.log(leval(['rst',['quote',[1,2]]],cx)); | |
| console.log(leval(['cons',1,['quote',[2,3]]],cx)); | |
| console.log(leval(['cond',['eq',1,2],42,43],cx)); | |
| console.log(leval(['atom',['quote',[1,2]]],cx)); | |
| console.log(leval(['set','second',['quote',['lambda',['x'],['fst',['rst','x']]]]],cx)); | |
| console.log(leval(['second',['quote',[1,2,3]]],cx)); | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | function extcx(ar,cx){ | |
| return ar.reduce(function(o, kv){ o[kv[0]] = kv[1]; return o; },cx || {}) | |
| } | |
| function zip(ar1, ar2){ | |
| return ar1.reduce(function(ar, v1, i1){ if (ar2[i1]) ar.push([v1,ar2[i1]]); return ar; },[]) | |
| } | |
| function atomp(a){ return !(typeof a in {object:0,array:0}) } | |
| function lazyp(a){ return (a in {cond:0,quote:0,lambda:0}) } | |
| function env(){ | |
| var inst = this; | |
| inst.atom = function(a){ return atomp(a) }; | |
| inst.set = function(as){ return inst[as[0]] = as[1] }; | |
| inst.quote = function(as){ return as[0] }; | |
| inst.fst = function(as){ return as[0][0] }; | |
| inst.rst = function(as){ return as[0].slice(1) }; | |
| inst.cons = function(as){ return [as[0]].concat(as[1]) }; | |
| inst.eq = function(as){ return as[0] === as[1] }; | |
| inst.cond = function(as,cx){ return leval(as[0],cx) ? leval(as[1],cx) : leval(as[2],cx) }; | |
| return inst; | |
| } | |
| function apply(rf, as, cx){ | |
| return rf in cx && cx[rf].call ? cx[rf].call(null, as, cx) : leval(cx[rf][2], extcx(zip(cx[rf][1], as), cx)); | |
| } | |
| function leval(sx, cx){ | |
| if (atomp(sx)) return sx in cx ? cx[sx] : sx; | |
| var rf = sx[0], as = sx.slice(1).map(function(a){ return lazyp(rf) ? a : leval(a, cx) }); | |
| return apply(rf, as, cx); | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment