nydp 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -15,7 +15,9 @@
15
15
  ("sorts a list of hashes by a specified key"
16
16
  (let hh (list { a 1 b 2 } { a 7 b 9 } { a 3 b 1 } { a 2 b 8 })
17
17
  (pp (sort-by &a hh)))
18
- "({ a 1 b 2 } { a 2 b 8 } { a 3 b 1 } { a 7 b 9 })")
18
+ "({ a 1 b 2 } { a 2 b 8 }
19
+ { a 3 b 1 }
20
+ { a 7 b 9 })")
19
21
 
20
22
  ("sorts a list of strings according to their length"
21
23
  (sort-by len
@@ -10,7 +10,8 @@ module Nydp
10
10
  def self.compile expression, bindings
11
11
  compile_expr expression, bindings
12
12
  rescue Exception => e
13
- raise "failed to compile expression #{expression.inspect},\nerror was #{e.message}"
13
+ new_msg = "failed to compile expression #{expression.inspect},\nerror was #{e.message}"
14
+ raise $!, new_msg, $!.backtrace
14
15
  end
15
16
 
16
17
  def self.compile_expr expression, bindings
@@ -1,54 +1,49 @@
1
1
  module Nydp
2
- class ContextLookup0 ; def self.get_context ctx; ctx; end; end
3
- class ContextLookup1 ; def self.get_context ctx; ctx.parent; end; end
4
- class ContextLookup2 ; def self.get_context ctx; ctx.parent.parent; end; end
5
- class ContextLookup3 ; def self.get_context ctx; ctx.parent.parent.parent; end; end
6
- class ContextLookup4 ; def self.get_context ctx; ctx.parent.parent.parent.parent; end; end
7
- class ContextLookup5 ; def self.get_context ctx; ctx.parent.parent.parent.parent.parent; end; end
8
- class ContextLookup6 ; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent; end; end
9
- class ContextLookup7 ; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent; end; end
10
- class ContextLookup8 ; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent; end; end
11
- class ContextLookup9 ; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
12
- class ContextLookup10; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
13
- class ContextLookup11; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
14
- class ContextLookup12; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
15
- class ContextLookup13; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
16
- class ContextLookup14; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
17
- class ContextLookup15; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
18
- class ContextLookup16; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
19
- class ContextLookup17; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
20
- class ContextLookup18; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
21
- class ContextLookupN
22
- def initialize depth ; @depth = depth ; end
23
- def get_context ctx ; ctx.nth(@depth) ; end
24
- end
25
-
26
2
  class ContextSymbol
27
- attr_accessor :depth, :name, :binding_index
3
+ def self.build depth, name, binding_index
4
+ cname = "ContextSymbol_#{depth}_#{binding_index}"
28
5
 
29
- def initialize depth, name, binding_index
30
- @ctx_lookup = build_lookup depth
31
- @depth, @name, @binding_index = depth, name, binding_index
32
- end
6
+ existing = const_get(cname) rescue nil
7
+ return existing.new(name) if existing
33
8
 
34
- def get_context(context); @ctx_lookup.get_context context; end
9
+ getctx = ([".parent"] * depth).join
10
+ at_index = if binding_index < 10
11
+ "at_#{binding_index}"
12
+ else
13
+ "at_index(#{binding_index})"
14
+ end
35
15
 
36
- def value context
37
- get_context(context).at_index(binding_index)
38
- end
16
+ set_index = if binding_index < 10
17
+ "at_#{binding_index}= value"
18
+ else
19
+ "set_index(#{binding_index}, value)"
20
+ end
39
21
 
40
- def assign value, context
41
- get_context(context).set_index(binding_index, value)
42
- end
22
+ klass = <<KLASS
23
+ class #{cname} < Nydp::ContextSymbol
24
+ def initialize name
25
+ @name = name
26
+ end
43
27
 
44
- def inspect; to_s; end
45
- def to_s
46
- "[#{depth}##{binding_index}]#{name}"
47
- end
28
+ def value ctx
29
+ ctx#{getctx}.#{at_index} || Nydp::NIL
30
+ end
31
+
32
+ def assign value, ctx
33
+ ctx#{getctx}.#{set_index}
34
+ end
35
+
36
+ def execute vm
37
+ vm.push_arg value vm.current_context
38
+ end
39
+
40
+ def inspect ; to_s ; end
41
+ def to_s ; "[#{depth}##{binding_index}]\#{@name}" ; end
42
+ end
43
+ KLASS
48
44
 
49
- def build_lookup depth
50
- fast = Nydp.const_get "ContextLookup#{depth}" rescue nil
51
- return fast || ContextLookupN.new(depth)
45
+ eval klass
46
+ const_get(cname).new(name)
52
47
  end
53
48
  end
54
49
  end
@@ -84,14 +84,84 @@ module Nydp
84
84
  handle e, args.car, args.cdr
85
85
  end
86
86
  end
87
+
88
+ # TODO generate various Invocation_XXX classes on-demand instead of hand_coding them all up front
89
+ class Invocation_SYM < Invocation::Base
90
+ def initialize expr, src
91
+ super src
92
+ @sym = expr.car
93
+ end
94
+
95
+ def execute vm
96
+ @sym.value.invoke_1 vm
97
+ rescue Exception => e
98
+ handle e, @sym.value, Nydp::NIL
99
+ end
100
+ end
101
+
102
+ class Invocation_SYM_LEX < Invocation::Base
103
+ def initialize expr, src
104
+ super src
105
+ @sym = expr.car
106
+ @lex = expr.cdr.car
107
+ end
108
+
109
+ def execute vm
110
+ fn = @sym.value
111
+ a0 = @lex.value(vm.current_context)
112
+ fn.invoke_2 vm, a0
113
+ rescue Exception => e
114
+ handle e, fn, cons(a0)
115
+ end
116
+ end
117
+
118
+ class Invocation_SYM_LEX_LEX < Invocation::Base
119
+ def initialize expr, src
120
+ super src
121
+ @sym = expr.car
122
+ @lex_0 = expr.cdr.car
123
+ @lex_1 = expr.cdr.cdr.car
124
+ end
125
+
126
+ def execute vm
127
+ fn = @sym.value
128
+ a0 = @lex_0.value(vm.current_context)
129
+ a1 = @lex_1.value(vm.current_context)
130
+ fn.invoke_3 vm, a0, a1
131
+ rescue Exception => e
132
+ handle e, fn, cons(a0, cons(a1))
133
+ end
134
+ end
87
135
  end
88
136
 
89
137
  class FunctionInvocation
90
138
  extend Helper
91
139
  attr_accessor :function_instruction, :argument_instructions
92
140
 
141
+ def self.sig klass
142
+ case klass
143
+ when Nydp::Symbol ; "SYM"
144
+ when Nydp::ContextSymbol ; "LEX"
145
+ when Nydp::Literal ; "LIT"
146
+ when Nydp::FunctionInvocation ; "NVK"
147
+ when Nydp::Invocation::Base ; "NVB"
148
+ when Nydp::InterpretedFunction ; "IFN"
149
+ when Nydp::Cond ; "CND"
150
+ when Nydp::Assignment ; "ASN"
151
+ else ; raise "no sig for #{klass.class.name}"
152
+ end
153
+ end
93
154
  def self.build expression, bindings
94
155
  compiled = Compiler.compile_each(expression, bindings)
156
+ invocation_sig = compiled.map { |x| sig x }.join("_")
157
+
158
+ cname = "Invocation_#{invocation_sig}"
159
+ iclass = Nydp::Invocation.const_get(cname) rescue nil
160
+ if iclass
161
+ # puts "found #{cname}"
162
+ return iclass.new(compiled, expression)
163
+ end
164
+
95
165
  invocation = cons case expression.size
96
166
  when 1
97
167
  Invocation::Invocation_1.new(expression)
@@ -1,71 +1,51 @@
1
- class Nydp::LexicalContext
2
- include Nydp::Helper
3
- attr_reader :names, :values, :parent
4
-
5
- def initialize parent
6
- @parent = parent
7
- @names = []
8
- @values = []
9
- end
10
-
11
- def nth n
12
- case n
13
- when 0
14
- self
15
- when -1
16
- raise "wrong nesting level"
17
- else
18
- parent.nth(n - 1)
1
+ module Nydp
2
+ class LexicalContext
3
+ include Nydp::Helper
4
+ attr_reader :parent
5
+ attr_accessor :at_0, :at_1, :at_2, :at_3, :at_4, :at_5, :at_6, :at_7, :at_8, :at_9
6
+
7
+ def initialize parent
8
+ @parent = parent
19
9
  end
20
- end
21
-
22
- def at_index index
23
- values[index] || Nydp::NIL
24
- end
25
-
26
- def set name, value
27
- names << name
28
- values << value
29
- end
30
10
 
31
- def set_args_1 names, arg
32
- if pair? names
33
- set names.car, arg
34
- elsif Nydp::NIL.isnt? names
35
- set names, cons(arg)
11
+ def nth n
12
+ case n
13
+ when 0
14
+ self
15
+ when -1
16
+ raise "wrong nesting level"
17
+ else
18
+ parent.nth(n - 1)
19
+ end
36
20
  end
37
- end
38
21
 
39
- def set_args_2 names, arg_0, arg_1
40
- if pair? names
41
- set names.car, arg_0
42
- set_args_1 names.cdr, arg_1
43
- elsif Nydp::NIL.isnt? names
44
- set names, cons(arg_0, cons(arg_1))
22
+ def at_index index
23
+ instance_variable_get :"@at_#{index}"
45
24
  end
46
- end
47
25
 
48
- def set_args_3 names, arg_0, arg_1, arg_2
49
- if pair? names
50
- set names.car, arg_0
51
- set_args_2 names.cdr, arg_1, arg_2
52
- elsif Nydp::NIL.isnt? names
53
- set names, cons(arg_0, cons(arg_1, cons(arg_2)))
26
+ def set_index index, value
27
+ instance_variable_set :"@at_#{index}", value
54
28
  end
55
- end
56
29
 
57
- def set_index index, value
58
- values[index] = value
59
- end
30
+ def method_missing mname, *args
31
+ if mname.to_s =~ /at_\d+=/
32
+ instance_variable_set :"@#{mname.to_s.sub(/=/, '')}", args[0]
33
+ elsif mname.to_s =~ /at_\d+/
34
+ instance_variable_get :"@#{mname}"
35
+ else
36
+ super
37
+ end
38
+ end
60
39
 
61
- def to_s_with_indent str
62
- me = @values.map { |k, v|
63
- [str, k, "=>", v].join ' '
64
- }.join "\n"
65
- me + (parent ? parent.to_s_with_indent(" #{str}") : '')
66
- end
40
+ def to_s_with_indent str
41
+ me = @values.map { |k, v|
42
+ [str, k, "=>", v].join ' '
43
+ }.join "\n"
44
+ me + (parent ? parent.to_s_with_indent(" #{str}") : '')
45
+ end
67
46
 
68
- def to_s
69
- to_s_with_indent ''
47
+ def to_s
48
+ to_s_with_indent ''
49
+ end
70
50
  end
71
51
  end
@@ -1,203 +1,111 @@
1
1
  module Nydp::LexicalContextBuilder
2
2
  extend Nydp::Helper
3
3
 
4
- module B_0
5
- def initialize_names _ ; end
6
- def set_args_1 lc, a ; end
7
- def set_args_2 lc, a_0, a_1 ; end
8
- def set_args_3 lc, a_0, a_1, a_2 ; end
9
- def set_args lc, args ; end
4
+ def self.build_set_args_n_method ngiven, nexpected
5
+ setter_count = [ngiven, nexpected].min
6
+ arg_names = (0...ngiven ).map { |i| "arg_#{i}"}
7
+ setters = (0...setter_count).map { |i| "lc.at_#{i}= arg_#{i}"}
8
+ " def set_args_#{ngiven} lc, #{arg_names.join ", "}
9
+ #{setters.join "\n "}
10
10
  end
11
-
12
- module B_1
13
- def initialize_names names ; @param_name = names.car ; end
14
- def set_args_1 lc, arg ; lc.set @param_name, arg ; end
15
- def set_args_2 lc, arg_0, arg_1 ; lc.set @param_name, arg_0 ; end
16
- def set_args_3 lc, arg_0, arg_1, arg_2 ; lc.set @param_name, arg_0 ; end
17
- def set_args lc, args ; lc.set @param_name, args.car ; end
11
+ "
18
12
  end
19
13
 
20
- module B_2
21
- def initialize_names names
22
- @param_name_0 = names.car
23
- @param_name_1 = names.cdr.car
24
- end
25
- def set_args_1 lc, arg
26
- lc.set @param_name_0, arg
27
- end
28
- def set_args_2 lc, arg_0, arg_1
29
- lc.set @param_name_0, arg_0
30
- lc.set @param_name_1, arg_1
31
- end
32
- def set_args_3 lc, arg_0, arg_1, arg_2
33
- lc.set @param_name_0, arg_0
34
- lc.set @param_name_1, arg_1
35
- end
36
- def set_args lc, args
37
- lc.set @param_name_0, args.car
38
- lc.set @param_name_1, args.cdr.car
14
+ def self.build_arg_conses arg_names, n
15
+ if n == arg_names.size - 1
16
+ "cons(#{arg_names[n]})"
17
+ else
18
+ "cons(#{arg_names[n]}, #{build_arg_conses(arg_names, n+1)})"
39
19
  end
40
20
  end
41
21
 
42
- module B_3
43
- def initialize_names names
44
- @param_name_0 = names.car
45
- @param_name_1 = names.cdr.car
46
- @param_name_2 = names.cdr.cdr.car
47
- end
48
- def set_args_1 lc, arg
49
- lc.set @param_name_0, arg
50
- end
51
- def set_args_2 lc, arg_0, arg_1
52
- lc.set @param_name_0, arg_0
53
- lc.set @param_name_1, arg_1
54
- end
55
- def set_args_3 lc, arg_0, arg_1, arg_2
56
- lc.set @param_name_0, arg_0
57
- lc.set @param_name_1, arg_1
58
- lc.set @param_name_2, arg_2
59
- end
60
- def set_args lc, args
61
- lc.set @param_name_0, args.car
62
- lc.set @param_name_1, args.cdr.car
63
- lc.set @param_name_2, args.cdr.cdr.car
64
- end
22
+ def self.build_set_args_n_rest_method ngiven, nexpected
23
+ setter_count = [ngiven, nexpected].min
24
+ arg_names = (0...ngiven ).map { |i| "arg_#{i}"}
25
+ setters = (0...setter_count).map { |i| "lc.at_#{i}= arg_#{i}"}
26
+ if ngiven > setter_count
27
+ rest_setter = "lc.at_#{nexpected}= #{build_arg_conses arg_names[setter_count..-1], 0}"
28
+ end
29
+ " def set_args_#{ngiven} lc, #{arg_names.join ", "}
30
+ #{setters.join "\n "}
31
+ #{rest_setter}
65
32
  end
66
-
67
- module B_0_Rest
68
- include Nydp::Helper
69
- def initialize_names names ; @param_name = names ; end
70
- def set_args_1 lc, arg ; lc.set @param_name, cons(arg) ; end
71
- def set_args_2 lc, arg_0, arg_1 ; lc.set @param_name, cons(arg_0, cons(arg_1)) ; end
72
- def set_args_3 lc, arg_0, arg_1, arg_2 ; lc.set @param_name, cons(arg_0, cons(arg_1, cons(arg_2))) ; end
73
- def set_args lc, args ; lc.set @param_name, args ; end
33
+ "
74
34
  end
75
35
 
76
- module B_1_Rest
77
- include Nydp::Helper
78
- def initialize_names names
79
- @param_name_0 = names.car
80
- @param_name_1 = names.cdr
81
- end
82
- def set_args_1 lc, arg
83
- lc.set @param_name_0, arg
84
- end
85
- def set_args_2 lc, arg_0, arg_1
86
- lc.set @param_name_0, arg_0
87
- lc.set @param_name_1, cons(arg_1)
88
- end
89
- def set_args_3 lc, arg_0, arg_1, arg_2
90
- lc.set @param_name_0, arg_0
91
- lc.set @param_name_1, cons(arg_1, cons(arg_2))
92
- end
93
- def set_args lc, args
94
- lc.set @param_name_0, args.car
95
- lc.set @param_name_1, args.cdr
96
- end
36
+ def self.build_set_args_method nexpected
37
+ setters = (0...nexpected).map { |i| "lc.at_#{i}= args#{ ([".cdr"] * i).join }.car"}
38
+ " def set_args lc, args
39
+ #{setters.join "\n "}
97
40
  end
98
-
99
- module B_2_Rest
100
- def initialize_names names
101
- @param_name_0 = names.car
102
- @param_name_1 = names.cdr.car
103
- @param_name_2 = names.cdr.cdr
104
- end
105
- def set_args_1 lc, arg
106
- lc.set @param_name_0, arg
107
- end
108
- def set_args_2 lc, arg_0, arg_1
109
- lc.set @param_name_0, arg_0
110
- lc.set @param_name_1, arg_1
111
- end
112
- def set_args_3 lc, arg_0, arg_1, arg_2
113
- lc.set @param_name_0, arg_0
114
- lc.set @param_name_1, arg_1
115
- lc.set @param_name_2, cons(arg_2)
116
- end
117
- def set_args lc, args
118
- lc.set @param_name_0, args.car
119
- lc.set @param_name_1, args.cdr.car
120
- lc.set @param_name_2, args.cdr.cdr
121
- end
41
+ "
122
42
  end
123
43
 
124
- module B_3_Rest
125
- def initialize_names names
126
- @param_name_0 = names.car
127
- @param_name_1 = names.cdr.car
128
- @param_name_2 = names.cdr.cdr
129
- end
130
- def set_args_1 lc, arg
131
- lc.set @param_name_0, arg
132
- end
133
- def set_args_2 lc, arg_0, arg_1
134
- lc.set @param_name_0, arg_0
135
- lc.set @param_name_1, arg_1
136
- end
137
- def set_args_3 lc, arg_0, arg_1, arg_2
138
- lc.set @param_name_0, arg_0
139
- lc.set @param_name_1, arg_1
140
- lc.set @param_name_2, arg_2
141
- end
142
- def set_args lc, args
143
- lc.set @param_name_0, args.car
144
- lc.set @param_name_1, args.cdr.car
145
- lc.set @param_name_2, args.cdr.cdr.car
146
- lc.set @param_name_3, args.cdr.cdr.cdr
147
- end
44
+ def self.build_set_args_rest_method nexpected
45
+ setters = (0...nexpected).map { |i| "lc.at_#{i}= args#{ ([".cdr"] * i).join }.car"}
46
+ rest_set = "lc.at_#{nexpected}= args#{ ([".cdr"] *(nexpected)).join }"
47
+ " def set_args lc, args
48
+ #{setters.join "\n "}
49
+ #{rest_set}
50
+ end
51
+ "
148
52
  end
149
53
 
150
- module B_X
151
- def initialize_names names
152
- @param_names = names
153
- end
154
- def set_args_1 lc, arg
155
- lc.set @param_names.car, arg
156
- end
157
- def set_args_2 lc, arg_0, arg_1
158
- lc.set @param_names.car, arg_0
159
- lc.set @param_names.cdr.car, arg_1
160
- end
161
- def set_args_3 lc, arg_0, arg_1, arg_2
162
- lc.set @param_names.car, arg_0
163
- lc.set @param_names.cdr.car, arg_1
164
- lc.set @param_names.cdr.cdr.car, arg_2
165
- end
166
- def set_args lc, args
167
- _set_args lc, @param_names, args
168
- end
169
- def _set_args lc, names, args
170
- unless Nydp::NIL.is? names
171
- lc.set names.car, args.car
172
- _set_args lc, names.cdr, args.cdr
173
- end
174
- end
54
+ def self.get_builder_class expected_arg_count
55
+ name = "B_#{expected_arg_count}"
56
+ existing = const_get(name) rescue nil
57
+ return name if existing
58
+
59
+ n_methods = (1..3).map { |given| build_set_args_n_method given, expected_arg_count }
60
+ x_method = build_set_args_method expected_arg_count
61
+ klass = <<KLASS
62
+ module #{name}
63
+ def initialize_names names ; end
64
+
65
+ #{n_methods.join "\n"}
66
+ #{x_method}
67
+ end
68
+ KLASS
69
+
70
+ eval klass
71
+ name
175
72
  end
176
73
 
177
- module B_X_Rest
178
- include Nydp::Helper
179
- def initialize_names names ; @param_names = names ; end
180
- def set_args_1 lc, arg ; set_args lc, cons(arg) ; end
181
- def set_args_2 lc, arg_0, arg_1 ; set_args lc, cons(arg_0, cons(arg_1)) ; end
182
- def set_args_3 lc, arg_0, arg_1, arg_2 ; set_args lc, cons(arg_0, cons(arg_1, cons(arg_2))) ; end
183
- def set_args lc, args ; _set_args lc, @param_names, args ; end
184
- def _set_args lc, names, args
185
- if pair? names
186
- lc.set names.car, args.car
187
- _set_args lc, names.cdr, args.cdr
188
- elsif Nydp::NIL.isnt? names
189
- lc.set names, args
190
- end
191
- end
74
+ def self.get_builder_rest_class proper_arg_count
75
+ name = "B_#{proper_arg_count}_Rest"
76
+ existing = const_get(name) rescue nil
77
+ return name if existing
78
+
79
+ n_methods = (1..3).map { |given| build_set_args_n_rest_method given, proper_arg_count }
80
+ x_method = build_set_args_rest_method proper_arg_count
81
+ klass = <<KLASS
82
+ module #{name}
83
+ def initialize_names names ; end
84
+
85
+ #{n_methods.join "\n"}
86
+ #{x_method}
87
+ end
88
+ KLASS
89
+
90
+ eval klass
91
+ name
192
92
  end
193
93
 
194
94
  def self.select arg_names
195
- if pair? arg_names
196
- size = pair?(arg_names) ? arg_names.size : 0
197
- class_name = "B_#{size > 3 ? "X" : size}#{arg_names.proper? ? "" : "_Rest"}"
95
+ if pair?(arg_names)
96
+ size = arg_names.size
97
+ proper = arg_names.proper?
98
+ else
99
+ size = 0
100
+ proper = Nydp::NIL.is? arg_names
101
+ end
102
+
103
+ if proper
104
+ class_name = get_builder_class size
198
105
  else
199
- class_name = "B_0_Rest"
106
+ class_name = get_builder_rest_class size
200
107
  end
108
+
201
109
  self.const_get(class_name.to_sym)
202
110
  end
203
111
  end