Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active December 15, 2015 07:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tompng/5222780 to your computer and use it in GitHub Desktop.
Save tompng/5222780 to your computer and use it in GitHub Desktop.
もうちょっとLispっぽいLispもどき
require './lisp_base.rb'
LISP do (cons 1,2) end
LISP do (cond true,(cond false,(cons 1,2),(cons 3,4)),(cons 5,6)) end
LISP do (defun :fact,:x,(cond (eq :x,0),1,(mult (sqrt (square :x)),(fact (minus :x,1))))) end
LISP do (defun :abs,:x,(cond (lt :x,0),(minus 0,:x),:x)) end
LISP do
(defun :sqrtrec,:x,:y,:d,
(cond (lt :d,0.0000000001),
:y,
(cond (lt (mult :y,:y),:x),
(sqrtrec :x,(add :y,:d),(mult :d,0.5)),
(sqrtrec :x,(minus :y,:d),(mult :d,0.5))
)
)
)
end
LISP do (defun :sqrt,:x,(sqrtrec :x,:x,:x)) end
LISP do (defun :square,(mult :x,:x)) end
LISP do (fact 5) end
class LispEvaluator
class ChainHash
def initialize hash
@parent=hash
@hash={ }
end
def []= key,value
@hash[key]=value
end
def [] key
@hash[key]||@parent[key]
end
end
def defun name,*args
code=args.pop
argument_list=args
@methods[name]=->(hash,*args){
hash=ChainHash.new hash
argument_list.zip(args).each{ |key,code|
hash[key]=run code,hash
}
run code,hash
}
true
end
def method_missing name,*args
{name:name,args:args}
end
def run code,hash
if code.class==Symbol
hash[code]
elsif code.class==Hash
@methods[code[:name]].call hash,*code[:args]
else
code
end
end
def initialize
@methods={ }
@methods[:cond]=->(hash,a,b,c){
if run a,hash
run b,hash
else
run c,hash
end
}
@methods[:cons]=->(hash,a,b){
[run(a,hash),run(b,hash)]
}
@methods[:eq]=->(hash,a,b){
run(a,hash)==run(b,hash)
}
@methods[:mult]=->(hash,a,b){
run(a,hash)*run(b,hash)
}
@methods[:minus]=->(hash,a,b){
run(a,hash)-run(b,hash)
}
@methods[:add]=->(hash,a,b){
run(a,hash)+run(b,hash)
}
@methods[:lt]=->(hash,a,b){
run(a,hash)<run(b,hash)
}
@methods[:le]=->(hash,a,b){
run(a,hash)>run(b,hash)
}
end
end
@lispevaluator=LispEvaluator.new
def LISP(&block)
code=@lispevaluator.instance_eval(&block)
p @lispevaluator.run(code,{})
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment