nydp 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +77 -56
  4. data/lib/lisp/core-000.nydp +1 -1
  5. data/lib/lisp/core-010-precompile.nydp +49 -29
  6. data/lib/lisp/core-012-utils.nydp +12 -8
  7. data/lib/lisp/core-015-documentation.nydp +41 -15
  8. data/lib/lisp/core-017-builtin-dox.nydp +621 -100
  9. data/lib/lisp/core-020-utils.nydp +33 -6
  10. data/lib/lisp/core-025-warnings.nydp +1 -1
  11. data/lib/lisp/core-030-syntax.nydp +64 -48
  12. data/lib/lisp/core-035-flow-control.nydp +20 -28
  13. data/lib/lisp/core-037-list-utils.nydp +84 -21
  14. data/lib/lisp/core-040-utils.nydp +8 -5
  15. data/lib/lisp/core-041-string-utils.nydp +17 -11
  16. data/lib/lisp/core-043-list-utils.nydp +140 -77
  17. data/lib/lisp/core-045-dox-utils.nydp +1 -0
  18. data/lib/lisp/core-050-test-runner.nydp +8 -12
  19. data/lib/lisp/core-070-prefix-list.nydp +19 -15
  20. data/lib/lisp/core-080-pretty-print.nydp +13 -5
  21. data/lib/lisp/core-090-hook.nydp +11 -11
  22. data/lib/lisp/core-100-utils.nydp +51 -66
  23. data/lib/lisp/core-110-hash-utils.nydp +34 -7
  24. data/lib/lisp/core-120-settings.nydp +14 -9
  25. data/lib/lisp/core-130-validations.nydp +28 -13
  26. data/lib/lisp/core-900-benchmarking.nydp +420 -47
  27. data/lib/lisp/tests/000-empty-args-examples.nydp +5 -0
  28. data/lib/lisp/tests/andify-examples.nydp +1 -1
  29. data/lib/lisp/tests/auto-hash-examples.nydp +6 -1
  30. data/lib/lisp/tests/best-examples.nydp +1 -1
  31. data/lib/lisp/tests/boot-tests.nydp +1 -1
  32. data/lib/lisp/tests/date-examples.nydp +129 -102
  33. data/lib/lisp/tests/destructuring-examples.nydp +1 -1
  34. data/lib/lisp/tests/dox-tests.nydp +2 -2
  35. data/lib/lisp/tests/hash-examples.nydp +58 -33
  36. data/lib/lisp/tests/list-tests.nydp +137 -1
  37. data/lib/lisp/tests/pretty-print-tests.nydp +12 -0
  38. data/lib/lisp/tests/rotate-2d-array-examples.nydp +26 -0
  39. data/lib/lisp/tests/sort-examples.nydp +5 -5
  40. data/lib/lisp/tests/string-tests.nydp +16 -5
  41. data/lib/lisp/tests/syntax-tests.nydp +10 -2
  42. data/lib/lisp/tests/time-examples.nydp +8 -1
  43. data/lib/lisp/tests/unparse-tests.nydp +13 -7
  44. data/lib/nydp/assignment.rb +15 -28
  45. data/lib/nydp/builtin/abs.rb +4 -3
  46. data/lib/nydp/builtin/apply.rb +8 -10
  47. data/lib/nydp/builtin/cdr_set.rb +1 -1
  48. data/lib/nydp/builtin/comment.rb +1 -3
  49. data/lib/nydp/builtin/date.rb +11 -28
  50. data/lib/nydp/builtin/divide.rb +3 -10
  51. data/lib/nydp/builtin/ensuring.rb +6 -21
  52. data/lib/nydp/builtin/error.rb +2 -4
  53. data/lib/nydp/builtin/eval.rb +9 -4
  54. data/lib/nydp/builtin/greater_than.rb +7 -8
  55. data/lib/nydp/builtin/handle_error.rb +10 -34
  56. data/lib/nydp/builtin/hash.rb +24 -45
  57. data/lib/nydp/builtin/inspect.rb +1 -3
  58. data/lib/nydp/builtin/is_equal.rb +4 -7
  59. data/lib/nydp/builtin/less_than.rb +6 -7
  60. data/lib/nydp/builtin/log.rb +7 -0
  61. data/lib/nydp/builtin/math_ceiling.rb +1 -3
  62. data/lib/nydp/builtin/math_floor.rb +1 -3
  63. data/lib/nydp/builtin/math_power.rb +1 -3
  64. data/lib/nydp/builtin/math_round.rb +2 -2
  65. data/lib/nydp/builtin/minus.rb +7 -14
  66. data/lib/nydp/builtin/parse.rb +5 -5
  67. data/lib/nydp/builtin/parse_in_string.rb +5 -7
  68. data/lib/nydp/builtin/plus.rb +14 -31
  69. data/lib/nydp/builtin/pre_compile.rb +1 -3
  70. data/lib/nydp/builtin/puts.rb +4 -8
  71. data/lib/nydp/builtin/quit.rb +1 -1
  72. data/lib/nydp/builtin/rand.rb +6 -11
  73. data/lib/nydp/builtin/random_string.rb +2 -4
  74. data/lib/nydp/builtin/rng.rb +25 -0
  75. data/lib/nydp/builtin/ruby_wrap.rb +27 -14
  76. data/lib/nydp/builtin/script_run.rb +1 -3
  77. data/lib/nydp/builtin/set_intersection.rb +3 -4
  78. data/lib/nydp/builtin/set_union.rb +3 -4
  79. data/lib/nydp/builtin/sort.rb +2 -7
  80. data/lib/nydp/builtin/string_match.rb +5 -13
  81. data/lib/nydp/builtin/string_replace.rb +2 -7
  82. data/lib/nydp/builtin/string_split.rb +3 -8
  83. data/lib/nydp/builtin/sym.rb +2 -9
  84. data/lib/nydp/builtin/thread_locals.rb +2 -2
  85. data/lib/nydp/builtin/time.rb +38 -44
  86. data/lib/nydp/builtin/times.rb +6 -15
  87. data/lib/nydp/builtin/to_integer.rb +8 -14
  88. data/lib/nydp/builtin/to_string.rb +2 -13
  89. data/lib/nydp/builtin/type_of.rb +10 -16
  90. data/lib/nydp/builtin/vm_info.rb +2 -10
  91. data/lib/nydp/builtin.rb +15 -37
  92. data/lib/nydp/compiler.rb +29 -19
  93. data/lib/nydp/cond.rb +95 -88
  94. data/lib/nydp/context_symbol.rb +11 -9
  95. data/lib/nydp/core.rb +74 -73
  96. data/lib/nydp/core_ext.rb +87 -26
  97. data/lib/nydp/date.rb +22 -19
  98. data/lib/nydp/error.rb +2 -3
  99. data/lib/nydp/function_invocation.rb +76 -289
  100. data/lib/nydp/helper.rb +18 -9
  101. data/lib/nydp/interpreted_function.rb +159 -25
  102. data/lib/nydp/lexical_context.rb +9 -8
  103. data/lib/nydp/lexical_context_builder.rb +1 -1
  104. data/lib/nydp/literal.rb +3 -7
  105. data/lib/nydp/loop.rb +72 -0
  106. data/lib/nydp/namespace.rb +52 -0
  107. data/lib/nydp/pair.rb +146 -50
  108. data/lib/nydp/parser.rb +9 -11
  109. data/lib/nydp/plugin.rb +88 -19
  110. data/lib/nydp/runner.rb +141 -23
  111. data/lib/nydp/symbol.rb +16 -26
  112. data/lib/nydp/symbol_lookup.rb +3 -2
  113. data/lib/nydp/tokeniser.rb +1 -1
  114. data/lib/nydp/truth.rb +2 -37
  115. data/lib/nydp/version.rb +1 -1
  116. data/lib/nydp.rb +33 -44
  117. data/nydp.gemspec +2 -1
  118. data/spec/date_spec.rb +26 -32
  119. data/spec/embedded_spec.rb +22 -22
  120. data/spec/error_spec.rb +12 -16
  121. data/spec/foreign_hash_spec.rb +21 -36
  122. data/spec/hash_non_hash_behaviour_spec.rb +12 -29
  123. data/spec/hash_spec.rb +36 -49
  124. data/spec/literal_spec.rb +6 -6
  125. data/spec/nydp_spec.rb +14 -14
  126. data/spec/pair_spec.rb +8 -8
  127. data/spec/parser_spec.rb +41 -37
  128. data/spec/rand_spec.rb +1 -4
  129. data/spec/spec_helper.rb +3 -3
  130. data/spec/string_atom_spec.rb +15 -16
  131. data/spec/symbol_spec.rb +27 -52
  132. data/spec/thread_local_spec.rb +23 -8
  133. data/spec/time_spec.rb +4 -10
  134. data/spec/tokeniser_spec.rb +10 -10
  135. metadata +25 -13
  136. data/lib/nydp/builtin/modulo.rb +0 -11
  137. data/lib/nydp/builtin/regexp.rb +0 -7
  138. data/lib/nydp/builtin/sqrt.rb +0 -7
  139. data/lib/nydp/builtin/string_pad_left.rb +0 -7
  140. data/lib/nydp/builtin/string_pad_right.rb +0 -7
  141. data/lib/nydp/hash.rb +0 -9
  142. data/lib/nydp/image_store.rb +0 -21
  143. data/lib/nydp/vm.rb +0 -129
