nendo 0.5.4 → 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.
- data/lib/nendo.rb +16 -2843
- data/lib/ruby/builtin_functions.rb +510 -0
- data/lib/ruby/core.rb +140 -0
- data/lib/ruby/evaluator.rb +1349 -0
- data/lib/ruby/out_of_module.rb +74 -0
- data/lib/ruby/printer.rb +111 -0
- data/lib/ruby/reader.rb +585 -0
- data/lib/ruby/types.rb +309 -0
- metadata +12 -5
@@ -0,0 +1,510 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
#
|
4
|
+
# builtin_functions.rb - "builtin functions for nendo"
|
5
|
+
#
|
6
|
+
# Copyright (c) 2009-2010 Kiyoka Nishiyama <kiyoka@sumibi.org>
|
7
|
+
#
|
8
|
+
# Redistribution and use in source and binary forms, with or without
|
9
|
+
# modification, are permitted provided that the following conditions
|
10
|
+
# are met:
|
11
|
+
#
|
12
|
+
# 1. Redistributions of source code must retain the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer.
|
14
|
+
#
|
15
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
16
|
+
# notice, this list of conditions and the following disclaimer in the
|
17
|
+
# documentation and/or other materials provided with the distribution.
|
18
|
+
#
|
19
|
+
# 3. Neither the name of the authors nor the names of its contributors
|
20
|
+
# may be used to endorse or promote products derived from this
|
21
|
+
# software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
24
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
25
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
26
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
27
|
+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
28
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
29
|
+
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
30
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
31
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
32
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
33
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
#
|
35
|
+
module Nendo
|
36
|
+
|
37
|
+
# built-in functions
|
38
|
+
module BuiltinFunctions
|
39
|
+
def __assertFlat( *args )
|
40
|
+
if 0 == args.length
|
41
|
+
raise ArgumentError, "Error: + - * / % operator got illegal argument. "
|
42
|
+
else
|
43
|
+
args.each { |x|
|
44
|
+
if Cell == x.class or Nil == x.class
|
45
|
+
raise ArgumentError, "Error: + - * / % operator got illegal argument. "
|
46
|
+
end
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def __assertList( funcname, arg )
|
52
|
+
if Cell != arg.class
|
53
|
+
raise ArgumentError, "Error: %s expects a list argument.\n"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def _equal_QUMARK( a, b )
|
58
|
+
if a.is_a? String and b.is_a? String
|
59
|
+
a === b
|
60
|
+
elsif a.class != b.class
|
61
|
+
false
|
62
|
+
elsif a.is_a? Cell
|
63
|
+
_equal_QUMARK( a.car, b.car ) and _equal_QUMARK( a.cdr, b.cdr )
|
64
|
+
elsif _null_QUMARK( a ) and _null_QUMARK( b )
|
65
|
+
true
|
66
|
+
elsif a.is_a? Proc
|
67
|
+
a == b
|
68
|
+
else
|
69
|
+
(a === b)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def __PLMARK_ARGS0( ) 0 end
|
74
|
+
def __PLMARK_ARGS1( a ) a end
|
75
|
+
def __PLMARK_ARGS2( a, b ) a + b end
|
76
|
+
def __PLMARK_ARGS3( a, b, c ) a + b + c end
|
77
|
+
|
78
|
+
def __PLMARK( *args )
|
79
|
+
arr = args[0].to_arr
|
80
|
+
case args[0].length
|
81
|
+
when 0
|
82
|
+
0
|
83
|
+
else
|
84
|
+
__assertFlat( arr )
|
85
|
+
arr.each { |x|
|
86
|
+
if not (_number_QUMARK(x) or _string_QUMARK(x))
|
87
|
+
##arr.each { |v| STDERR.printf( "__PLMARK: %s\n", v ) }
|
88
|
+
raise TypeError, sprintf( "Error: arg %s is [%s] type",x ,x.class )
|
89
|
+
end
|
90
|
+
}
|
91
|
+
case args[0].length
|
92
|
+
when 1
|
93
|
+
args[0].car
|
94
|
+
else
|
95
|
+
arr[1..-1].inject(arr[0]){|x,y| x+y}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def __ASMARK_ARGS0( ) 1 end
|
101
|
+
def __ASMARK_ARGS1( a ) a end
|
102
|
+
def __ASMARK_ARGS2( a, b ) a * b end
|
103
|
+
def __ASMARK_ARGS3( a, b, c ) a * b * c end
|
104
|
+
|
105
|
+
def __ASMARK( *args )
|
106
|
+
arr = args[0].to_arr
|
107
|
+
case args[0].length
|
108
|
+
when 0
|
109
|
+
1
|
110
|
+
else
|
111
|
+
__assertFlat( arr )
|
112
|
+
arr.each { |x|
|
113
|
+
if not _number_QUMARK(x)
|
114
|
+
raise TypeError
|
115
|
+
end
|
116
|
+
}
|
117
|
+
case args[0].length
|
118
|
+
when 1
|
119
|
+
args[0].car
|
120
|
+
else
|
121
|
+
arr[1..-1].inject(arr[0]){|x,y| x*y}
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def __MIMARK_ARGS0( ) 0 end
|
127
|
+
def __MIMARK_ARGS1( a ) -a end
|
128
|
+
def __MIMARK_ARGS2( a, b ) a - b end
|
129
|
+
def __MIMARK_ARGS3( a, b, c ) a - b - c end
|
130
|
+
|
131
|
+
def __MIMARK( first, *rest )
|
132
|
+
raise TypeError if not _number_QUMARK(first)
|
133
|
+
rest = rest[0].to_arr
|
134
|
+
__assertFlat( rest )
|
135
|
+
if 0 == rest.length
|
136
|
+
- first
|
137
|
+
else
|
138
|
+
rest.inject(first){|x,y| x-y}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def __SLMARK( first, *rest )
|
143
|
+
raise TypeError if not _number_QUMARK(first)
|
144
|
+
rest = rest[0].to_arr
|
145
|
+
__assertFlat( rest )
|
146
|
+
if 0 == rest.length
|
147
|
+
1 / first
|
148
|
+
else
|
149
|
+
rest.inject(first){|x,y| x/y}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def __PAMARK( first, *rest )
|
154
|
+
_modulo( first, *rest )
|
155
|
+
end
|
156
|
+
|
157
|
+
def _quotient( first, second )
|
158
|
+
raise TypeError if not _number_QUMARK(first)
|
159
|
+
raise TypeError if not _number_QUMARK(second)
|
160
|
+
(first / second.to_f).to_i
|
161
|
+
end
|
162
|
+
|
163
|
+
def _remainder( first, second )
|
164
|
+
raise TypeError if not _number_QUMARK(first)
|
165
|
+
raise TypeError if not _number_QUMARK(second)
|
166
|
+
first - _quotient( first, second ) * second
|
167
|
+
end
|
168
|
+
|
169
|
+
def _modulo( first, *rest )
|
170
|
+
raise TypeError if not _number_QUMARK(first)
|
171
|
+
rest = rest[0].to_arr
|
172
|
+
__assertFlat( rest )
|
173
|
+
if 0 == rest.length
|
174
|
+
1 % first
|
175
|
+
else
|
176
|
+
rest.inject(first){|x,y| x%y}
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def _not( arg )
|
181
|
+
arg = false if Nil == arg.class
|
182
|
+
not arg
|
183
|
+
end
|
184
|
+
|
185
|
+
def _cons( first, second )
|
186
|
+
if first.is_a? Nil
|
187
|
+
first = Cell.new
|
188
|
+
end
|
189
|
+
if second.is_a? Cell
|
190
|
+
if second.isNull
|
191
|
+
Cell.new( first )
|
192
|
+
else
|
193
|
+
Cell.new( first, second )
|
194
|
+
end
|
195
|
+
else
|
196
|
+
Cell.new( first, second )
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def _set_MIMARKcar_EXMARK( cell, arg )
|
201
|
+
if cell.is_a? Cell
|
202
|
+
cell.car = arg
|
203
|
+
cell
|
204
|
+
else
|
205
|
+
raise TypeError
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def _set_MIMARKcdr_EXMARK( cell, arg )
|
210
|
+
arg = if arg.is_a? Cell
|
211
|
+
_null_QUMARK( arg ) ? Nil.new : arg
|
212
|
+
else
|
213
|
+
arg
|
214
|
+
end
|
215
|
+
if cell.is_a? Cell
|
216
|
+
cell.cdr = arg
|
217
|
+
cell
|
218
|
+
else
|
219
|
+
raise TypeError
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def _exit( *args )
|
224
|
+
if 0 == args[0].length
|
225
|
+
Kernel::exit(0)
|
226
|
+
else
|
227
|
+
arr = args[0].to_arr
|
228
|
+
Kernel::exit(arr[0])
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def _print( format, *rest )
|
233
|
+
print( format, *(rest[0].to_arr) )
|
234
|
+
end
|
235
|
+
|
236
|
+
def _printf( format, *rest )
|
237
|
+
Kernel::printf( format, *(rest[0].to_arr) )
|
238
|
+
end
|
239
|
+
|
240
|
+
def _sprintf( format, *rest )
|
241
|
+
Kernel::sprintf( format, *(rest[0].to_arr) )
|
242
|
+
end
|
243
|
+
|
244
|
+
def _null_QUMARK( arg )
|
245
|
+
if Nil == arg.class
|
246
|
+
true
|
247
|
+
elsif Cell == arg.class
|
248
|
+
arg.isNull
|
249
|
+
else
|
250
|
+
false
|
251
|
+
end
|
252
|
+
end
|
253
|
+
def _length( arg )
|
254
|
+
if _null_QUMARK( arg )
|
255
|
+
0
|
256
|
+
elsif arg.is_a? Cell
|
257
|
+
arg.length
|
258
|
+
else
|
259
|
+
raise TypeError
|
260
|
+
end
|
261
|
+
end
|
262
|
+
def _list( *args) args[0] end
|
263
|
+
def _reverse( arg ) arg.to_arr.reverse.to_list end
|
264
|
+
def _uniq( arg ) arg.to_arr.uniq.to_list end
|
265
|
+
def _range( num, *args )
|
266
|
+
arr = args[0].to_arr
|
267
|
+
if 0 < arr.length
|
268
|
+
if arr[0].is_a? Fixnum
|
269
|
+
(0..num-1).to_a.map { |x| x + arr[0] }.to_list
|
270
|
+
else
|
271
|
+
raise TypeError, "Error range's start expects number."
|
272
|
+
end
|
273
|
+
else
|
274
|
+
(0..num-1).to_a.to_list
|
275
|
+
end
|
276
|
+
end
|
277
|
+
def __EQMARK( a,b ) a == b end
|
278
|
+
def __GTMARK( a,b ) a > b end
|
279
|
+
def __GTMARK_EQMARK( a,b ) a >= b end
|
280
|
+
def __LTMARK( a,b ) a < b end
|
281
|
+
def __LTMARK_EQMARK( a,b ) a <= b end
|
282
|
+
def _eq_QUMARK( a,b ) a == b end
|
283
|
+
def _gt_QUMARK( a,b ) a > b end
|
284
|
+
def _ge_QUMARK( a,b ) a >= b end
|
285
|
+
def _lt_QUMARK( a,b ) a < b end
|
286
|
+
def _le_QUMARK( a,b ) a <= b end
|
287
|
+
def _eqv_QUMARK( a,b ) a === b end
|
288
|
+
def _car( cell ) cell.car end
|
289
|
+
def _cdr( cell )
|
290
|
+
if cell.cdr.is_a? Nil
|
291
|
+
Cell.new
|
292
|
+
else
|
293
|
+
cell.cdr
|
294
|
+
end
|
295
|
+
end
|
296
|
+
def _write( arg ) printer = Printer.new ; print printer._write( arg ) ; arg end
|
297
|
+
def _write_MIMARKto_MIMARKstring( arg ) printer = Printer.new ; printer._write( arg ) end
|
298
|
+
alias write_to_string _write_MIMARKto_MIMARKstring
|
299
|
+
def _display( arg ) printer = Printer.new ; print printer._print( arg ) ; arg end
|
300
|
+
def _print( arg ) self._display( arg ) ; self._newline() ; arg end
|
301
|
+
def _newline( ) print "\n" end
|
302
|
+
def _procedure_QUMARK( arg ) ((Proc == arg.class) or (Method == arg.class)) end
|
303
|
+
def _macro_QUMARK( arg ) (LispMacro == arg.class) end
|
304
|
+
def _symbol_QUMARK( arg ) (arg.is_a? Symbol or arg.is_a? SyntacticClosure) end
|
305
|
+
def _keyword_QUMARK( arg ) (arg.is_a? LispKeyword) end
|
306
|
+
def _syntax_QUMARK( arg ) (arg.is_a? LispSyntax) end
|
307
|
+
def _core_MIMARKsyntax_QUMARK( arg )
|
308
|
+
if arg.is_a? LispCoreSyntax
|
309
|
+
arg.syntaxName
|
310
|
+
else
|
311
|
+
nil
|
312
|
+
end
|
313
|
+
end
|
314
|
+
def _pair_QUMARK( arg )
|
315
|
+
if _null_QUMARK( arg )
|
316
|
+
false
|
317
|
+
else
|
318
|
+
(Cell == arg.class)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
def __PAMARKlist_QUMARK( arg )
|
322
|
+
if _pair_QUMARK( arg )
|
323
|
+
(not arg.lastAtom) and (1 <= arg.to_arr.size) # it means proper list?
|
324
|
+
else
|
325
|
+
_null_QUMARK( arg )
|
326
|
+
end
|
327
|
+
end
|
328
|
+
def _integer_QUMARK( arg ) arg.is_a? Integer end
|
329
|
+
def _number_QUMARK( arg ) arg.is_a? Numeric end
|
330
|
+
def _string_QUMARK( arg ) arg.is_a? String end
|
331
|
+
def _macroexpand_MIMARK1( arg )
|
332
|
+
if _pair_QUMARK( arg )
|
333
|
+
macroexpandInit( 1 )
|
334
|
+
macroexpandEngine( arg, [], [] )
|
335
|
+
else
|
336
|
+
arg
|
337
|
+
end
|
338
|
+
end
|
339
|
+
def _to_s( arg ) _to_MIMARKs( arg ) end
|
340
|
+
def _to_MIMARKs( arg ) arg.to_s end
|
341
|
+
def _to_i( arg ) _to_MIMARKi( arg ) end
|
342
|
+
def _to_MIMARKi( arg ) arg.to_i end
|
343
|
+
def _nil_QUMARK( arg ) arg.nil? end
|
344
|
+
def _to_list( arg ) _to_MIMARKlist( arg ) end
|
345
|
+
def _to_MIMARKlist( arg )
|
346
|
+
case arg
|
347
|
+
when Array
|
348
|
+
arg.to_list
|
349
|
+
when Cell
|
350
|
+
arg
|
351
|
+
else
|
352
|
+
raise TypeError
|
353
|
+
end
|
354
|
+
end
|
355
|
+
def _to_arr( arg ) _to_MIMARKarr( arg ) end
|
356
|
+
def _to_MIMARKarr( arg )
|
357
|
+
case arg
|
358
|
+
when Cell
|
359
|
+
arg.to_arr
|
360
|
+
when Array
|
361
|
+
arg
|
362
|
+
else
|
363
|
+
raise TypeError
|
364
|
+
end
|
365
|
+
end
|
366
|
+
def _intern( arg ) arg.intern end
|
367
|
+
def _string_MIMARK_GTMARKsymbol( arg ) arg.intern end
|
368
|
+
def _symbol_MIMARK_GTMARKstring( arg ) arg.to_s end
|
369
|
+
def _string_MIMARKjoin( lst, *args )
|
370
|
+
arr = args[0].to_arr
|
371
|
+
if 0 < arr.length
|
372
|
+
if not arr[0].is_a? String
|
373
|
+
raise TypeError, "Error: string-join's expects delimitter as String."
|
374
|
+
else
|
375
|
+
lst.to_a.map{ |x| x.car }.join( arr[0] )
|
376
|
+
end
|
377
|
+
else
|
378
|
+
lst.to_a.map{ |x| x.car }.join
|
379
|
+
end
|
380
|
+
end
|
381
|
+
def _require( arg )
|
382
|
+
require( arg )
|
383
|
+
false
|
384
|
+
end
|
385
|
+
def _read_MIMARKfrom_MIMARKstring( str )
|
386
|
+
if not str.is_a? String
|
387
|
+
raise TypeError, "Error: read-from-string expects sexp as String."
|
388
|
+
else
|
389
|
+
sio = StringIO.open( str )
|
390
|
+
reader = Reader.new( sio, "(string)", false )
|
391
|
+
s = reader._read
|
392
|
+
s[0]
|
393
|
+
end
|
394
|
+
end
|
395
|
+
def _read( *args )
|
396
|
+
lst = args[0].to_arr
|
397
|
+
io = if 0 == lst.length
|
398
|
+
STDIN
|
399
|
+
else
|
400
|
+
lst[0]
|
401
|
+
end
|
402
|
+
reader = Reader.new( io, "STDIN", false )
|
403
|
+
ret = nil
|
404
|
+
begin
|
405
|
+
s = reader._read
|
406
|
+
ret = s[0]
|
407
|
+
if s[1] # EOF?
|
408
|
+
ret = Cell.new
|
409
|
+
break
|
410
|
+
end
|
411
|
+
end until s[2]
|
412
|
+
ret
|
413
|
+
end
|
414
|
+
|
415
|
+
def _apply1( first, arg )
|
416
|
+
trampCall( callProcedure( nil, "(apply1 genereate func)", first, arg.to_arr ))
|
417
|
+
end
|
418
|
+
|
419
|
+
def _global_MIMARKvariables
|
420
|
+
self.instance_variables.select { |x|
|
421
|
+
x.match( /^[@]_[_a-zA-Z]/ )
|
422
|
+
}.map{ |name|
|
423
|
+
self.toLispSymbol( name[1..-1] ).intern
|
424
|
+
}.to_list
|
425
|
+
end
|
426
|
+
|
427
|
+
def _make_MIMARKvalues( lst )
|
428
|
+
if _pair_QUMARK( lst )
|
429
|
+
LispValues.new( lst.to_arr )
|
430
|
+
elsif _null_QUMARK( lst )
|
431
|
+
LispValues.new( [] )
|
432
|
+
else
|
433
|
+
raise ArgumentError, "Error: make-values expects a list argument."
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
def _values_QUMARK( arg ) arg.is_a? LispValues end
|
438
|
+
|
439
|
+
def _values_MIMARKvalues( arg )
|
440
|
+
if _values_QUMARK( arg )
|
441
|
+
arg.values.to_list
|
442
|
+
else
|
443
|
+
raise TypeError, "Error: values-values expects only LispValues object."
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
def _make_MIMARKkeyword( arg )
|
448
|
+
if _symbol_QUMARK( arg ) or _string_QUMARK( arg )
|
449
|
+
LispKeyword.new( arg.to_s )
|
450
|
+
else
|
451
|
+
raise TypeError, "Error: make-keyword expects symbol or string object."
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
def _keyword_MIMARK_GTMARKstring( arg )
|
456
|
+
if _keyword_QUMARK( arg )
|
457
|
+
arg.key.to_s
|
458
|
+
else
|
459
|
+
raise TypeError, "Error: keyword->string expects only keyword object."
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
def _hash_MIMARKtable_MIMARKget( h, key, *args )
|
464
|
+
if h.has_key?(key)
|
465
|
+
h[key]
|
466
|
+
else
|
467
|
+
arr = args[0].to_arr
|
468
|
+
if 0 < arr.length
|
469
|
+
arr[0]
|
470
|
+
else
|
471
|
+
raise RuntimeError, sprintf( "Error: in hash-table-get() key [%s] was not exist.\n", key )
|
472
|
+
end
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
def _hash_MIMARKtable_MIMARKput_EXMARK( h, key, value )
|
477
|
+
h[key] = value
|
478
|
+
end
|
479
|
+
|
480
|
+
def _hash_MIMARKtable_MIMARKexist_QUMARK( h, key )
|
481
|
+
# don't use h.has_key(k), because has_key method undefined on some database bindings. (e.g. KyotoCabinet)
|
482
|
+
h[key] ? true : false
|
483
|
+
end
|
484
|
+
|
485
|
+
# backtrace expects this format "filename:lineno: place message ". e.g. "init.nnd:10: in aaa macro.".
|
486
|
+
def __PAMARKraise( exception, message, backtrace )
|
487
|
+
raise exception, message, [ backtrace ]
|
488
|
+
end
|
489
|
+
|
490
|
+
def __ASMARKLINE_ASMARK()
|
491
|
+
@lastLineno
|
492
|
+
end
|
493
|
+
|
494
|
+
def __ASMARKFILE_ASMARK()
|
495
|
+
@lastSourcefile
|
496
|
+
end
|
497
|
+
|
498
|
+
def _vector_MIMARKset_EXMARK( v, index, value )
|
499
|
+
if !(v.is_a? Array)
|
500
|
+
raise TypeError, "Error: vector-set! requires Array as argument v(Lisp's vector).\n"
|
501
|
+
end
|
502
|
+
if (index < 0) or (v.size <= index)
|
503
|
+
raise ArgumentError, "Error: vector-set! requires index between 0 and (size-1) number.\n"
|
504
|
+
end
|
505
|
+
v[index] = value
|
506
|
+
end
|
507
|
+
|
508
|
+
end
|
509
|
+
|
510
|
+
end
|
data/lib/ruby/core.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
#
|
4
|
+
# core.rb - "core for nendo"
|
5
|
+
#
|
6
|
+
# Copyright (c) 2009-2010 Kiyoka Nishiyama <kiyoka@sumibi.org>
|
7
|
+
#
|
8
|
+
# Redistribution and use in source and binary forms, with or without
|
9
|
+
# modification, are permitted provided that the following conditions
|
10
|
+
# are met:
|
11
|
+
#
|
12
|
+
# 1. Redistributions of source code must retain the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer.
|
14
|
+
#
|
15
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
16
|
+
# notice, this list of conditions and the following disclaimer in the
|
17
|
+
# documentation and/or other materials provided with the distribution.
|
18
|
+
#
|
19
|
+
# 3. Neither the name of the authors nor the names of its contributors
|
20
|
+
# may be used to endorse or promote products derived from this
|
21
|
+
# software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
24
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
25
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
26
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
27
|
+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
28
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
29
|
+
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
30
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
31
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
32
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
33
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
#
|
35
|
+
module Nendo
|
36
|
+
|
37
|
+
class Core
|
38
|
+
def initialize( debug_evaluator = false, debug_printer = false )
|
39
|
+
@debug_evaluator = debug_evaluator
|
40
|
+
@evaluator = Evaluator.new( self, debug_evaluator )
|
41
|
+
@debug_printer = debug_printer
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.version
|
45
|
+
"0.6.0" ##NENDO-VERSION
|
46
|
+
end
|
47
|
+
|
48
|
+
attr_reader :evaluator
|
49
|
+
|
50
|
+
def loadInitFile( use_compiled = true )
|
51
|
+
done = false
|
52
|
+
if use_compiled
|
53
|
+
compiled_file = File.dirname(__FILE__) + "/../init.nndc"
|
54
|
+
if File.exist?( compiled_file )
|
55
|
+
@evaluator.__PAMARKload_MIMARKcompiled_MIMARKcode( compiled_file )
|
56
|
+
done = true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
unless done
|
60
|
+
@evaluator.__PAMARKload( File.dirname(__FILE__) + "/../init.nnd" )
|
61
|
+
@evaluator.__PAMARKload( File.dirname(__FILE__) + "/../init.nnd" ) # for %tailcall compile for init.nnd
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def load( path )
|
66
|
+
@evaluator.__PAMARKload( path )
|
67
|
+
end
|
68
|
+
|
69
|
+
def load_compiled_code( path )
|
70
|
+
@evaluator.__PAMARKload_MIMARKcompiled_MIMARKcode( path )
|
71
|
+
end
|
72
|
+
|
73
|
+
def load_compiled_code_from_string( rubyExp )
|
74
|
+
@evaluator._load_MIMARKcompiled_MIMARKcode_MIMARKfrom_MIMARKstring( rubyExp )
|
75
|
+
end
|
76
|
+
|
77
|
+
def setArgv( argv )
|
78
|
+
@evaluator.setArgv( argv )
|
79
|
+
end
|
80
|
+
|
81
|
+
def setOptimizeLevel( level )
|
82
|
+
@evaluator.setOptimizeLevel( level )
|
83
|
+
end
|
84
|
+
|
85
|
+
def setDisplayErrors( flag )
|
86
|
+
@evaluator.setDisplayErrors( flag )
|
87
|
+
end
|
88
|
+
|
89
|
+
def clean_compiled_code
|
90
|
+
@evaluator._clean_MIMARKcompiled_MIMARKcode()
|
91
|
+
end
|
92
|
+
|
93
|
+
def prompt
|
94
|
+
STDERR.print "nendo> "
|
95
|
+
end
|
96
|
+
|
97
|
+
def repl
|
98
|
+
printer = Printer.new( @debug_printer )
|
99
|
+
reader = Reader.new( STDIN, "(stdin)", false )
|
100
|
+
self.prompt
|
101
|
+
while true
|
102
|
+
begin
|
103
|
+
lineno = reader.lineno
|
104
|
+
s = reader._read
|
105
|
+
if s[1] # EOF?
|
106
|
+
break
|
107
|
+
elsif not s[0].is_a? Nil
|
108
|
+
printf( "\n readExp=<<< %s >>>\n", printer._write(s[0]) ) if @debug_evaluator
|
109
|
+
STDERR.print printer._write( @evaluator.lispEval( s[0], reader.sourcefile, lineno )) + "\n"
|
110
|
+
self.prompt
|
111
|
+
end
|
112
|
+
rescue => e
|
113
|
+
print e.message + "\n"
|
114
|
+
e.backtrace.each { |x| printf( "\tfrom %s\n", x ) }
|
115
|
+
print "\n"
|
116
|
+
self.prompt
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def evalStr( str )
|
122
|
+
printer = Printer.new( @debug_printer )
|
123
|
+
sio = StringIO.open( str )
|
124
|
+
reader = Reader.new( sio, "(string)", false )
|
125
|
+
result = nil
|
126
|
+
while true
|
127
|
+
lineno = reader.lineno
|
128
|
+
s = reader._read
|
129
|
+
if s[1] # EOF?
|
130
|
+
break
|
131
|
+
elsif not s[0].is_a? Nil
|
132
|
+
printf( "\n readExp=<<< %s >>>\n", printer._write(s[0]) ) if @debug_evaluator
|
133
|
+
result = printer._write( @evaluator.lispEval( s[0], reader.sourcefile, lineno ))
|
134
|
+
end
|
135
|
+
end
|
136
|
+
result
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|