-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnodes.rb
executable file
·70 lines (51 loc) · 1.31 KB
/
nodes.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class Program < Treetop::Runtime::SyntaxNode
def eval(env={})
exprs.inject(nil){ |last_env, exp|
exp.eval(env)
}
end
def exprs
[expression] + expressions.exprs
end
end
class Cons < Treetop::Runtime::SyntaxNode
def eval(env)
self
end
end
class CompoundProcedure < Treetop::Runtime::SyntaxNode
def initialize(env, args, body)
@env = env
@args = args.elements.map{ |arg| arg.name}
@body = body
end
def apply(*values)
raise SchemeSyntaxError.new("Parameter doesn't match") unless @args.size == values.size
@body.eval(extend_env(values))
end
def extend_env(values)
@env.merge([@args, values].transpose.
map{ |key, value| { key => value}}.
inject{|sum, value| sum.merge(value)})
end
end
class RubyProcedure < Treetop::Runtime::SyntaxNode
def initialize(env, args, body)
@env = env
@args = args.elements.map{ |arg| arg.name}
@body = body
end
def apply(*values)
raise SchemeSyntaxError.new("Parameter doesn't match") unless @args.size == values.size
@body.call(*values)
end
def add(x, y)
x + y
end
def extend_env(values)
@env.merge([@args, values].transpose.map{ |key, value| { key => value}}.
inject{|sum, value| sum.merge(value)})
end
end
class SchemeSyntaxError < Exception
end