data/lib/nydp/helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Nydp
2
2
  module AutoWrap
3
3
  # include this and be sure to either override #_nydp_ok? or #_nydp_whitelist
4
- # #_nydp_whitelist should return a list of accessor (zero-arg) methods which are safe for nydp to invoke
4
+ # #_nydp_whitelist should return a list of accessor (zero-arg) methods which are safe for nydp to call
5
5
  # #_nydp_procify should return a list of methods that can be exposed to script code.
6
6
  #
7
7
  # class Blub
@@ -19,11 +19,9 @@ module Nydp
19
19
  #
20
20
  # blubme here, now
21
21
  #
22
- def _nydp_wrapper ; self ; end
23
22
  def _nydp_ok? method ; _nydp_whitelist.include? method ; end
24
23
  def _nydp_procify? method ; _nydp_procs.include? method ; end # override to allow returning Method instances for given method name
25
24
  def _nydp_get key ; _nydp_safe_send(key.to_s.as_method_name) ; end
26
- def to_ruby ; self ; end
27
25
  def _nydp_safe_send meth, *args
28
26
  return send meth, *args if _nydp_ok?(meth)
29
27
  return method(meth) if _nydp_procify?(meth)
@@ -37,8 +35,16 @@ module Nydp
37
35
  end
38
36
 
