nydp 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +77 -56
- data/lib/lisp/core-000.nydp +1 -1
- data/lib/lisp/core-010-precompile.nydp +49 -29
- data/lib/lisp/core-012-utils.nydp +12 -8
- data/lib/lisp/core-015-documentation.nydp +41 -15
- data/lib/lisp/core-017-builtin-dox.nydp +621 -100
- data/lib/lisp/core-020-utils.nydp +33 -6
- data/lib/lisp/core-025-warnings.nydp +1 -1
- data/lib/lisp/core-030-syntax.nydp +64 -48
- data/lib/lisp/core-035-flow-control.nydp +20 -28
- data/lib/lisp/core-037-list-utils.nydp +84 -21
- data/lib/lisp/core-040-utils.nydp +8 -5
- data/lib/lisp/core-041-string-utils.nydp +17 -11
- data/lib/lisp/core-043-list-utils.nydp +140 -77
- data/lib/lisp/core-045-dox-utils.nydp +1 -0
- data/lib/lisp/core-050-test-runner.nydp +8 -12
- data/lib/lisp/core-070-prefix-list.nydp +19 -15
- data/lib/lisp/core-080-pretty-print.nydp +13 -5
- data/lib/lisp/core-090-hook.nydp +11 -11
- data/lib/lisp/core-100-utils.nydp +51 -66
- data/lib/lisp/core-110-hash-utils.nydp +34 -7
- data/lib/lisp/core-120-settings.nydp +14 -9
- data/lib/lisp/core-130-validations.nydp +28 -13
- data/lib/lisp/core-900-benchmarking.nydp +420 -47
- data/lib/lisp/tests/000-empty-args-examples.nydp +5 -0
- data/lib/lisp/tests/andify-examples.nydp +1 -1
- data/lib/lisp/tests/auto-hash-examples.nydp +6 -1
- data/lib/lisp/tests/best-examples.nydp +1 -1
- data/lib/lisp/tests/boot-tests.nydp +1 -1
- data/lib/lisp/tests/date-examples.nydp +129 -102
- data/lib/lisp/tests/destructuring-examples.nydp +1 -1
- data/lib/lisp/tests/dox-tests.nydp +2 -2
- data/lib/lisp/tests/hash-examples.nydp +58 -33
- data/lib/lisp/tests/list-tests.nydp +137 -1
- data/lib/lisp/tests/pretty-print-tests.nydp +12 -0
- data/lib/lisp/tests/rotate-2d-array-examples.nydp +26 -0
- data/lib/lisp/tests/sort-examples.nydp +5 -5
- data/lib/lisp/tests/string-tests.nydp +30 -5
- data/lib/lisp/tests/syntax-tests.nydp +10 -2
- data/lib/lisp/tests/time-examples.nydp +8 -1
- data/lib/lisp/tests/unparse-tests.nydp +13 -7
- data/lib/nydp/assignment.rb +15 -28
- data/lib/nydp/builtin/abs.rb +4 -3
- data/lib/nydp/builtin/apply.rb +8 -10
- data/lib/nydp/builtin/cdr_set.rb +1 -1
- data/lib/nydp/builtin/comment.rb +1 -3
- data/lib/nydp/builtin/date.rb +11 -28
- data/lib/nydp/builtin/divide.rb +3 -10
- data/lib/nydp/builtin/ensuring.rb +6 -21
- data/lib/nydp/builtin/error.rb +2 -4
- data/lib/nydp/builtin/eval.rb +9 -4
- data/lib/nydp/builtin/greater_than.rb +7 -8
- data/lib/nydp/builtin/handle_error.rb +10 -34
- data/lib/nydp/builtin/hash.rb +24 -45
- data/lib/nydp/builtin/inspect.rb +1 -3
- data/lib/nydp/builtin/is_equal.rb +4 -7
- data/lib/nydp/builtin/less_than.rb +6 -7
- data/lib/nydp/builtin/log.rb +7 -0
- data/lib/nydp/builtin/math_ceiling.rb +1 -3
- data/lib/nydp/builtin/math_floor.rb +1 -3
- data/lib/nydp/builtin/math_power.rb +1 -3
- data/lib/nydp/builtin/math_round.rb +2 -2
- data/lib/nydp/builtin/minus.rb +7 -14
- data/lib/nydp/builtin/parse.rb +5 -5
- data/lib/nydp/builtin/parse_in_string.rb +5 -7
- data/lib/nydp/builtin/plus.rb +14 -31
- data/lib/nydp/builtin/pre_compile.rb +1 -3
- data/lib/nydp/builtin/puts.rb +4 -8
- data/lib/nydp/builtin/quit.rb +1 -1
- data/lib/nydp/builtin/rand.rb +6 -11
- data/lib/nydp/builtin/random_string.rb +2 -4
- data/lib/nydp/builtin/rng.rb +25 -0
- data/lib/nydp/builtin/ruby_wrap.rb +27 -14
- data/lib/nydp/builtin/script_run.rb +1 -3
- data/lib/nydp/builtin/set_intersection.rb +3 -4
- data/lib/nydp/builtin/set_union.rb +3 -4
- data/lib/nydp/builtin/sort.rb +2 -7
- data/lib/nydp/builtin/string_match.rb +5 -13
- data/lib/nydp/builtin/string_replace.rb +2 -7
- data/lib/nydp/builtin/string_split.rb +3 -8
- data/lib/nydp/builtin/sym.rb +2 -9
- data/lib/nydp/builtin/thread_locals.rb +2 -2
- data/lib/nydp/builtin/time.rb +38 -44
- data/lib/nydp/builtin/times.rb +6 -15
- data/lib/nydp/builtin/to_integer.rb +8 -14
- data/lib/nydp/builtin/to_string.rb +2 -13
- data/lib/nydp/builtin/type_of.rb +10 -16
- data/lib/nydp/builtin/vm_info.rb +2 -10
- data/lib/nydp/builtin.rb +15 -37
- data/lib/nydp/compiler.rb +29 -19
- data/lib/nydp/cond.rb +95 -88
- data/lib/nydp/context_symbol.rb +11 -9
- data/lib/nydp/core.rb +74 -73
- data/lib/nydp/core_ext.rb +88 -24
- data/lib/nydp/date.rb +22 -19
- data/lib/nydp/error.rb +2 -3
- data/lib/nydp/function_invocation.rb +76 -289
- data/lib/nydp/helper.rb +18 -9
- data/lib/nydp/interpreted_function.rb +159 -25
- data/lib/nydp/lexical_context.rb +9 -8
- data/lib/nydp/lexical_context_builder.rb +1 -1
- data/lib/nydp/literal.rb +3 -7
- data/lib/nydp/loop.rb +72 -0
- data/lib/nydp/namespace.rb +52 -0
- data/lib/nydp/pair.rb +146 -50
- data/lib/nydp/parser.rb +9 -11
- data/lib/nydp/plugin.rb +88 -19
- data/lib/nydp/runner.rb +141 -23
- data/lib/nydp/symbol.rb +16 -26
- data/lib/nydp/symbol_lookup.rb +3 -2
- data/lib/nydp/tokeniser.rb +1 -1
- data/lib/nydp/truth.rb +2 -37
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp.rb +33 -44
- data/nydp.gemspec +2 -1
- data/spec/date_spec.rb +26 -32
- data/spec/embedded_spec.rb +22 -22
- data/spec/error_spec.rb +12 -16
- data/spec/foreign_hash_spec.rb +21 -36
- data/spec/hash_non_hash_behaviour_spec.rb +12 -29
- data/spec/hash_spec.rb +36 -49
- data/spec/literal_spec.rb +6 -6
- data/spec/nydp_spec.rb +14 -14
- data/spec/pair_spec.rb +8 -8
- data/spec/parser_spec.rb +41 -37
- data/spec/rand_spec.rb +1 -4
- data/spec/spec_helper.rb +3 -3
- data/spec/string_atom_spec.rb +15 -16
- data/spec/symbol_spec.rb +27 -52
- data/spec/thread_local_spec.rb +23 -8
- data/spec/time_spec.rb +4 -10
- data/spec/tokeniser_spec.rb +10 -10
- metadata +25 -13
- data/lib/nydp/builtin/modulo.rb +0 -11
- data/lib/nydp/builtin/regexp.rb +0 -7
- data/lib/nydp/builtin/sqrt.rb +0 -7
- data/lib/nydp/builtin/string_pad_left.rb +0 -7
- data/lib/nydp/builtin/string_pad_right.rb +0 -7
- data/lib/nydp/hash.rb +0 -9
- data/lib/nydp/image_store.rb +0 -21
- data/lib/nydp/vm.rb +0 -129
data/lib/nydp/pair.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Nydp::Pair
|
2
|
-
NIL =
|
2
|
+
NIL = nil
|
3
3
|
include Nydp::Helper, Enumerable
|
4
4
|
extend Nydp::Helper
|
5
5
|
|
@@ -14,19 +14,95 @@ class Nydp::Pair
|
|
14
14
|
def cadr ; cdr.car ; end
|
15
15
|
def cdar ; car.cdr ; end
|
16
16
|
def cddr ; cdr.cdr ; end
|
17
|
-
def car= thing ; @car = thing
|
18
|
-
def cdr= thing ; @cdr = thing
|
19
|
-
# def hash ; @_hash ||= (car.hash + cdr.hash) ; end
|
20
|
-
def hash ; (car.hash + cdr.hash) ; end # can't cache hash of symbol, breaks when unmarshalling
|
17
|
+
def car= thing ; @car = thing ; end
|
18
|
+
def cdr= thing ; @cdr = thing ; end
|
21
19
|
def eql? other ; self == other ; end
|
22
|
-
def
|
23
|
-
def + other ; copy.append other ; end
|
20
|
+
def + other ; copy_append other ; end
|
24
21
|
def size ; 1 + (cdr.is_a?(Nydp::Pair) ? cdr.size : 0) ; end
|
25
22
|
def inspect ; "(#{inspect_rest})" ; end
|
26
|
-
def
|
27
|
-
def
|
28
|
-
def
|
29
|
-
def
|
23
|
+
def [] i ; nth i ; end
|
24
|
+
def & other ; self.class.from_list((Set.new(self) & Array(other)).to_a) ; end
|
25
|
+
def | other ; self.class.from_list((Set.new(self) | Array(other)).to_a) ; end
|
26
|
+
def - other ; self.class.from_list((Set.new(self) - Array(other)).to_a) ; end
|
27
|
+
def proper? ; (!cdr) || (cdr.is_a?(Nydp::Pair) && cdr.proper?) ; end
|
28
|
+
|
29
|
+
# def method_missing m, *args
|
30
|
+
# to_a.send m, *args
|
31
|
+
# end
|
32
|
+
|
33
|
+
# can't cache hash of symbol, breaks when unmarshalling
|
34
|
+
def hash
|
35
|
+
a = 0
|
36
|
+
x = self
|
37
|
+
while (x.is_a? Nydp::Pair)
|
38
|
+
a = a + x.car.hash
|
39
|
+
x = x.cdr
|
40
|
+
end
|
41
|
+
|
42
|
+
a + x.hash
|
43
|
+
end
|
44
|
+
|
45
|
+
def copy
|
46
|
+
a = last = cons
|
47
|
+
x = self
|
48
|
+
while (x.is_a? Nydp::Pair)
|
49
|
+
last = last.cdr = cons(x.car)
|
50
|
+
x = x.cdr
|
51
|
+
end
|
52
|
+
|
53
|
+
last.cdr = x
|
54
|
+
a.cdr
|
55
|
+
end
|
56
|
+
|
57
|
+
def copy_append lastcdr
|
58
|
+
a = last = cons
|
59
|
+
x = self
|
60
|
+
while (x.is_a? Nydp::Pair)
|
61
|
+
last = last.cdr = cons(x.car)
|
62
|
+
x = x.cdr
|
63
|
+
end
|
64
|
+
|
65
|
+
last.cdr = lastcdr
|
66
|
+
a.cdr
|
67
|
+
end
|
68
|
+
|
69
|
+
def map
|
70
|
+
a = last = cons
|
71
|
+
x = self
|
72
|
+
while (x.is_a? Nydp::Pair)
|
73
|
+
last = last.cdr = cons(yield x.car)
|
74
|
+
x = x.cdr
|
75
|
+
end
|
76
|
+
|
77
|
+
last.cdr = yield(x) if x
|
78
|
+
a.cdr
|
79
|
+
end
|
80
|
+
|
81
|
+
def join str
|
82
|
+
to_a.join(str)
|
83
|
+
end
|
84
|
+
|
85
|
+
def compile_to_ruby indent, srcs, opts=nil
|
86
|
+
a,x = [], self
|
87
|
+
while x.is_a?(Nydp::Pair)
|
88
|
+
a << x.car.compile_to_ruby("", srcs)
|
89
|
+
x = x.cdr
|
90
|
+
end
|
91
|
+
|
92
|
+
if !x || (x.is_a?(Nydp::Literal) && !x.expression)
|
93
|
+
"#{indent}list(" + a.join(", ") + ")"
|
94
|
+
else
|
95
|
+
"#{indent}Nydp::Pair.from_list([" + a.join(", ") + "], #{x.compile_to_ruby "", srcs})"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def nth n
|
100
|
+
xs = self
|
101
|
+
while n > 0
|
102
|
+
xs, n = xs.cdr, n-1
|
103
|
+
end
|
104
|
+
xs.car
|
105
|
+
end
|
30
106
|
|
31
107
|
def index_of x
|
32
108
|
if x == car
|
@@ -51,24 +127,34 @@ class Nydp::Pair
|
|
51
127
|
|
52
128
|
# returns Array of elements as they are
|
53
129
|
def to_a list=[]
|
54
|
-
|
55
|
-
|
130
|
+
x = self
|
131
|
+
while x.is_a?(Nydp::Pair)
|
132
|
+
list << x.car
|
133
|
+
x = x.cdr
|
134
|
+
end
|
135
|
+
list
|
56
136
|
end
|
57
137
|
|
138
|
+
# this breaks everything even though it seems like the logical thing to do...
|
139
|
+
# def to_ary
|
140
|
+
# to_a
|
141
|
+
# end
|
142
|
+
|
58
143
|
def self.parse_list list
|
59
|
-
if
|
144
|
+
if list.slice(-2) == :"."
|
60
145
|
from_list(list[0...-2], list.slice(-1))
|
61
146
|
else
|
62
147
|
from_list list
|
63
148
|
end
|
64
149
|
end
|
65
150
|
|
66
|
-
def self.from_list list, last=
|
67
|
-
|
68
|
-
last
|
69
|
-
|
70
|
-
Nydp::Pair.new list[n], from_list(list, last, n+1)
|
151
|
+
def self.from_list list, last=nil, n=list.size-1
|
152
|
+
while (n >= 0)
|
153
|
+
last = cons(list[n], last)
|
154
|
+
n -= 1
|
71
155
|
end
|
156
|
+
|
157
|
+
last
|
72
158
|
end
|
73
159
|
|
74
160
|
def == other
|
@@ -76,37 +162,48 @@ class Nydp::Pair
|
|
76
162
|
end
|
77
163
|
|
78
164
|
def each &block
|
79
|
-
|
80
|
-
|
165
|
+
xs = self
|
166
|
+
while xs
|
167
|
+
yield xs.car
|
168
|
+
xs = xs.cdr
|
169
|
+
end
|
81
170
|
end
|
82
171
|
|
83
172
|
def to_s
|
84
|
-
if car
|
85
|
-
if
|
173
|
+
if (car == :quote)
|
174
|
+
if !cdr.cdr
|
86
175
|
"'#{cdr.car.to_s}"
|
87
176
|
else
|
88
177
|
"'#{cdr.to_s}"
|
89
178
|
end
|
90
|
-
elsif car
|
91
|
-
if
|
179
|
+
elsif (car == :"brace-list")
|
180
|
+
if !cdr
|
92
181
|
"{}"
|
93
182
|
else
|
94
183
|
"{ #{cdr.to_s_rest} }"
|
95
184
|
end
|
96
|
-
elsif car
|
97
|
-
|
185
|
+
elsif (car == :"percent-syntax")
|
186
|
+
cdr.to_a.compact.join("%")
|
187
|
+
elsif (car == :"colon-syntax")
|
188
|
+
cdr.to_a.compact.join(":")
|
189
|
+
elsif (car == :"dot-syntax")
|
190
|
+
cdr.to_a.compact.join(".")
|
191
|
+
elsif (car == :"prefix-list")
|
192
|
+
"#{cdr.car.to_s}#{cdr.cdr.car.to_s}"
|
193
|
+
elsif (car == :quasiquote)
|
194
|
+
if !cdr.cdr
|
98
195
|
"`#{cdr.car.to_s}"
|
99
196
|
else
|
100
197
|
"`#{cdr.to_s}"
|
101
198
|
end
|
102
|
-
elsif car
|
103
|
-
if
|
199
|
+
elsif (car == :unquote)
|
200
|
+
if !cdr.cdr
|
104
201
|
",#{cdr.car.to_s}"
|
105
202
|
else
|
106
203
|
",#{cdr.to_s}"
|
107
204
|
end
|
108
|
-
elsif car
|
109
|
-
if
|
205
|
+
elsif (car == :"unquote-splicing")
|
206
|
+
if !cdr.cdr
|
110
207
|
",@#{cdr.car.to_s}"
|
111
208
|
else
|
112
209
|
",@#{cdr.to_s}"
|
@@ -116,42 +213,41 @@ class Nydp::Pair
|
|
116
213
|
end
|
117
214
|
end
|
118
215
|
|
216
|
+
def to_s_car
|
217
|
+
if (!car)
|
218
|
+
"nil"
|
219
|
+
elsif car.is_a?(String)
|
220
|
+
car.inspect
|
221
|
+
elsif car.is_a?(Symbol)
|
222
|
+
car._nydp_inspect
|
223
|
+
else
|
224
|
+
car.to_s
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
119
228
|
def to_s_rest
|
120
229
|
cdr_s = if cdr.is_a?(self.class)
|
121
230
|
cdr.to_s_rest
|
122
|
-
elsif
|
123
|
-
nil
|
124
|
-
else
|
231
|
+
elsif cdr
|
125
232
|
". #{cdr.to_s}"
|
126
233
|
end
|
127
234
|
|
128
|
-
[
|
235
|
+
[to_s_car, cdr_s].compact.join " "
|
129
236
|
end
|
130
237
|
|
131
238
|
def inspect_rest
|
132
|
-
res = [car.
|
239
|
+
res = [car._nydp_inspect]
|
133
240
|
it = cdr
|
134
|
-
while it
|
241
|
+
while it
|
135
242
|
if it.is_a?(self.class)
|
136
|
-
res << it.car.
|
243
|
+
res << it.car._nydp_inspect
|
137
244
|
it = it.cdr
|
138
245
|
else
|
139
246
|
res << "."
|
140
|
-
res << it.
|
247
|
+
res << it._nydp_inspect
|
141
248
|
it = nil
|
142
249
|
end
|
143
250
|
end
|
144
251
|
res.compact.join " "
|
145
252
|
end
|
146
|
-
|
147
|
-
def append thing
|
148
|
-
if Nydp::NIL.is? self.cdr
|
149
|
-
self.cdr = thing
|
150
|
-
elsif pair? self.cdr
|
151
|
-
self.cdr.append thing
|
152
|
-
else
|
153
|
-
raise "can't append #{thing} to list #{self} : cdr is #{self.cdr.inspect}"
|
154
|
-
end
|
155
|
-
self
|
156
|
-
end
|
157
253
|
end
|
data/lib/nydp/parser.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
module Nydp
|
2
2
|
class Parser
|
3
|
-
attr_accessor :ns
|
4
|
-
|
5
|
-
def initialize ns
|
6
|
-
@ns = ns
|
7
|
-
# TODO pre-initialize all the hard-coded syms used here, eg
|
8
|
-
# @quote = sym(:quote)
|
9
|
-
# @quasiquote = sym(:quasiquote)
|
10
|
-
end
|
11
|
-
|
12
3
|
def sym name
|
13
|
-
|
4
|
+
n = name.to_s.to_sym
|
5
|
+
if n == :nil
|
6
|
+
nil
|
7
|
+
elsif n == :t
|
8
|
+
true
|
9
|
+
else
|
10
|
+
n
|
11
|
+
end
|
14
12
|
end
|
15
13
|
|
16
14
|
def read_list token_stream, termination_token, list=[]
|
@@ -102,7 +100,7 @@ module Nydp
|
|
102
100
|
when :string_open_delim
|
103
101
|
string token_stream, token.last, close_delimiter_for(token.last)
|
104
102
|
when :sym_open_delim
|
105
|
-
sym token_stream.next_string_fragment(token.last, /\|/, nil)
|
103
|
+
sym token_stream.next_string_fragment(token.last, /\|/, nil).string
|
106
104
|
when :left_paren
|
107
105
|
prefix_list token[1], read_list(token_stream, :right_paren)
|
108
106
|
when :left_brace
|
data/lib/nydp/plugin.rb
CHANGED
@@ -1,40 +1,109 @@
|
|
1
|
-
require '
|
1
|
+
require 'digest'
|
2
2
|
|
3
3
|
module Nydp
|
4
4
|
PLUGINS = []
|
5
|
-
|
5
|
+
COMMENT_RX = /^.*##> /
|
6
|
+
GENERATED_CLASS_PREFIX_REGEXP = /#{Nydp::GENERATED_CLASS_PREFIX}/
|
6
7
|
|
8
|
+
module PluginHelper
|
9
|
+
def base_path ; "" ; end # override this to provide common prefix for plugin filenames
|
10
|
+
|
11
|
+
def file_readers filenames, bp=base_path
|
12
|
+
filenames.map { |f| Nydp::FileReader.new(f.gsub(bp, ""), f) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def relative_path name
|
16
|
+
# File.join File.expand_path(File.dirname(__FILE__)), name
|
17
|
+
File.join File.expand_path(File.dirname(caller[0].split(/:\d+:/)[0])), name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.nydp_from_backtrace str
|
22
|
+
file, original_line, meth = str.split(/:/)
|
23
|
+
line = original_line.to_i - 2 # -1 to convert from 1-based index to zero-based index ; -1 to start looking backwards from previous line
|
24
|
+
filepath = File.expand_path file
|
25
|
+
|
26
|
+
if filepath =~ Nydp::GENERATED_CLASS_PREFIX_REGEXP
|
27
|
+
code = File.read filepath
|
28
|
+
lines = code.split /\n/
|
29
|
+
|
30
|
+
while line > 0 && !(lines[line] =~ COMMENT_RX)
|
31
|
+
line = line - 1
|
32
|
+
end
|
33
|
+
|
34
|
+
if (line >= 0 && (lines[line] =~ COMMENT_RX))
|
35
|
+
comment = lines[line].sub(COMMENT_RX, '').gsub(/\\n/, "\n")
|
36
|
+
return [(filepath.sub(base_gen_path + '/', '') + ":" + original_line), comment].join("\n")
|
37
|
+
else
|
38
|
+
return str
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
str
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.enhance_backtrace bt
|
46
|
+
bt.map { |s| nydp_from_backtrace s }
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.base_gen_path ; File.expand_path("rubycode/") ; end
|
7
50
|
def self.plug_in plugin ; PLUGINS << plugin ; end
|
8
51
|
def self.load_rake_tasks ; PLUGINS.each &:load_rake_tasks ; end
|
9
52
|
def self.setup ns ; PLUGINS.each { |plg| plg.setup ns } ; end
|
10
|
-
def self.loadfiles ; PLUGINS.map(&:loadfiles).flatten ; end
|
11
|
-
def self.testfiles ; PLUGINS.map(&:testfiles).flatten ; end
|
12
53
|
def self.plugin_names ; PLUGINS.map(&:name) ; end
|
13
|
-
|
14
|
-
|
15
|
-
|
54
|
+
|
55
|
+
def self.loadall ns, plugin, files, manifest
|
56
|
+
ns.apply :"script-run", :"plugin-start", plugin.name if plugin
|
16
57
|
files.each { |f|
|
17
|
-
|
18
|
-
|
19
|
-
Nydp::Runner.new(vm, ns, reader, nil, (script_name || f)).run
|
20
|
-
yield script_name if block_given?
|
58
|
+
Nydp::Runner.new(ns, f, nil, f.name, manifest).run
|
59
|
+
yield f.name if block_given?
|
21
60
|
}
|
22
61
|
ensure
|
23
|
-
|
62
|
+
ns.apply :"script-run", :"plugin-end", plugin.name if plugin
|
24
63
|
end
|
25
64
|
|
26
65
|
def self.all_files ; PLUGINS.each_with_object([]) { |plg, list| plg.loadfiles.each { |f| list << f } } ; end
|
27
|
-
def self.set_image_store store ; @@image_store = store ; end
|
28
|
-
|
29
|
-
def self.get_nydp ; @@image_store.get ; end
|
30
66
|
|
31
67
|
def self.build_nydp &block
|
32
|
-
|
68
|
+
rc = base_gen_path
|
69
|
+
$LOAD_PATH.unshift rc unless $LOAD_PATH.include?(rc)
|
70
|
+
|
71
|
+
digest = Digest::SHA256.hexdigest(all_files.map { |f| f.read }.join("\n"))
|
72
|
+
mname = "Manifest_#{digest}"
|
73
|
+
|
74
|
+
ns = ::Nydp::Namespace.new
|
33
75
|
setup(ns)
|
34
|
-
|
35
|
-
|
36
|
-
|
76
|
+
|
77
|
+
digest = ""
|
78
|
+
|
79
|
+
PLUGINS.each { |plugin|
|
80
|
+
digest = install_plugin ns, plugin, digest, &block
|
37
81
|
}
|
82
|
+
|
38
83
|
ns
|
39
84
|
end
|
85
|
+
|
86
|
+
def self.install_plugin ns, plugin, digest, &block
|
87
|
+
f0 = plugin.loadfiles.map { |f| f.read }.join("\n")
|
88
|
+
f1 = plugin.testfiles.map { |f| f.read }.join("\n")
|
89
|
+
digest = Digest::SHA256.hexdigest([digest, f0, f1].join("\n"))
|
90
|
+
mname = "Manifest_#{digest}"
|
91
|
+
|
92
|
+
if Nydp.logger
|
93
|
+
Nydp.logger.info "manifest name for plugin #{plugin.name.inspect} is #{mname.inspect}"
|
94
|
+
end
|
95
|
+
|
96
|
+
begin
|
97
|
+
require mname
|
98
|
+
const_get(mname).build ns
|
99
|
+
|
100
|
+
rescue LoadError => e
|
101
|
+
manifest = []
|
102
|
+
loadall ns, plugin, plugin.loadfiles, manifest, &block
|
103
|
+
loadall ns, plugin, plugin.testfiles, manifest, &block
|
104
|
+
Nydp::Evaluator.mk_manifest "Manifest_#{digest}", manifest
|
105
|
+
end
|
106
|
+
|
107
|
+
digest
|
108
|
+
end
|
40
109
|
end
|
data/lib/nydp/runner.rb
CHANGED
@@ -1,19 +1,51 @@
|
|
1
|
+
require 'digest'
|
1
2
|
require 'readline'
|
2
3
|
require 'nydp/readline_history'
|
3
4
|
|
4
5
|
module Nydp
|
5
6
|
class StringReader
|
6
|
-
|
7
|
+
attr_accessor :name
|
8
|
+
|
9
|
+
def initialize name, string
|
10
|
+
@name, @string, @read = name, string, string
|
11
|
+
end
|
12
|
+
|
7
13
|
def nextline
|
8
|
-
s = @
|
14
|
+
s = @read ; @read = nil ; s
|
15
|
+
end
|
16
|
+
|
17
|
+
def read
|
18
|
+
@string
|
9
19
|
end
|
10
20
|
end
|
11
21
|
|
12
22
|
class StreamReader
|
13
|
-
|
23
|
+
attr_accessor :name
|
24
|
+
|
25
|
+
def initialize name, stream
|
26
|
+
@name, @stream = name, stream
|
27
|
+
end
|
28
|
+
|
14
29
|
def nextline
|
15
30
|
@stream.readline unless @stream.eof?
|
16
31
|
end
|
32
|
+
|
33
|
+
def read
|
34
|
+
""
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class FileReader < StreamReader
|
39
|
+
attr_accessor :filename
|
40
|
+
|
41
|
+
def initialize name, filename
|
42
|
+
super name, File.new(filename)
|
43
|
+
@filename = filename
|
44
|
+
end
|
45
|
+
|
46
|
+
def read
|
47
|
+
File.read filename
|
48
|
+
end
|
17
49
|
end
|
18
50
|
|
19
51
|
class ReadlineReader
|
@@ -37,52 +69,138 @@ module Nydp
|
|
37
69
|
end
|
38
70
|
|
39
71
|
class Evaluator
|
40
|
-
attr_accessor :
|
72
|
+
attr_accessor :ns, :name
|
41
73
|
|
42
|
-
def initialize
|
43
|
-
@name
|
44
|
-
@
|
45
|
-
@
|
46
|
-
@precompile = Symbol.mk(:"pre-compile", ns)
|
47
|
-
@quote = Symbol.mk(:quote, ns)
|
74
|
+
def initialize ns, name
|
75
|
+
@name = name
|
76
|
+
@ns = ns
|
77
|
+
@rubydir = FileUtils.mkdir_p "rubycode"
|
48
78
|
end
|
49
79
|
|
50
|
-
def
|
80
|
+
def compile_expr expr
|
51
81
|
begin
|
52
|
-
|
82
|
+
Compiler.compile(expr, nil, ns)
|
53
83
|
rescue StandardError => e
|
54
|
-
raise Nydp::Error, "failed to
|
84
|
+
raise Nydp::Error, "failed to compile #{expr._nydp_inspect}"
|
55
85
|
end
|
56
86
|
end
|
57
87
|
|
58
|
-
def
|
59
|
-
|
88
|
+
def self.mk_manifest name, class_list
|
89
|
+
class_expr = <<KLA
|
90
|
+
#{class_list.map {|k| "require '#{k}'" }.join("\n")}
|
91
|
+
|
92
|
+
class #{name}
|
93
|
+
def self.build ns
|
94
|
+
#{class_list.map {|k| "#{k}.new(ns).call" }.join("\n ")}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
KLA
|
98
|
+
File.open("rubycode/#{name}.rb", "w") { |f|
|
99
|
+
fullpath = File.expand_path("rubycode/#{name}.rb")
|
100
|
+
Nydp.logger.info "writing #{fullpath}" if Nydp.logger
|
101
|
+
f.write class_expr
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
class CompiledExpression
|
106
|
+
attr_accessor :ns
|
107
|
+
def initialize ns
|
108
|
+
@ns = ns
|
109
|
+
end
|
110
|
+
|
111
|
+
def list *things
|
112
|
+
Nydp::Pair.from_list things
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def mk_ruby_source src, precompiled, compiled_expr, cname
|
117
|
+
srcs = []
|
118
|
+
ruby_expr = compiled_expr.compile_to_ruby " ", srcs
|
119
|
+
six = 0
|
120
|
+
srcs = srcs.map { |s|
|
121
|
+
s = " @@src_#{six} = #{s.inspect}"
|
122
|
+
six += 1
|
123
|
+
s
|
124
|
+
}
|
125
|
+
class_expr = "class #{cname} < Nydp::Runner::CompiledExpression
|
126
|
+
|
127
|
+
#{srcs.join("\n")}
|
128
|
+
|
129
|
+
def src
|
130
|
+
#{src.inspect.inspect}
|
131
|
+
end
|
132
|
+
|
133
|
+
def precompiled
|
134
|
+
#{precompiled.inspect.inspect}
|
135
|
+
end
|
136
|
+
|
137
|
+
def call
|
138
|
+
#{ruby_expr}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
#{cname}
|
143
|
+
"
|
144
|
+
File.open("rubycode/#{cname}.rb", "w") { |f| f.write class_expr }
|
145
|
+
class_expr
|
146
|
+
end
|
147
|
+
|
148
|
+
def mk_ruby_class src, precompiled, compiled_expr, cname
|
149
|
+
begin
|
150
|
+
require cname
|
151
|
+
self.class.const_get(cname)
|
152
|
+
|
153
|
+
rescue LoadError => e
|
154
|
+
# compiled_expr = compile_expr precompiled # TODO : delete line in #evaluate and uncomment this one
|
155
|
+
fname = "rubycode/#{cname}.rb"
|
156
|
+
txt = mk_ruby_source src, precompiled, compiled_expr, cname
|
157
|
+
|
158
|
+
eval(txt, nil, fname) || raise("failed to generate class #{cname} from src #{src}")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def eval_compiled compiled_expr, precompiled, src, manifest
|
163
|
+
return nil unless precompiled
|
164
|
+
|
165
|
+
digest = Digest::SHA256.hexdigest(precompiled.inspect)
|
166
|
+
cname = "#{GENERATED_CLASS_PREFIX}_#{digest.upcase}"
|
167
|
+
kla = mk_ruby_class src, precompiled, compiled_expr, cname
|
168
|
+
|
169
|
+
manifest << cname
|
170
|
+
|
171
|
+
kla.new(ns).call
|
172
|
+
|
173
|
+
rescue Exception => e
|
174
|
+
raise Nydp::Error, "failed to eval #{compiled_expr._nydp_inspect} from src #{src._nydp_inspect}"
|
60
175
|
end
|
61
176
|
|
62
|
-
def evaluate expr
|
63
|
-
|
177
|
+
def evaluate expr, manifest=[]
|
178
|
+
precompiled = ns.apply :"pre-compile-new-expression", expr
|
179
|
+
compiled = compile_expr precompiled # TODO : we don't need this step if the class already exists! Do it later only when we need it
|
180
|
+
eval_compiled compiled, precompiled, expr, manifest
|
64
181
|
end
|
65
182
|
end
|
66
183
|
|
67
184
|
class Runner < Evaluator
|
68
|
-
def initialize
|
69
|
-
super
|
185
|
+
def initialize ns, stream, printer=nil, name=nil, manifest=[]
|
186
|
+
super ns, name
|
70
187
|
@printer = printer
|
71
|
-
@parser = Nydp.new_parser
|
188
|
+
@parser = Nydp.new_parser
|
72
189
|
@tokens = Nydp.new_tokeniser stream
|
190
|
+
@manifest = manifest
|
73
191
|
end
|
74
192
|
|
75
193
|
def print val
|
76
|
-
@printer.puts val.
|
194
|
+
@printer.puts val._nydp_inspect if @printer
|
77
195
|
end
|
78
196
|
|
79
197
|
def run
|
80
198
|
Nydp.apply_function ns, :"script-run", :"script-start", name
|
81
|
-
res =
|
199
|
+
res = nil
|
82
200
|
begin
|
83
201
|
while !@tokens.finished
|
84
202
|
expr = @parser.expression(@tokens)
|
85
|
-
print(res = evaluate(expr)) unless expr.nil?
|
203
|
+
print(res = evaluate(expr, @manifest)) unless expr.nil?
|
86
204
|
end
|
87
205
|
ensure
|
88
206
|
Nydp.apply_function ns, :"script-run", :"script-end", name
|