nendo 0.3.3 → 0.3.4

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 CHANGED
@@ -153,6 +153,17 @@ module Nendo
153
153
  attr_reader :values
154
154
  end
155
155
 
156
+ class LispRegexp
157
+ def initialize( str )
158
+ @exp = str[ 1 ... str.size ]
159
+ @ignoreCase = (str[0] == 'i')
160
+ end
161
+ def escape
162
+ @exp.gsub( /\\/, "\\\\\\\\" )
163
+ end
164
+ attr_reader :ignoreCase
165
+ end
166
+
156
167
  class LispKeyword
157
168
  def initialize( str )
158
169
  @key = str.intern
@@ -176,6 +187,49 @@ module Nendo
176
187
 
177
188
  attr_reader :key
178
189
  end
190
+
191
+ class SourceInfo
192
+ def initialize
193
+ @varname = nil
194
+ @sourcefile = nil
195
+ @lineno = nil
196
+ @source_sexp = Cell.new
197
+ @expanded_sexp = Cell.new
198
+ @compiled_str = nil
199
+ end
200
+
201
+ def deepCopy( sexp )
202
+ Marshal.load(Marshal.dump( sexp ))
203
+ end
204
+
205
+ def setVarname( varname )
206
+ @varname = varname
207
+ end
208
+
209
+ def setSource( sourcefile, lineno, source_sexp )
210
+ @sourcefile = sourcefile
211
+ @lineno = lineno
212
+ @source_sexp = self.deepCopy( source_sexp )
213
+ end
214
+
215
+ def setExpanded( expanded_sexp )
216
+ @expanded_sexp = self.deepCopy( expanded_sexp )
217
+ end
218
+
219
+ def setCompiled( compiled_str )
220
+ @compiled_str = compiled_str
221
+ end
222
+
223
+ def debugPrint
224
+ printf( "=== sourceInfo === \n" )
225
+ printf( " varname = %s\n", @varname )
226
+ printf( " sourcefile = %s\n", @sourcefile )
227
+ printf( " lineno = %s\n", @lineno)
228
+ printf( " compiled_str = %s\n", @compiled_str )
229
+ end
230
+
231
+ attr_reader :varname, :sourcefile, :lineno, :source_sexp, :expanded_sexp, :compiled_str
232
+ end
179
233
 
180
234
  class DelayedCallPacket
181
235
  def initialize( _origname, _pred, _args )
@@ -261,6 +315,7 @@ module Nendo
261
315
  T_LINEFEED = :t_linefeed
262
316
  T_COMMENT = :t_comment
263
317
  T_DEBUG_PRINT = :t_debug_print
318
+ T_REGEXP = :t_regexp
264
319
 
265
320
  # inport is IO class
266
321
  def initialize( inport, sourcefile, debug = false )
@@ -362,7 +417,33 @@ module Nendo
362
417
  end
363
418
  ret
364
419
  end
365
-
420
+
421
+ def readRegexp()
422
+ ret = ""
423
+ while true
424
+ ch = @chReader.getc
425
+ #printf( " readRegexp1: [%s]\n", ch )
426
+ if !ch # eof?
427
+ break
428
+ end
429
+ if ch.chr == "\\" #escape
430
+ ch2 = @chReader.getc
431
+ #printf( " readRegexp2: [%s]\n", ch2 )
432
+ if ch2.chr == '/'
433
+ ret += ch2.chr # drop escape "\\" char
434
+ else
435
+ ret += ch.chr
436
+ ret += ch2.chr
437
+ end
438
+ elsif ch.chr == '/'
439
+ break
440
+ else
441
+ ret += ch.chr
442
+ end
443
+ end
444
+ ret
445
+ end
446
+
366
447
  def tokenWithComment
367
448
  skipspace
368
449
  ch = @chReader.getc
@@ -401,7 +482,7 @@ module Nendo
401
482
  str = ""
402
483
  T_COMMENT
403
484
  when /[#]/
404
- nextch = peekchar( /[?!tfbodx(]/ )
485
+ nextch = peekchar( /[?!tfbodx(\/]/ )
405
486
  case nextch
406
487
  when "?"
407
488
  if peekchar( /[=]/ )
@@ -454,6 +535,11 @@ module Nendo
454
535
  end
455
536
  str = Integer( str ).to_s
456
537
  T_NUM
538
+ when "/" # T_REGEXP's str takes "iXXXXX"(igreno case) or " XXXXXX"(case sensitive) value.
539
+ readwhile( /[\/]/ ) # consume
540
+ str = readRegexp()
541
+ str = ((0 < readwhile( /[i]/ ).size) ? "i" : " ") + str
542
+ T_REGEXP
457
543
  else
458
544
  str += readwhile( /[^ \t\r\n]/ )
459
545
  raise NameError, sprintf( "Error: unknown #xxxx syntax for Nendo %s", str )
@@ -526,6 +612,8 @@ module Nendo
526
612
  end
527
613
  when T_STRING
528
614
  cur.str
615
+ when T_REGEXP
616
+ LispRegexp.new( cur.str )
529
617
  when T_QUOTE
530
618
  :quote
531
619
  when T_QUASIQUOTE
@@ -557,7 +645,12 @@ module Nendo
557
645
  when T_LINEFEED
558
646
  token # skipEnter
559
647
  when T_EOF
560
- raise RuntimeError, "Error: unbalanced vector's paren(4)"
648
+ begin
649
+ raise RuntimeError, "Error: unbalanced vector's paren(4)"
650
+ rescue => e
651
+ e.set_backtrace( [sprintf( "%s:%d", curtoken.sourcefile, curtoken.lineno )] + e.backtrace )
652
+ raise e
653
+ end
561
654
  when T_LPAREN, T_LVECTOR
562
655
  arr << sexp()
563
656
  when T_RPAREN
@@ -586,7 +679,12 @@ module Nendo
586
679
  when T_LINEFEED
587
680
  token # skipEnter
588
681
  when T_EOF
589
- raise RuntimeError, "Error: unbalanced paren(1)"
682
+ begin
683
+ raise RuntimeError, "Error: unbalanced paren(1)"
684
+ rescue => e
685
+ e.set_backtrace( [sprintf( "%s:%d", curtoken.sourcefile, curtoken.lineno )] + e.backtrace )
686
+ raise e
687
+ end
590
688
  when T_LPAREN, T_LVECTOR
591
689
  cells << Cell.new( sexp() )
592
690
  when T_RPAREN
@@ -644,7 +742,12 @@ module Nendo
644
742
  token
645
743
  sexp()
646
744
  when T_EOF
647
- raise RuntimeError, "Error: unbalanced paren(2)"
745
+ begin
746
+ raise RuntimeError, "Error: unbalanced paren(2)"
747
+ rescue => e
748
+ e.set_backtrace( [sprintf( "%s:%d", curtoken.sourcefile, curtoken.lineno )] + e.backtrace )
749
+ raise e
750
+ end
648
751
  when T_LPAREN
649
752
  skipEnter
650
753
  token # consume '('
@@ -653,7 +756,13 @@ module Nendo
653
756
  token # consume ')'
654
757
  ret
655
758
  when T_RPAREN
656
- raise RuntimeError, "Error: unbalanced paren(3)"
759
+ token # consume ')'
760
+ begin
761
+ raise RuntimeError, "Error: unbalanced vector's paren(3)"
762
+ rescue => e
763
+ e.set_backtrace( [sprintf( "%s:%d", curtoken.sourcefile, curtoken.lineno )] + e.backtrace )
764
+ raise e
765
+ end
657
766
  when T_LVECTOR
658
767
  skipEnter
659
768
  token # consume '#('
@@ -901,7 +1010,6 @@ module Nendo
901
1010
  end
902
1011
  end
903
1012
  def _list( *args) args[0] end
904
- def _sort( arg ) arg.to_arr.sort.to_list end
905
1013
  def _reverse( arg ) arg.to_arr.reverse.to_list end
906
1014
  def _uniq( arg ) arg.to_arr.uniq.to_list end
907
1015
  def _range( num, *args )
@@ -946,6 +1054,13 @@ module Nendo
946
1054
  (Cell == arg.class)
947
1055
  end
948
1056
  end
1057
+ def __PAMARKlist_QUMARK( arg )
1058
+ if _pair_QUMARK( arg )
1059
+ (not arg.lastAtom) and (1 <= arg.to_arr.size) # it means proper list?
1060
+ else
1061
+ _null_QUMARK( arg )
1062
+ end
1063
+ end
949
1064
  def _integer_QUMARK( arg ) arg.is_a? Integer end
950
1065
  def _number_QUMARK( arg ) arg.is_a? Numeric end
951
1066
  def _string_QUMARK( arg ) String == arg.class end
@@ -1000,7 +1115,7 @@ module Nendo
1000
1115
  end
1001
1116
  end
1002
1117
  def _require( arg )
1003
- Kernel::require( arg )
1118
+ require( arg )
1004
1119
  false
1005
1120
  end
1006
1121
  def _read( *args )
@@ -1076,11 +1191,9 @@ module Nendo
1076
1191
  end
1077
1192
 
1078
1193
  def _hash_MIMARKtable_MIMARKget( h, key, *args )
1079
- if !((key.is_a? String) or ( key.is_a? Symbol))
1080
- raise TypeError, "Error: argument key requires String or Symbol.\n"
1081
- end
1082
- if h.has_key?( key )
1083
- h[key]
1194
+ val = h[key]
1195
+ if val
1196
+ val
1084
1197
  else
1085
1198
  arr = args[0].to_arr
1086
1199
  if 0 < arr.length
@@ -1092,11 +1205,13 @@ module Nendo
1092
1205
  end
1093
1206
 
1094
1207
  def _hash_MIMARKtable_MIMARKput_EXMARK( h, key, value )
1095
- if !((key.is_a? String) or ( key.is_a? Symbol))
1096
- raise TypeError, "Error: argument key requires String or Symbol.\n"
1097
- end
1098
1208
  h[key] = value
1099
1209
  end
1210
+
1211
+ def _hash_MIMARKtable_MIMARKexist_QUMARK( h, key )
1212
+ # don't use h.has_key(k), because has_key method undefined on some database bindings. (e.g. KyotoCabinet)
1213
+ h[key] ? true : false
1214
+ end
1100
1215
 
1101
1216
  # backtrace expects this format "filename:lineno: place message ". e.g. "init.nnd:10: in aaa macro.".
1102
1217
  def _raise( exception, message, backtrace )
@@ -1120,6 +1235,7 @@ module Nendo
1120
1235
  end
1121
1236
  v[index] = value
1122
1237
  end
1238
+
1123
1239
  end
1124
1240
 
1125
1241
 
@@ -1130,10 +1246,12 @@ module Nendo
1130
1246
  EXEC_TYPE_ANONYMOUS = 2
1131
1247
  EXEC_TYPE_TAILCALL = 3
1132
1248
 
1133
- def initialize( debug = false )
1249
+ def initialize( core, debug = false )
1250
+ @core = core
1134
1251
  @indent = " "
1135
1252
  @binding = binding
1136
1253
  @debug = debug
1254
+ @trace_debug = false
1137
1255
  @char_table_lisp_to_ruby = {
1138
1256
  # list (! $ % & * + - . / : < = > ? @ ^ _ ~)
1139
1257
  '!' => '_EXMARK',
@@ -1165,7 +1283,7 @@ module Nendo
1165
1283
  x.to_s.match( /^_/ )
1166
1284
  }.map { |name|
1167
1285
  [
1168
- defMethodStr( name ),
1286
+ defMethodStr( name, false ),
1169
1287
  sprintf( "@%s = self.method( :%s ).to_proc", name, name ),
1170
1288
  sprintf( "@global_lisp_binding['%s'] = self.method( :%s_METHOD ).to_proc", name, name ),
1171
1289
  ].join( " ; " )
@@ -1175,13 +1293,17 @@ module Nendo
1175
1293
  # reset gensym counter
1176
1294
  @gensym_counter = 0
1177
1295
 
1296
+ # call depth counter
1297
+ @call_depth = 0
1298
+
1178
1299
  # init optimize level
1179
1300
  @optimize_level = 1
1180
1301
 
1181
1302
  # compiled ruby code
1182
1303
  # { 'filename1' => [ 'code1' 'code2' ... ],
1183
1304
  # 'filename2' => [ 'code1' 'code2' ... ], ... }
1184
- @compiled_code = Hash.new
1305
+ @compiled_code = Hash.new
1306
+ @source_info_hash = Hash.new
1185
1307
 
1186
1308
  global_lisp_define( toRubySymbol( "%compile-phase-functions" ), Cell.new())
1187
1309
  end
@@ -1204,10 +1326,28 @@ module Nendo
1204
1326
  @optimize_level
1205
1327
  end
1206
1328
 
1207
- def defMethodStr( name )
1208
- sprintf( "def self.%s_METHOD( origname, pred, args ) callProcedure( origname, pred, args ) end", name )
1329
+ def lispMethodEntry( name, _log )
1330
+ @call_depth += 1
1331
+ if @trace_debug and _log
1332
+ puts " " * @call_depth + "ENTRY: " + name
1333
+ end
1334
+ end
1335
+ def lispMethodExit( name, _log )
1336
+ if @trace_debug and _log
1337
+ puts " " * @call_depth + "exit: " + name
1338
+ end
1339
+ @call_depth -= 1
1209
1340
  end
1210
1341
 
1342
+ def defMethodStr( name, _log )
1343
+ [ "def self." + name.to_s + "_METHOD( origname, pred, args ) ",
1344
+ " lispMethodEntry( origname, " + _log.to_s + " ) ; ",
1345
+ " ret = callProcedure( origname, pred, args ) ;",
1346
+ " lispMethodExit( origname, " + _log.to_s + " ) ; ",
1347
+ " return ret ",
1348
+ "end " ].join
1349
+ end
1350
+
1211
1351
  def _gensym( )
1212
1352
  @gensym_counter += 1
1213
1353
  filename = if @lastSourcefile.is_a? String
@@ -1321,14 +1461,14 @@ module Nendo
1321
1461
  end
1322
1462
 
1323
1463
  def method_missing( name, *args )
1324
- sym = toRubySymbol( name );
1464
+ sym = toRubySymbol( name )
1325
1465
  if @global_lisp_binding[name].is_a? Proc
1326
1466
  @global_lisp_binding[name].call( args[0], args[1], args[2] )
1327
1467
  else
1328
1468
  callProcedure( args[0], args[1], args[2] )
1329
1469
  end
1330
1470
  end
1331
-
1471
+
1332
1472
  def delayCall( origname, pred, args )
1333
1473
  case @optimize_level
1334
1474
  when 0 # no optimize
@@ -1357,17 +1497,20 @@ module Nendo
1357
1497
  }
1358
1498
  end
1359
1499
 
1360
- def execFunc( funcname, args, sourcefile, lineno, locals, execType )
1500
+ def execFunc( funcname, args, sourcefile, lineno, locals, sourceInfo, execType )
1361
1501
  case funcname
1362
1502
  when :define, :set! # `define' special form
1363
1503
  ar = args.cdr.map { |x| x.car }
1364
1504
  variable_sym = toRubySymbol( args.car.to_s.sub( /^:/, "" ))
1365
1505
  global_cap = locals.flatten.include?( variable_sym.split( /[.]/ )[0] ) ? nil : "@"
1506
+ if global_cap and sourceInfo
1507
+ sourceInfo.setVarname( toLispSymbol( variable_sym ))
1508
+ end
1366
1509
  [ "begin",
1367
1510
  [
1368
1511
  if global_cap
1369
1512
  [
1370
- defMethodStr( variable_sym ),
1513
+ defMethodStr( variable_sym, true ),
1371
1514
  sprintf( "@global_lisp_binding['%s'] = self.method( :%s_METHOD )", variable_sym, variable_sym )
1372
1515
  ]
1373
1516
  else
@@ -1471,6 +1614,8 @@ module Nendo
1471
1614
  sprintf( "LispMacro.new { %s ", argStr )
1472
1615
  when :lambda
1473
1616
  sprintf( "Proc.new { %s ", argStr )
1617
+ when :"&block"
1618
+ sprintf( "&Proc.new { %s ", argStr )
1474
1619
  else
1475
1620
  raise "Error: makeClosure: unknown symbol type " + sym
1476
1621
  end
@@ -1552,13 +1697,13 @@ module Nendo
1552
1697
  "end"]
1553
1698
  end
1554
1699
 
1555
- def apply( car, cdr, sourcefile, lineno, locals, execType )
1700
+ def apply( car, cdr, sourcefile, lineno, locals, sourceInfo, execType )
1556
1701
  cdr.each { |x|
1557
1702
  if Cell == x.class
1558
- x.car = translate( x.car, locals )
1703
+ x.car = translate( x.car, locals, sourceInfo )
1559
1704
  end
1560
1705
  }
1561
- execFunc( car, cdr, sourcefile, lineno, locals, execType )
1706
+ execFunc( car, cdr, sourcefile, lineno, locals, sourceInfo, execType )
1562
1707
  end
1563
1708
 
1564
1709
  def genQuote( sexp, str = "" )
@@ -1638,7 +1783,7 @@ module Nendo
1638
1783
  # (let ((c 3))
1639
1784
  # (print (+ a b c))))
1640
1785
  # => locals must be [["_a" "_b"]["_c"]] value.
1641
- def translate( sexp, locals )
1786
+ def translate( sexp, locals, sourceInfo = nil )
1642
1787
  case sexp
1643
1788
  when Cell
1644
1789
  if :quote == sexp.car
@@ -1648,13 +1793,15 @@ module Nendo
1648
1793
  elsif sexp.isNull
1649
1794
  [ "Cell.new()" ]
1650
1795
  elsif Cell == sexp.car.class
1651
- self.apply( translate( sexp.car, locals ), sexp.cdr, sexp.car.car.sourcefile, sexp.car.car.lineno, locals, EXEC_TYPE_ANONYMOUS )
1796
+ self.apply( translate( sexp.car, locals, sourceInfo ), sexp.cdr, sexp.car.car.sourcefile, sexp.car.car.lineno, locals, sourceInfo, EXEC_TYPE_ANONYMOUS )
1652
1797
  elsif :begin == sexp.car
1653
1798
  self.makeBegin( sexp.cdr, locals )
1654
1799
  elsif :lambda == sexp.car
1655
1800
  self.makeClosure( :lambda, sexp.cdr, locals )
1656
1801
  elsif :macro == sexp.car
1657
1802
  self.makeClosure( :macro, sexp.cdr, locals )
1803
+ elsif :"&block" == sexp.car
1804
+ self.makeClosure( :"&block", sexp.cdr, locals )
1658
1805
  elsif :if == sexp.car
1659
1806
  self.makeIf( sexp.cdr, locals )
1660
1807
  elsif :let == sexp.car
@@ -1664,12 +1811,12 @@ module Nendo
1664
1811
  elsif :"%tailcall" == sexp.car
1665
1812
  if sexp.cdr.car.is_a? Cell
1666
1813
  sexp = sexp.cdr.car
1667
- self.apply( sexp.car, sexp.cdr, sexp.car.sourcefile, sexp.car.lineno, locals, EXEC_TYPE_TAILCALL )
1814
+ self.apply( sexp.car, sexp.cdr, sexp.car.sourcefile, sexp.car.lineno, locals, sourceInfo, EXEC_TYPE_TAILCALL )
1668
1815
  else
1669
1816
  raise RuntimeError, "Error: special form tailcall expects function call expression."
1670
1817
  end
1671
1818
  else
1672
- self.apply( sexp.car, sexp.cdr, sexp.car.sourcefile, sexp.car.lineno, locals, EXEC_TYPE_NORMAL )
1819
+ self.apply( sexp.car, sexp.cdr, sexp.car.sourcefile, sexp.car.lineno, locals, sourceInfo, EXEC_TYPE_NORMAL )
1673
1820
  end
1674
1821
  when Array
1675
1822
  raise RuntimeError, "Error: can't eval unquoted vector."
@@ -1683,6 +1830,12 @@ module Nendo
1683
1830
  sexp.to_s
1684
1831
  when String, LispString
1685
1832
  sprintf( "\"%s\"", LispString.escape( sexp ))
1833
+ when LispRegexp
1834
+ if sexp.ignoreCase
1835
+ sprintf( "Regexp.new( \"%s\", Regexp::IGNORECASE)", sexp.escape )
1836
+ else
1837
+ sprintf( "Regexp.new( \"%s\")", sexp.escape )
1838
+ end
1686
1839
  when LispKeyword
1687
1840
  sprintf( "LispKeyword.new( \"%s\" )", sexp.key )
1688
1841
  when Nil
@@ -1716,7 +1869,7 @@ module Nendo
1716
1869
  when Cell
1717
1870
  if :quote == sexp.car or :quasiquote == sexp.car
1718
1871
  sexp
1719
- elsif :define == sexp.car or :set! == sexp.car or :lambda == sexp.car or :macro == sexp.car
1872
+ elsif :define == sexp.car or :set! == sexp.car or :lambda == sexp.car or :macro == sexp.car or :"&block" == sexp.car
1720
1873
  sexp.cdr.car = Cell.new( :quote, Cell.new( sexp.cdr.car ))
1721
1874
  sexp.cdr.cdr = quotingPhase( sexp.cdr.cdr )
1722
1875
  sexp
@@ -1822,8 +1975,10 @@ module Nendo
1822
1975
  end
1823
1976
 
1824
1977
  def lispEval( sexp, sourcefile, lineno )
1978
+ sourceInfo = SourceInfo.new
1825
1979
  @lastSourcefile = sourcefile
1826
1980
  @lastLineno = lineno
1981
+ sourceInfo.setSource( sourcefile, lineno, sexp )
1827
1982
  sexp = macroExpandPhase( sexp )
1828
1983
  sexp = quotingPhase( sexp )
1829
1984
  if @debug
@@ -1838,13 +1993,18 @@ module Nendo
1838
1993
  printf( "\n compiled=<<< %s >>>\n", (Printer.new())._print(sexp))
1839
1994
  end
1840
1995
  end
1996
+ sourceInfo.setExpanded( sexp )
1841
1997
 
1842
- arr = [ "trampCall( ", translate( sexp, [] ), " )" ]
1998
+ arr = [ "trampCall( ", translate( sexp, [], sourceInfo ), " )" ]
1843
1999
  rubyExp = ppRubyExp( 0, arr ).flatten.join
2000
+ sourceInfo.setCompiled( rubyExp )
1844
2001
  if not @compiled_code.has_key?( sourcefile )
1845
2002
  @compiled_code[ sourcefile ] = Array.new
1846
2003
  end
1847
2004
  @compiled_code[ sourcefile ] << rubyExp
2005
+ if sourceInfo.varname
2006
+ @source_info_hash[ sourceInfo.varname ] = sourceInfo
2007
+ end
1848
2008
  printf( " rubyExp=<<<\n%s\n>>>\n", rubyExp ) if @debug
1849
2009
  eval( rubyExp, @binding, @lastSourcefile, @lastLineno )
1850
2010
  end
@@ -1903,12 +2063,60 @@ module Nendo
1903
2063
  def _disable_MIMARKidebug()
1904
2064
  @debug = false
1905
2065
  end
2066
+ def _enable_MIMARKtrace()
2067
+ @trace_debug = true
2068
+ end
2069
+ def _disable_MIMARKtrace()
2070
+ @trace_debug = false
2071
+ end
1906
2072
  def _set_MIMARKoptimize_MIMARKlevel(level)
1907
2073
  self.setOptimizeLevel( level )
1908
2074
  end
1909
2075
  def _get_MIMARKoptimize_MIMARKlevel()
1910
2076
  self.getOptimizeLevel
1911
2077
  end
2078
+
2079
+ def _get_MIMARKsource_MIMARKinfo( varname )
2080
+ info = @source_info_hash[ varname.to_s ]
2081
+ if info
2082
+ [
2083
+ Cell.new( "varname", info.varname ),
2084
+ Cell.new( "sourcefile", info.sourcefile ),
2085
+ Cell.new( "lineno", info.lineno ),
2086
+ Cell.new( "source", info.source_sexp ),
2087
+ Cell.new( "expanded", info.expanded_sexp ),
2088
+ Cell.new( "compiled_str", info.compiled_str ) ].to_list
2089
+ else
2090
+ raise NameError, sprintf( "Error: not found variable [%s]. \n", varname.to_s )
2091
+ end
2092
+ end
2093
+
2094
+ def __PAMARKexport_MIMARKto_MIMARKruby( origname, pred )
2095
+ if toRubySymbol( origname ) != ("_" + origname)
2096
+ raise ArgumentError, "Error: %export-to-ruby requires function name in ruby method naming rule."
2097
+ end
2098
+ if not _procedure_QUMARK( pred )
2099
+ raise ArgumentError, "Error: %export-to-ruby requires 'pred' as a Proc instance."
2100
+ end
2101
+ if 0 > pred.arity
2102
+ raise ArgumentError, "Error: %export-to-ruby requires only a function that have fixed length argument."
2103
+ end
2104
+ if self.methods.include?( origname.intern ) or @core.methods.include?( origname.intern )
2105
+ raise RuntimeError, "Error: %export-to-ruby: Nendo::Core." + origname + " method was already deifned."
2106
+ end
2107
+
2108
+ argsStr = (1..(pred.arity)).map { |n| "arg" + n.to_s }.join( "," )
2109
+ str = [ "def self." + origname + "(" + argsStr + ")",
2110
+ sprintf( " trampCall( callProcedure( '%s', @_%s, [ " + argsStr + " ].to_list )) ",
2111
+ origname, origname ),
2112
+ "end ;",
2113
+ "def @core." + origname + "(" + argsStr + ")",
2114
+ " @evaluator." + origname + "(" + argsStr + ") ",
2115
+ "end"
2116
+ ].join
2117
+ eval( str, @binding )
2118
+ true
2119
+ end
1912
2120
  end
1913
2121
 
1914
2122
  class Printer
@@ -1964,6 +2172,8 @@ module Nendo
1964
2172
  else
1965
2173
  sexp.to_s
1966
2174
  end
2175
+ when Regexp
2176
+ "#/" + sexp.source + "/" + (sexp.casefold? ? "i" : "")
1967
2177
  when LispKeyword
1968
2178
  ":" + sexp.key.to_s
1969
2179
  when Nil
@@ -1987,7 +2197,7 @@ module Nendo
1987
2197
  class Core
1988
2198
  def initialize( debug_evaluator = false, debug_printer = false )
1989
2199
  @debug_evaluator = debug_evaluator
1990
- @evaluator = Evaluator.new( debug_evaluator )
2200
+ @evaluator = Evaluator.new( self, debug_evaluator )
1991
2201
  @debug_printer = debug_printer
1992
2202
  end
1993
2203
 
@@ -2002,6 +2212,7 @@ module Nendo
2002
2212
  end
2003
2213
  unless done
2004
2214
  @evaluator._load( File.dirname(__FILE__) + "/init.nnd" )
2215
+ @evaluator._load( File.dirname(__FILE__) + "/init.nnd" ) # for %tailcall compile for init.nnd
2005
2216
  end
2006
2217
  end
2007
2218
 
@@ -2057,7 +2268,7 @@ module Nendo
2057
2268
  end
2058
2269
  end
2059
2270
 
2060
- def replStr( str )
2271
+ def evalStr( str )
2061
2272
  printer = Printer.new( @debug_printer )
2062
2273
  sio = StringIO.open( str )
2063
2274
  reader = Reader.new( sio, "(string)", false )
@@ -2095,7 +2306,7 @@ end
2095
2306
  class Array
2096
2307
  def to_list( lastAtom = false, value = Nendo::Nil.new )
2097
2308
  if 0 == self.length
2098
- Nendo::Nil.new
2309
+ Nendo::Cell.new()
2099
2310
  else
2100
2311
  cells = self.map { |x|
2101
2312
  Nendo::Cell.new( x )
data/lib/srfi-1.nnd CHANGED
@@ -790,12 +790,7 @@
790
790
  '())))
791
791
 
792
792
  ;; Fast path.
793
- (let recur ((lis lis1))
794
- (if (null-list? lis) lis
795
- (let ((tail (recur (cdr lis))))
796
- (cond ((f (car lis)) => (lambda (x) (cons x tail)))
797
- (else tail)))))))
798
-
793
+ (%filter-map f lis1)))
799
794
 
800
795
  ;;; Map F across lists, guaranteeing to go left-to-right.
801
796
  ;;; NOTE: Some implementations of R5RS MAP are compliant with this spec;
@@ -812,18 +807,12 @@
812
807
  '())))
813
808
 
814
809
  ;; Fast path.
815
- (let recur ((lis lis1))
816
- (if (null-list? lis) lis
817
- (let ((tail (cdr lis))
818
- (x (f (car lis)))) ; Do head first,
819
- (cons x (recur tail))))))) ; then tail.
820
-
810
+ (%map f lis1)))
821
811
 
822
812
  ;;; We extend MAP to handle arguments of unequal length.
823
813
  (define map map-in-order)
824
814
  (define for-each map-in-order)
825
815
 
826
-
827
816
  ;;; filter, remove, partition
828
817
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
829
818
  ;;; FILTER, REMOVE, PARTITION and their destructive counterparts do not
@@ -832,17 +821,19 @@
832
821
  ;; This FILTER shares the longest tail of L that has no deleted elements.
833
822
  ;; If Scheme had multi-continuation calls, they could be made more efficient.
834
823
 
835
- (define (filter pred lis) ; Sleazing with EQ? makes this
836
- (check-arg procedure? pred filter) ; one faster.
837
- (let recur ((lis lis))
838
- (if (null-list? lis) lis ; Use NOT-PAIR? to handle dotted lists.
839
- (let ((head (car lis))
840
- (tail (cdr lis)))
841
- (if (pred head)
842
- (let ((new-tail (recur tail))) ; Replicate the RECUR call so
843
- (if (eq? tail new-tail) lis
844
- (cons head new-tail)))
845
- (recur tail)))))) ; this one can be a tail call.
824
+ ;;(define (filter pred lis) ; Sleazing with EQ? makes this
825
+ ;; (check-arg procedure? pred filter) ; one faster.
826
+ ;; (let recur ((lis lis))
827
+ ;; (if (null-list? lis) lis ; Use NOT-PAIR? to handle dotted lists.
828
+ ;; (let ((head (car lis))
829
+ ;; (tail (cdr lis)))
830
+ ;; (if (pred head)
831
+ ;; (let ((new-tail (recur tail))) ; Replicate the RECUR call so
832
+ ;; (if (eq? tail new-tail) lis
833
+ ;; (cons head new-tail)))
834
+ ;; (recur tail)))))) ; this one can be a tail call.
835
+
836
+ (define filter %filter)
846
837
 
847
838
 
848
839
  ;;; Another version that shares longest tail.