39
37
  module Converter
40
- def n2r o ; o.respond_to?(:to_ruby) ? o.to_ruby : o ; end
41
- def r2n o, ns=nil ; o._nydp_wrapper ; end
38
+ def n2r o ; o.respond_to?(:to_ruby) ? o.to_ruby : o ; end
39
+ def r2n o ; o._nydp_wrapper ; end
40
+
41
+ def rubify value
42
+ if value.is_a?(Array) ; value.map { |v| rubify v }
43
+ elsif value.is_a?(::Nydp::Pair) ; rubify(value.to_a)
44
+ elsif value.is_a?(::Hash) ; { }.tap { |h| value.each { |k, v| h[rubify k] = rubify(v) } }
45
+ else ; n2r value
46
+ end
47
+ end
42
48
  end
43
49
 
44
50
  extend Converter
@@ -62,14 +68,15 @@ module Nydp
62
68
  end
63
69
 
64
70
  def sym? expr, name
65
- expr.is_a?(Nydp::Symbol) && (expr.is? name)
71
+ # expr.is_a?(Nydp::Symbol) && (expr.is? name)
72
+ expr.is_a?(::Symbol) && (expr == name.to_sym)
66
73
  end
67
74
 
68
75
  def pair? expr
69
76
  expr.is_a?(Nydp::Pair)
70
77
  end
71
78
 
72
- def cons a, b=Nydp::NIL
79
+ def cons a=nil, b=nil
73
80
  Nydp::Pair.new a, b
74
81
  end
75
82
 
@@ -78,12 +85,14 @@ module Nydp
78
85
  end
79
86
 
80
87
  def sym name, ns
81
- Nydp::Symbol.mk name, ns
88
+ name.to_s.to_sym
82
89
  end
83
90
 
84
91
  def literal? expr
85
92
  case expr
86
- when String, Float, Integer, Integer, Nydp::Symbol, Nydp::Truth, Nydp::Nil
93
+ # when String, Float, Integer, Integer, Symbol, Nydp::Truth, Nydp::Nil
94
+ # when String, Float, Integer, Integer, Symbol, Nydp::Truth, NilClass
95
+ when String, Float, Integer, Integer, Symbol, TrueClass, FalseClass, NilClass
87
96
  true
88
97
  else
89
98
  false
@@ -3,14 +3,37 @@ require 'nydp/lexical_context_builder'
3
3
  require 'nydp/closure'
4
4
 
5
5
  module Nydp
6
- class PopArg
7
- def self.execute vm ; vm.args.pop ; end
8
- def self.to_s ; "" ; end
9
- def self.inspect ; "#pop_arg" ; end
6
+ class Fn < Proc
7
+ attr_accessor :src
8
+ def initialize &b
9
+ super &b
10
+ end
11
+ def to_s
12
+ Nydp.nydp_from_backtrace(source_location.join(":"))
13
+ end
14
+ def container_class_name
15
+ file, line = source_location
16
+ [file.split(/\//).last, line].join(":")
17
+ end
18
+ def inspect
19
+ [@name, Nydp.nydp_from_backtrace(source_location.join(":"))].compact.join(" : ")
20
+ end
21
+ def src
22
+ Nydp.nydp_from_backtrace(source_location.join(":"))
23
+ end
24
+ def nydp_type
25
+ :fn
26
+ end
27
+
28
+ def is_named name
29
+ @name = name
30
+ end
31
+
32
+ alias _nydp_call call
10
33
  end
11
34
 
12
35
  class InterpretedFunction
13
- NIL = Nydp::NIL
36
+ NIL = nil
14
37
  include Helper
15
38
  extend Helper
16
39
 
@@ -20,10 +43,63 @@ module Nydp
20
43
  body.map { |b| b.lexical_reach(n - 1) }.max
21
44
  end
22
45
 
23
- def self.build arg_list, body, bindings
46
+ def can_do?
47
+ arg_names == nil
48
+ end
49
+
50
+ def compile_do_expr_to_ruby indent, srcs
51
+ body.
52
+ map { |expr| expr.compile_to_ruby(" ", srcs, cando: true) }.
53
+ to_a.
54
+ join("\n").
55
+ split(/\n/). # need join-split to separate out embedded newlines (TODO worry about newlines within literal strings?)
56
+ map { |e| "#{indent} #{e}" }.
57
+ join("\n")
58
+ end
59
+
60
+ def compile_to_ruby indent, srcs, opts={}
61
+ an = arg_names
62
+ rubyargs = []
63
+ src_index = srcs.length
64
+
65
+ srcs << to_s
66
+
67
+ while (pair? an)
68
+ rubyargs << "_arg_#{an.car.to_s._nydp_name_to_rb_name}=nil"
69
+ an = an.cdr
70
+ end
71
+
72
+ if an
73
+ rest_arg = "_arg_#{an.to_s._nydp_name_to_rb_name}"
74
+ rubyargs << "*#{rest_arg}"
75
+ end
76
+
77
+ if rubyargs == []
78
+ rubyargs = ""
79
+ else
80
+ rubyargs = "|#{rubyargs.join ","}|"
81
+ # rubyargs = "(#{rubyargs.join ","})"
82
+ end
83
+
84
+ # code = "#{indent}(Nydp::Fn.new(@@src_#{src_index}) {#{rubyargs}\n"
85
+ code = "#{indent}##> (fn #{arg_names._nydp_inspect} #{body.to_a.map(&:_nydp_inspect).join(" ").gsub(/\n/, '\n')})\n"
86
+ code << "#{indent}(Nydp::Fn.new {#{rubyargs}\n"
87
+ # code << "#{indent}(Proc.new {#{rubyargs}\n"
88
+ # code = "(->#{rubyargs} {\n"
89
+ if rest_arg
90
+ code << "#{indent} #{rest_arg} = #{rest_arg}._nydp_wrapper\n"
91
+ end
92
+ bodycode = body.map { |expr| expr.compile_to_ruby(" ", srcs, cando: true) }.to_a
93
+
94
+ bodycode.push "#{bodycode.pop}._nydp_wrapper"
95
+ code << bodycode.join("\n").split(/\n/).map { |e| "#{indent} #{e}" }.join("\n")
96
+ code << "\n#{indent}})"
97
+ end
98
+
99
+ def self.build arg_list, body, bindings, ns
24
100
  my_params = { }
25
101
  index_parameters arg_list, my_params
26
- body = compile_body body, cons(my_params, bindings), []
102
+ body = compile_body body, cons(my_params, bindings), [], ns
27
103
  reach = body.map { |b| b.lexical_reach(-1) }.max
28
104
 
29
105
  ifn_klass = reach >= 0 ? InterpretedFunctionWithClosure : InterpretedFunctionWithoutClosure
@@ -35,11 +111,11 @@ module Nydp
35
111
  ifn
36
112
  end
37
113
 
38
- def self.compile_body body_forms, bindings, instructions
39
- instructions << Nydp::Compiler.compile(body_forms.car, bindings)
114
+ def self.compile_body body_forms, bindings, instructions, ns
115
+ instructions << Nydp::Compiler.compile(body_forms.car, bindings, ns)
40
116
 
41
117
  rest = body_forms.cdr
42
- if Nydp::NIL.is? rest
118
+ if !rest
43
119
  return Pair.from_list(instructions)
44
120
  else
45
121
  # PopArg is necessary because each expression pushes an arg onto the arg stack.
@@ -47,8 +123,8 @@ module Nydp
47
123
  # so we need the following line in order to remove unwanted args from the stack.
48
124
  # Each expression at some executes vm.push_arg(thing)
49
125
  # TODO find a more intelligent way to do this, eg change the meaning of vm or of push_arg in the expression vm.push_arg(thing)
50
- instructions << PopArg
51
- compile_body rest, bindings, instructions
126
+ # instructions << PopArg
127
+ compile_body rest, bindings, instructions, ns
52
128
  end
53
129
  end
54
130
 
@@ -64,59 +140,117 @@ module Nydp
64
140
  def nydp_type ; "fn" ; end
65
141
  def inspect ; to_s ; end
66
142
  def to_s
67
- "(fn #{arg_names.inspect} #{body.map { |b| b.inspect}.join(' ')})"
143
+ "(fn #{arg_names._nydp_inspect} #{body.map { |b| b._nydp_inspect}.join('\n')})"
144
+ end
145
+
146
+ def run_body vm
147
+ res = nil
148
+ self.body.each { |x| res = x.execute(vm) }
149
+ res
68
150
  end
69
151
  end
70
152
 
71
153
  class InterpretedFunctionWithClosure < InterpretedFunction
72
154
  def invoke_1 vm, ctx
73
- vm.push_instructions self.body, set_args_0(ctx)
155
+ cc = vm.current_context
156
+ vm.current_context = set_args_0(ctx)
157
+ res = run_body(vm)
158
+ vm.current_context = cc
159
+ res
160
+ # vm.push_instructions self.body, set_args_0(ctx)
74
161
  end
75
162
 
76
163
  def invoke_2 vm, ctx, arg
77
- vm.push_instructions self.body, set_args_1(ctx, arg)
164
+ cc = vm.current_context
165
+ vm.current_context = set_args_1(ctx, arg)
166
+ res = run_body(vm)
167
+ vm.current_context = cc
168
+ res
169
+ # vm.push_instructions self.body, set_args_1(ctx, arg)
78
170
  end
79
171
 
80
172
  def invoke_3 vm, ctx, arg_0, arg_1
81
- vm.push_instructions self.body, set_args_2(ctx, arg_0, arg_1)
173
+ cc = vm.current_context
174
+ vm.current_context = set_args_2(ctx, arg_0, arg_1)
175
+ res = run_body(vm)
176
+ vm.current_context = cc
177
+ res
178
+ # vm.push_instructions self.body, set_args_2(ctx, arg_0, arg_1)
82
179
  end
83
180
 
84
181
  def invoke_4 vm, ctx, arg_0, arg_1, arg_2
85
- vm.push_instructions self.body, set_args_3(ctx, arg_0, arg_1, arg_2)
182
+ cc = vm.current_context
183
+ vm.current_context = set_args_3(ctx, arg_0, arg_1, arg_2)
184
+ res = run_body(vm)
185
+ vm.current_context = cc
186
+ res
187
+ # vm.push_instructions self.body, set_args_3(ctx, arg_0, arg_1, arg_2)
86
188
  end
87
189
 
88
190
  def invoke vm, ctx, arg_values
89
- vm.push_instructions self.body, set_args(ctx, arg_values)
191
+ cc = vm.current_context
192
+ vm.current_context = set_args(ctx, arg_values)
193
+ res = run_body(vm)
194
+ vm.current_context = cc
195
+ res
196
+ # vm.push_instructions self.body, set_args(ctx, arg_values)
90
197
  end
91
198
 
92
199
  def execute vm
93
- vm.push_arg Closure.new(self, vm.current_context)
200
+ Closure.new(self, vm.current_context)
201
+ # vm.push_arg Closure.new(self, vm.current_context)
94
202
  end
95
203
  end
96
204
 
97
205
  class InterpretedFunctionWithoutClosure < InterpretedFunction
98
206
  def invoke_1 vm
99
- vm.push_instructions self.body, set_args_0(vm.current_context)
207
+ cc = vm.current_context
208
+ vm.current_context = set_args_0(vm.current_context)
209
+ res = run_body(vm)
210
+ vm.current_context = cc
211
+ res
212
+ # vm.push_instructions self.body, set_args_0(vm.current_context)
100
213
  end
101
214
 
102
215
  def invoke_2 vm, arg
103
- vm.push_instructions self.body, set_args_1(vm.current_context, arg)
216
+ cc = vm.current_context
217
+ vm.current_context = set_args_1(vm.current_context, arg)
218
+ res = run_body(vm)
219
+ vm.current_context = cc
220
+ res
221
+ # vm.push_instructions self.body, set_args_1(vm.current_context, arg)
104
222
  end
105
223
 
106
224
  def invoke_3 vm, arg_0, arg_1
107
- vm.push_instructions self.body, set_args_2(vm.current_context, arg_0, arg_1)
225
+ cc = vm.current_context
226
+ vm.current_context = set_args_2(vm.current_context, arg_0, arg_1)
227
+ res = run_body(vm)
228
+ vm.current_context = cc
229
+ res
230
+ # vm.push_instructions self.body, set_args_2(vm.current_context, arg_0, arg_1)
108
231
  end
109
232
 
110
233
  def invoke_4 vm, arg_0, arg_1, arg_2
111
- vm.push_instructions self.body, set_args_3(vm.current_context, arg_0, arg_1, arg_2)
234
+ cc = vm.current_context
235
+ vm.current_context = set_args_3(vm.current_context, arg_0, arg_1, arg_2)
236
+ res = run_body(vm)
237
+ vm.current_context = cc
238
+ res
239
+ # vm.push_instructions self.body, set_args_3(vm.current_context, arg_0, arg_1, arg_2)
112
240
  end
113
241
 
114
242
  def invoke vm, arg_values
115
- vm.push_instructions self.body, set_args(vm.current_context, arg_values)
243
+ cc = vm.current_context
244
+ vm.current_context = set_args(vm.current_context, arg_values)
245
+ res = run_body(vm)
246
+ vm.current_context = cc
247
+ res
248
+ # vm.push_instructions self.body, set_args(vm.current_context, arg_values)
116
249
  end
117
250
 
118
251
  def execute vm
119
- vm.push_arg self
252
+ # vm.push_arg self
253
+ self
120
254
  end
121
255
  end
122
256
  end
@@ -49,14 +49,15 @@ module Nydp
49
49
  end
50
50
 
51
51
  def to_s
52
- values = []
53
- n = 0
54
- while at_index n
55
- values << at_index(n).inspect
56
- n += 1
57
- end
58
- parent_s = parent ? " parent #{parent.to_s}" : ""
59
- "(context (#{values.join ' '})#{parent_s})"
52
+ # values = []
53
+ # n = 0
54
+ # while at_index n
55
+ # values << at_index(n)._nydp_inspect
56
+ # n += 1
57
+ # end
58
+ # parent_s = parent ? " parent #{parent.to_s}" : ""
59
+ # "(context (#{values.join ' '})#{parent_s})"
60
+ "(NEW context)"
60
61
  end
61
62
  end
62
63
  end
@@ -103,7 +103,7 @@ module Nydp::LexicalContextBuilder
103
103
  proper = arg_names.proper?
104
104
  else
105
105
  size = 0
106
- proper = Nydp::NIL.is? arg_names
106
+ proper = (!arg_names)
107
107
  end
108
108
  const_get(proper ? :"B_#{size}" : :"B_#{size}_Rest")
109
109
  end
data/lib/nydp/literal.rb CHANGED
@@ -7,12 +7,12 @@ module Nydp
7
7
  @expression = expression
8
8
  end
9
9
 
10
- def self.build expression, bindings
10
+ def self.build expression, bindings, ns
11
11
  new expression
12
12
  end
13
13
 
14
- def execute vm
15
- vm.push_arg expression
14
+ def compile_to_ruby indent, srcs, opts=nil
15
+ "#{indent}#{expression.compile_to_ruby "", srcs}"
16
16
  end
17
17
 
18
18
  def nydp_type ; :literal ; end
@@ -20,10 +20,6 @@ module Nydp
20
20
  def to_s ; @expression.to_s ; end
21
21
  def to_ruby ; n2r @expression ; end
22
22
 
23
- def coerce _
24
- [_, expression]
25
- end
26
-
27
23
  def > other
28
24
  other < expression
29
25
  end
data/lib/nydp/loop.rb ADDED
@@ -0,0 +1,72 @@
1
+ module Nydp
2
+ # class LoopBodyInstruction
3
+ # extend Helper
4
+ # include Helper
5
+
6
+ # def initialize loop_body, condition
7
+ # @loop_body, @condition = loop_body, cons(Nydp::PopArg, cons(condition))
8
+ # # @loop_body, @condition = loop_body, cons(condition)
9
+ # end
10
+
11
+ # def lexical_reach n
12
+ # @loop_body.lexical_reach(n)
13
+ # end
14
+
15
+ # def execute vm
16
+ # if vm.args.pop
17
+ # vm.push_ctx_instructions @condition
18
+ # @loop_body.execute vm
19
+ # else
20
+ # vm.push_arg nil
21
+ # end
22
+ # end
23
+
24
+ # def inspect
25
+ # "loop_body:#{@loop_body._nydp_inspect}"
26
+ # end
27
+
28
+ # def to_s
29
+ # "#{@loop_body.to_s}"
30
+ # end
31
+ # end
32
+
33
+ class Loop
34
+ extend Helper
35
+ include Helper
36
+ attr_reader :condition, :loop_body
37
+
38
+ def initialize cond, loop_body
39
+ @condition, @loop_body = cond, loop_body
40
+ end
41
+
42
+ def lexical_reach n
43
+ [condition.lexical_reach(n), loop_body.lexical_reach(n)].max
44
+ end
45
+
46
+ def inspect
47
+ "loop:#{condition._nydp_inspect}:#{loop_body._nydp_inspect}"
48
+ end
49
+
50
+ def to_s
51
+ "(loop #{condition.to_s} #{loop_body.to_s})"
52
+ end
53
+
54
+ def self.build expressions, bindings, ns
55
+ if expressions.is_a? Nydp::Pair
56
+ cond = Compiler.compile expressions.car, bindings, ns
57
+ loop_body = Compiler.compile expressions.cdr.car, bindings, ns
58
+ csig = sig(cond)
59
+ new(cond, loop_body)
60
+ else
61
+ raise "can't compile Loop: #{expressions._nydp_inspect}"
62
+ end
63
+ end
64
+
65
+ def compile_to_ruby indent, srcs, opts=nil
66
+ "#{indent}##> #{to_s.split(/\n/).join('\n')}\n" +
67
+ "#{indent}while (#{condition.compile_to_ruby "", srcs})
68
+ #{loop_body.compile_to_ruby(indent + " ", srcs, cando: true)}
69
+ #{indent}end"
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,52 @@
1
+ module Nydp
2
+ class Namespace
3
+ include Nydp::Helper
4
+
5
+ def method_missing name, *args
6
+ if name.to_s =~ /^ns_/
7
+ attr = name.to_s.gsub(/=$/, '').to_sym
8
+ singleton_class.instance_eval do
9
+ attr_accessor attr
10
+ end
11
+ send name, *args
12
+ else
13
+ super
14
+ end
15
+ end
16
+
17
+ def names
18
+ mm = methods.select { |m| m.to_s =~ /^ns_.*[^=]$/ }.map { |m| nydp_name(m).to_sym }
19
+ end
20
+
21
+ def nydp_name n
22
+ n.to_s.gsub(/^ns_/, '').gsub(/_../) { |ch| ch[1,2].to_i(16).chr }
23
+ end
24
+
25
+ def ruby_name n
26
+ n.to_s._nydp_name_to_rb_name
27
+ end
28
+
29
+ def assign name, value
30
+ send "ns_#{ruby_name name}=", value
31
+ end
32
+
33
+ def fetch name
34
+ send "ns_#{ruby_name name}"
35
+ end
36
+
37
+ def apply name, *args
38
+ fn = if name.is_a?(String) || name.is_a?(::Symbol)
39
+ fetch name
40
+ elsif name.respond_to? :call
41
+ name
42
+ end
43
+
44
+ raise "can't apply #{name.inspect} : not a function" unless fn && fn.respond_to?(:call)
45
+
46
+ fn.call *(args.map { |a| r2n a })
47
+
48
+ rescue StandardError => e
49
+ raise Nydp::Error.new("Invoking #{name}\nwith args (#{args.map(&:_nydp_compact_inspect).join(' ')})")
50
+ end
51
+ end
52
+ end