nydp 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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