nydp 0.5.1 → 0.6.0

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.
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