Last active
December 15, 2015 04:50
-
-
Save tompng/5204548 to your computer and use it in GitHub Desktop.
lispもどき
This file contains 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
require './lisp_base' | |
LISPRUN [:cdr,[:cons,L(1,2,3),L(4,5,6)]] | |
LISPRUN [:cdr,D(L(1,2,3,D(4,5)),L(6,7,8))] | |
LISPRUN [:do, | |
[:print,[:car,[:cons,3,[:cons,4,5]]]], | |
[:print,[:+,3,[:+,6,3]]], | |
[:defun,:dist2,[:a,:b],[:+,[:*,:a,:a],[:*,:b,:b]]], | |
[:print,[:dist2,3,4]], | |
[:defun,:fact,[:a],[:ifelse,[:==,:a,0],1,[:*,:a,[:fact,[:-,:a,1]]]]], | |
[:print,[:fact,10]], | |
[:loop,10,:n,[:do,[:ruby,:printf,"%d!=%d\n",:n,[:fact,:n]],[:ruby,:sleep,1]]], | |
[:ruby,:sleep,1], | |
[:ruby,:printf,"hello world!\n"], | |
[:ruby,:exit] | |
] |
This file contains 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
def L(*arr) | |
arr=parse arr | |
def arr.eval hash | |
self | |
end | |
arr | |
end | |
def D(a,b) | |
arr=[a,b] | |
def arr.eval hash | |
self | |
end | |
arr | |
end | |
def args(hash,tree) | |
return nil if tree.nil? | |
first=tree[0] | |
first=first.eval hash if first.class==Array | |
first=hash[first] if first.class==Symbol | |
[first,*args(hash,tree[1])] | |
end | |
def parse arr,index=0 | |
if index<arr.size | |
prev=arr[index] | |
if prev.class==Array | |
unless prev.respond_to? :eval | |
prev=parse prev | |
end | |
end | |
code=[prev,parse(arr,index+1)] | |
def code.eval hash | |
lispeval(self,hash) | |
end | |
code | |
end | |
end | |
def lispeval tree,hash | |
method=tree[0] | |
if hash[method] | |
hash[method].call(hash,tree[1]) | |
else | |
method.to_proc.call(hash,tree[1]) | |
end | |
end | |
class ChainHash | |
def initialize(parent) | |
@parent=parent | |
@hash={} | |
end | |
def [] key | |
@hash[key]||@parent[key] | |
end | |
def []=key,value | |
@hash[key]=value | |
end | |
end | |
def defun(hash,tree) | |
def arglistparse(tree) | |
[tree[0],*arglistparse(tree[1])] unless tree.nil? | |
end | |
name=tree[0] | |
arglist=arglistparse(tree[1][0]) | |
code=tree[1][1][0] | |
hash[name]=->(hash,tree){ | |
hash=ChainHash.new hash | |
arglist.zip(args(hash,tree)).each do|key,value| | |
hash[key]=value | |
end | |
if code.class==Array | |
code.eval hash | |
else | |
code | |
end | |
} | |
end | |
@hash={} | |
@hash[:+]=->(hash,tree){ | |
a,b=args(hash,tree) | |
a+b | |
} | |
@hash[:*]=->(hash,tree){ | |
a,b=args(hash,tree) | |
a*b | |
} | |
@hash[:-]=->(hash,tree){ | |
a,b=args(hash,tree) | |
a-b | |
} | |
@hash[:/]=->(hash,tree){ | |
a,b=args(hash,tree) | |
a/b | |
} | |
@hash[:do]=->(hash,tree){ | |
args(hash,tree).last | |
} | |
@hash[:if]=->(hash,tree){ | |
if tree[0].eval hash | |
code=tree[1][0] | |
if code.class==Array | |
code.eval hash | |
else | |
code | |
end | |
end | |
} | |
@hash[:ifelse]=->(hash,tree){ | |
if tree[0].eval hash | |
code=tree[1][0] | |
else | |
code=tree[1][1][0] | |
end | |
if code.class==Array | |
code.eval hash | |
else | |
code | |
end | |
} | |
@hash[:==]=->(hash,tree){ | |
a,b=args(hash,tree) | |
a==b | |
} | |
@hash[:p]=@hash[:print]=->(hash,tree){ | |
p *args(hash,tree) | |
} | |
@hash[:defun]=->(hash,tree){ | |
defun hash,tree | |
} | |
@hash[:ruby]=->(hash,tree){ | |
func=tree[0] | |
arguments=args(hash,tree[1]) | |
self.method(func).call *arguments | |
} | |
@hash[:loop]=->(hash,tree){ | |
count=tree[0] | |
count=count.eval hash if count.class==Array | |
name=tree[1][0] | |
code=tree[1][1][0] | |
count.times do |i| | |
hash[name]=i | |
if code.class==Array | |
code.eval hash | |
else | |
code | |
end | |
end | |
} | |
@hash[:car]=->(hash,tree){ | |
tree,=args(hash,tree) | |
tree[0] | |
} | |
@hash[:cdr]=->(hash,tree){ | |
tree,=args(hash,tree) | |
tree[1] | |
} | |
@hash[:cons]=->(hash,tree){ | |
a,b=args(hash,tree) | |
[a,b] | |
} | |
def LISPRUN(x) | |
p parse(x).eval @hash | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment