nendo 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/nendo.rb CHANGED
@@ -35,6 +35,8 @@
35
35
  # $Id:
36
36
  #
37
37
 
38
+ require 'pp'
39
+
38
40
  module Nendo
39
41
  require 'stringio'
40
42
  require 'digest/sha1'
@@ -71,6 +73,16 @@ module Nendo
71
73
 
72
74
  class LispMacro < Proc
73
75
  end
76
+
77
+ class LispSyntax < Proc
78
+ end
79
+
80
+ class LispCoreSyntax
81
+ def initialize( syntaxName )
82
+ @syntaxName = syntaxName
83
+ end
84
+ attr_reader :syntaxName
85
+ end
74
86
 
75
87
  class Cell
76
88
  include Enumerable
@@ -821,16 +833,12 @@ module Nendo
821
833
  def _equal_QUMARK( a, b )
822
834
  if a.is_a? String and b.is_a? String
823
835
  a === b
836
+ elsif _null_QUMARK( a ) and _null_QUMARK( b )
837
+ true
824
838
  elsif a.class != b.class
825
839
  false
826
840
  elsif a.class == Cell
827
- if a.isNull and b.isNull
828
- true
829
- else
830
- _equal_QUMARK( a.car, b.car ) and _equal_QUMARK( a.cdr, b.cdr )
831
- end
832
- elsif a.class == Nil and b.class == Nil
833
- true
841
+ _equal_QUMARK( a.car, b.car ) and _equal_QUMARK( a.cdr, b.cdr )
834
842
  else
835
843
  (a === b)
836
844
  end
@@ -1047,6 +1055,14 @@ module Nendo
1047
1055
  def _macro_QUMARK( arg ) (LispMacro == arg.class) end
1048
1056
  def _symbol_QUMARK( arg ) (Symbol == arg.class) end
1049
1057
  def _keyword_QUMARK( arg ) (arg.is_a? LispKeyword) end
1058
+ def _syntax_QUMARK( arg ) (arg.is_a? LispSyntax) end
1059
+ def _core_MIMARKsyntax_QUMARK( arg )
1060
+ if arg.is_a? LispCoreSyntax
1061
+ arg.syntaxName
1062
+ else
1063
+ nil
1064
+ end
1065
+ end
1050
1066
  def _pair_QUMARK( arg )
1051
1067
  if _null_QUMARK( arg )
1052
1068
  false
@@ -1154,7 +1170,7 @@ module Nendo
1154
1170
 
1155
1171
  def _global_MIMARKvariables
1156
1172
  self.instance_variables.select { |x|
1157
- x.match( /^[@]_[a-zA-Z]/ )
1173
+ x.match( /^[@]_[_a-zA-Z]/ )
1158
1174
  }.map{ |name|
1159
1175
  self.toLispSymbol( name[1..-1] ).intern
1160
1176
  }.to_list
@@ -1258,32 +1274,40 @@ module Nendo
1258
1274
  @debug = debug
1259
1275
  @trace_debug = false
1260
1276
  @char_table_lisp_to_ruby = {
1261
- # list (! $ % & * + - . / : < = > ? @ ^ _ ~)
1262
- '!' => '_EXMARK',
1263
- '$' => '_DOMARK',
1264
- '%' => '_PAMARK',
1265
- '&' => '_ANMARK',
1266
- '*' => '_ASMARK',
1267
- '+' => '_PLMARK',
1268
- '-' => '_MIMARK',
1277
+ # list (! $ % & * + - . / : < = > ? @ ^ _ ~ ...)
1278
+ '!' => '_EXMARK',
1279
+ '$' => '_DOMARK',
1280
+ '%' => '_PAMARK',
1281
+ '&' => '_ANMARK',
1282
+ '*' => '_ASMARK',
1283
+ '+' => '_PLMARK',
1284
+ '-' => '_MIMARK',
1269
1285
  # '.'
1270
- '/' => '_SLMARK',
1271
- ':' => '_COMARK',
1272
- '<' => '_LTMARK',
1273
- '=' => '_EQMARK',
1274
- '>' => '_GTMARK',
1275
- '?' => '_QUMARK',
1276
- '@' => '_ATMARK',
1277
- '^' => '_NKMARK',
1286
+ '/' => '_SLMARK',
1287
+ ':' => '_COMARK',
1288
+ '<' => '_LTMARK',
1289
+ '=' => '_EQMARK',
1290
+ '>' => '_GTMARK',
1291
+ '?' => '_QUMARK',
1292
+ '@' => '_ATMARK',
1293
+ '^' => '_NKMARK',
1278
1294
  # '_'
1279
- '~' => '_CHMARK',
1295
+ '~' => '_CHMARK',
1296
+ '...' => '_DOTDOTDOT',
1280
1297
  }
1281
1298
  @char_table_ruby_to_lisp = @char_table_lisp_to_ruby.invert
1282
-
1299
+
1300
+ @core_syntax_list = [ :quote, :"syntax-quote", :if , :begin , :lambda , :macro , :"&block" , :let , :letrec , :define, :set!, :error, :"%syntax", :"define-syntax" ]
1301
+ @core_syntax_hash = Hash.new
1302
+ @core_syntax_list.each { |x|
1303
+ renamed = ("/nendo/core/" + x.to_s).intern
1304
+ @core_syntax_hash[ x ] = renamed
1305
+ }
1306
+
1283
1307
  # toplevel binding
1284
1308
  @global_lisp_binding = Hash.new
1285
1309
 
1286
- # initialize buildin functions as Proc objects
1310
+ # initialize builtin functions as Proc objects
1287
1311
  rubyExp = self.methods.select { |x|
1288
1312
  x.to_s.match( /^_/ )
1289
1313
  }.map { |name|
@@ -1294,6 +1318,17 @@ module Nendo
1294
1318
  ].join( " ; " )
1295
1319
  }.join( " ; " )
1296
1320
  eval( rubyExp, @binding )
1321
+
1322
+ # initialize builtin syntax as LispCoreSyntax
1323
+ rubyExp = @core_syntax_hash.map { |k,v|
1324
+ name1 = toRubySymbol( k )
1325
+ name2 = toRubySymbol( v )
1326
+ [ sprintf( "@%s = LispCoreSyntax.new( :\"%s\" ) ", name1, k ),
1327
+ sprintf( "@global_lisp_binding['%s'] = @%s ", name1, name1 ),
1328
+ sprintf( "@%s = @%s ", name2, name1 ),
1329
+ sprintf( "@global_lisp_binding['%s'] = @%s ", name1, name2 ) ].join( " ; " )
1330
+ }.join( " ; " )
1331
+ eval( rubyExp, @binding )
1297
1332
 
1298
1333
  # reset gensym counter
1299
1334
  @gensym_counter = 0
@@ -1388,6 +1423,7 @@ module Nendo
1388
1423
  if 0 == name.length
1389
1424
  ""
1390
1425
  else
1426
+ name.gsub!( Regexp.new( Regexp.escape( '...' )), @char_table_lisp_to_ruby[ '...' ] )
1391
1427
  arr = name.gsub( /["]/, '' ).split( /[.]/ )
1392
1428
  tmp = arr[0]
1393
1429
  tmp.gsub!( /[:][:]/, " " ) # save '::'
@@ -1516,7 +1552,7 @@ module Nendo
1516
1552
 
1517
1553
  def execFunc( funcname, args, sourcefile, lineno, locals, sourceInfo, execType )
1518
1554
  case funcname
1519
- when :define, :set! # `define' special form
1555
+ when :define, :set!, :"define-syntax", @core_syntax_hash[ :define ], @core_syntax_hash[ :set! ], @core_syntax_hash[ :"define-syntax" ] # `define' special form
1520
1556
  ar = args.cdr.map { |x| x.car }
1521
1557
  variable_sym = toRubySymbol( args.car.to_s.sub( /^:/, "" ))
1522
1558
  global_cap = locals.flatten.include?( variable_sym.split( /[.]/ )[0] ) ? nil : "@"
@@ -1537,10 +1573,18 @@ module Nendo
1537
1573
  "trampCall(", [ ar ], ")"],
1538
1574
  "end"
1539
1575
  ]
1540
- when :error
1576
+ when :error, @core_syntax_hash[ :error ]
1577
+ arr = if args.length < 2
1578
+ args.car
1579
+ else
1580
+ [ args.car + " ' ' + ",
1581
+ "_write_MIMARKto_MIMARKstring(",
1582
+ args.cdr.car,
1583
+ ")" ]
1584
+ end
1541
1585
  [
1542
1586
  'begin raise RuntimeError, ',
1543
- args.car,
1587
+ arr,
1544
1588
  "rescue => __e ",
1545
1589
  sprintf( " __e.set_backtrace( [\"%s:%d\"] + __e.backtrace )", sourcefile, lineno ),
1546
1590
  " raise __e",
@@ -1626,6 +1670,8 @@ module Nendo
1626
1670
  sprintf( "LispMacro.new { %s ", argStr )
1627
1671
  when :lambda
1628
1672
  sprintf( "Proc.new { %s ", argStr )
1673
+ when :"%syntax"
1674
+ sprintf( "LispSyntax.new { %s ", argStr )
1629
1675
  when :"&block"
1630
1676
  sprintf( "&Proc.new { %s ", argStr )
1631
1677
  else
@@ -1800,7 +1846,13 @@ module Nendo
1800
1846
  def translate( sexp, locals, sourceInfo = nil )
1801
1847
  case sexp
1802
1848
  when Cell
1803
- if :quote == sexp.car
1849
+ inv = @core_syntax_hash.invert
1850
+ car = if inv.has_key?( sexp.car )
1851
+ inv[ sexp.car ]
1852
+ else
1853
+ sexp.car
1854
+ end
1855
+ if :quote == car or :"syntax-quote" == car
1804
1856
  genQuote( sexp.cdr.car )
1805
1857
  elsif sexp.isDotted
1806
1858
  raise NameError, "Error: can't eval dotted pair."
@@ -1808,21 +1860,23 @@ module Nendo
1808
1860
  [ "Cell.new()" ]
1809
1861
  elsif Cell == sexp.car.class
1810
1862
  self.apply( translate( sexp.car, locals, sourceInfo ), sexp.cdr, sexp.car.car.sourcefile, sexp.car.car.lineno, locals, sourceInfo, EXEC_TYPE_ANONYMOUS )
1811
- elsif :begin == sexp.car
1863
+ elsif :begin == car
1812
1864
  self.makeBegin( sexp.cdr, locals )
1813
- elsif :lambda == sexp.car
1865
+ elsif :lambda == car
1814
1866
  self.makeClosure( :lambda, sexp.cdr, locals )
1815
- elsif :macro == sexp.car
1867
+ elsif :macro == car
1816
1868
  self.makeClosure( :macro, sexp.cdr, locals )
1817
- elsif :"&block" == sexp.car
1869
+ elsif :"%syntax" == car
1870
+ self.makeClosure( :"%syntax", sexp.cdr, locals )
1871
+ elsif :"&block" == car
1818
1872
  self.makeClosure( :"&block", sexp.cdr, locals )
1819
- elsif :if == sexp.car
1873
+ elsif :if == car
1820
1874
  self.makeIf( sexp.cdr, locals )
1821
- elsif :let == sexp.car
1875
+ elsif :let == car
1822
1876
  self.makeLet( sexp.cdr, locals )
1823
- elsif :letrec == sexp.car
1877
+ elsif :letrec == car
1824
1878
  self.makeLetrec( sexp.cdr, locals )
1825
- elsif :"%tailcall" == sexp.car
1879
+ elsif :"%tailcall" == car
1826
1880
  if sexp.cdr.car.is_a? Cell
1827
1881
  sexp = sexp.cdr.car
1828
1882
  self.apply( sexp.car, sexp.cdr, sexp.car.sourcefile, sexp.car.lineno, locals, sourceInfo, EXEC_TYPE_TAILCALL )
@@ -1881,13 +1935,40 @@ module Nendo
1881
1935
  def quotingPhase( sexp )
1882
1936
  case sexp
1883
1937
  when Cell
1884
- if :quote == sexp.car or :quasiquote == sexp.car
1938
+ car = sexp.car
1939
+ if :quote == car or :quasiquote == car or :"syntax-quote" == car or
1940
+ @core_syntax_hash[ :quote ] == car or
1941
+ @core_syntax_hash[ :quasiquote ] == car or
1942
+ @core_syntax_hash[ :"syntax-quote" ] == car
1885
1943
  sexp
1886
- elsif :define == sexp.car or :set! == sexp.car or :lambda == sexp.car or :macro == sexp.car or :"&block" == sexp.car
1887
- sexp.cdr.car = Cell.new( :quote, Cell.new( sexp.cdr.car ))
1888
- sexp.cdr.cdr = quotingPhase( sexp.cdr.cdr )
1944
+ elsif :define == car or :set! == car or :lambda == car or :macro == car or :"&block" == car or :"%syntax" == car or :"define-syntax" == car or
1945
+ @core_syntax_hash[ :define ] == car or
1946
+ @core_syntax_hash[ :set! ] == car or
1947
+ @core_syntax_hash[ :lambda ] == car or
1948
+ @core_syntax_hash[ :macro ] == car or
1949
+ @core_syntax_hash[ :"&block" ] == car or
1950
+ @core_syntax_hash[ :"%syntax" ] == car or
1951
+ @core_syntax_hash[ :"define-syntax" ] == car
1952
+ if @debug
1953
+ if 2 >= sexp.length
1954
+ printf( "\n quotingPhase-1 label=%s, sexp.length=%d \n", sexp.car, sexp.length )
1955
+ else
1956
+ printf( "\n quotingPhase-1 label=%s, sexp.length=%d, sexp.cdr=%s sexp.cdr.car=%s sexp.cdr.cdr=%s\n", sexp.car, sexp.length, sexp.cdr, sexp.cdr.car, sexp.cdr.cdr )
1957
+ end
1958
+ end
1959
+ if 1 == sexp.length
1960
+ nil
1961
+ # do nothing
1962
+ elsif 3 <= sexp.length
1963
+ # argument
1964
+ sexp.cdr.car = Cell.new( :quote, Cell.new( sexp.cdr.car ))
1965
+ # body
1966
+ sexp.cdr.cdr = quotingPhase( sexp.cdr.cdr )
1967
+ else
1968
+ raise RuntimeError, sprintf( "Error: %s is not a illegal form got: %s", sexp.car, _write_MIMARKto_MIMARKstring( sexp ))
1969
+ end
1889
1970
  sexp
1890
- elsif :let == sexp.car
1971
+ elsif :let == car or @core_syntax_hash[ :let ] == car
1891
1972
  if _null_QUMARK( sexp.cdr )
1892
1973
  # do nothing
1893
1974
  else
@@ -1902,13 +1983,17 @@ module Nendo
1902
1983
  end
1903
1984
  end
1904
1985
  sexp
1905
- elsif :letrec == sexp.car
1906
- case sexp.cdr.car
1907
- when Cell # letrec
1908
- sexp.cdr = Cell.new( letArgumentList( sexp.cdr.car ),
1909
- quotingPhase( sexp.cdr.cdr ))
1910
- when Symbol # named letrec is illegal
1911
- raise RuntimeError, "Error: named letrec is not a illegal form"
1986
+ elsif :letrec == car or @core_syntax_hash[ :letrec ] == car
1987
+ if _null_QUMARK( sexp.cdr )
1988
+ # do nothing
1989
+ else
1990
+ case sexp.cdr.car
1991
+ when Cell # letrec
1992
+ sexp.cdr = Cell.new( letArgumentList( sexp.cdr.car ),
1993
+ quotingPhase( sexp.cdr.cdr ))
1994
+ when Symbol # named letrec is illegal
1995
+ raise RuntimeError, "Error: named letrec is not a illegal form"
1996
+ end
1912
1997
  end
1913
1998
  sexp
1914
1999
  else
@@ -1926,10 +2011,14 @@ module Nendo
1926
2011
  def macroexpandEngine( sexp )
1927
2012
  case sexp
1928
2013
  when Cell
1929
- if :quote == sexp.car
2014
+ car = sexp.car
2015
+ if :quote == car or :"syntax-quote" == car or @core_syntax_hash[ :quote ] == car or @core_syntax_hash[ :"syntax-quote" ] == car
1930
2016
  sexp
1931
2017
  else
1932
2018
  sym = sexp.car.to_s
2019
+ p 'macroexpandEngine' if @debug
2020
+ p sexp.car.class if @debug
2021
+ p sym if @debug
1933
2022
  sym = toRubySymbol( sym )
1934
2023
  newSexp = sexp
1935
2024
  if isRubyInterface( sym )
@@ -1938,6 +2027,13 @@ module Nendo
1938
2027
  elsif sexp.car.class == Symbol and eval( sprintf( "(defined? @%s and LispMacro == @%s.class)", sym,sym ), @binding )
1939
2028
  eval( sprintf( "@__macro = @%s", sym ), @binding )
1940
2029
  newSexp = trampCall( callProcedure( sym, @__macro, sexp.cdr.to_arr ))
2030
+ elsif sexp.car.class == Symbol and eval( sprintf( "(defined? @%s and LispSyntax == @%s.class)", sym,sym ), @binding )
2031
+ # expected input is
2032
+ # (syntaxName arg1 arg2 ...)
2033
+ # will be transformed
2034
+ # (syntaxName (syntaxName arg1 arg2 ...) () (global-variables))
2035
+ eval( sprintf( "@__syntax = @%s", sym ), @binding )
2036
+ newSexp = trampCall( callProcedure( sym, @__syntax, [ sexp, Cell.new(), _global_MIMARKvariables( ) ] ))
1941
2037
  end
1942
2038
  if _equal_QUMARK( newSexp, sexp )
1943
2039
  sexp.map { |x|
@@ -2149,6 +2245,20 @@ module Nendo
2149
2245
  eval( str, @binding )
2150
2246
  true
2151
2247
  end
2248
+
2249
+ def _make_MIMARKsyntactic_MIMARKclosure( mac_env, use_env, identifier )
2250
+ if _pair_QUMARK( identifier )
2251
+ raise RuntimeError, "Error: make-syntactic-closure requires symbol only..."
2252
+ else
2253
+ if mac_env.to_arr.include?( identifier )
2254
+ identifier
2255
+ else
2256
+ sym = toRubySymbol( identifier ) + _gensym( ).to_s
2257
+ sym.intern
2258
+ end
2259
+ end
2260
+ end
2261
+
2152
2262
  end
2153
2263
 
2154
2264
  class Printer
@@ -2234,7 +2344,7 @@ module Nendo
2234
2344
  end
2235
2345
 
2236
2346
  def self.version
2237
- "0.4.1" ##NENDO-VERSION
2347
+ "0.5.0" ##NENDO-VERSION
2238
2348
  end
2239
2349
 
2240
2350
  def loadInitFile( use_compiled = true )
data/lib/rfc/json.nnd CHANGED
@@ -35,7 +35,7 @@
35
35
  ;;;
36
36
 
37
37
  (require "json")
38
-
38
+ (use util.list)
39
39
 
40
40
  ;; ------------------------------
41
41
  (define (%json:hash-table->alist obj)
data/lib/rfc/json.nndc CHANGED
@@ -18,6 +18,21 @@ trampCall(
18
18
  )
19
19
  #--------------------
20
20
 
21
+ trampCall(
22
+ delayCall( '_load', 'load',
23
+ begin
24
+ if @global_lisp_binding.has_key?('_load') then
25
+ trampCall(@_load)
26
+ else raise NameError.new( "Error: undefined variable _load", "_load" ) end
27
+ rescue => __e ; __e.set_backtrace( [":1"] + __e.backtrace ) ; raise __e
28
+ end ,
29
+ [
30
+ "util/list"
31
+ ]
32
+ )
33
+ )
34
+ #--------------------
35
+
21
36
  trampCall(
22
37
  begin
23
38
  def self.__PAMARKjson_COMARKhash_MIMARKtable_MIMARK_GTMARKalist_METHOD( origname, pred, args ) lispMethodEntry( origname, true ) ; ret = callProcedure( origname, pred, args ) ; lispMethodExit( origname, true ) ; return ret end
@@ -517,7 +532,7 @@ trampCall(
517
532
  end
518
533
  } ; ___lambda.call(
519
534
  begin
520
- ___lambda = lambda { |___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_20019|
535
+ ___lambda = lambda { |___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_80019|
521
536
  if (
522
537
  trampCall( self._null_QUMARK_METHOD( 'null?',
523
538
  begin
@@ -528,7 +543,7 @@ trampCall(
528
543
  end ,
529
544
  [
530
545
  begin
531
- trampCall(___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_20019)
546
+ trampCall(___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_80019)
532
547
  rescue => __e ; __e.set_backtrace( [":1"] + __e.backtrace ) ; raise __e
533
548
  end
534
549
  ]
@@ -548,7 +563,7 @@ trampCall(
548
563
  end ,
549
564
  [
550
565
  begin
551
- trampCall(___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_20019)
566
+ trampCall(___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_80019)
552
567
  rescue => __e ; __e.set_backtrace( [":1"] + __e.backtrace ) ; raise __e
553
568
  end
554
569
  ]
@@ -631,7 +646,7 @@ trampCall(
631
646
  end
632
647
  } ; ___lambda.call(
633
648
  begin
634
- ___lambda = lambda { |___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_20020|
649
+ ___lambda = lambda { |___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_80020|
635
650
  if (
636
651
  trampCall( self._null_QUMARK_METHOD( 'null?',
637
652
  begin
@@ -642,7 +657,7 @@ trampCall(
642
657
  end ,
643
658
  [
644
659
  begin
645
- trampCall(___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_20020)
660
+ trampCall(___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_80020)
646
661
  rescue => __e ; __e.set_backtrace( [":1"] + __e.backtrace ) ; raise __e
647
662
  end
648
663
  ]
@@ -662,7 +677,7 @@ trampCall(
662
677
  end ,
663
678
  [
664
679
  begin
665
- trampCall(___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_20020)
680
+ trampCall(___gensym__6e1da08b054bbf0469585c6330e1b00b59b91d4c_80020)
666
681
  rescue => __e ; __e.set_backtrace( [":1"] + __e.backtrace ) ; raise __e
667
682
  end
668
683
  ]
data/lib/srfi-1.nnd CHANGED
@@ -1057,11 +1057,15 @@
1057
1057
  (check-arg procedure? elt= delete-duplicates!)
1058
1058
  (let recur ((lis lis))
1059
1059
  (if (null-list? lis) lis
1060
- (let* ((x (car lis))
1061
- (tail (cdr lis))
1062
- (new-tail (recur (delete! x tail elt=))))
1063
- (if (eq? tail new-tail) lis (cons x new-tail)))))))
1064
-
1060
+ (let* ((x (car lis))
1061
+ (tail (cdr lis))
1062
+ (new-tail (recur (delete! x tail elt=))))
1063
+ (if (eq? tail new-tail)
1064
+ lis
1065
+ (begin
1066
+ (set-car! lis x)
1067
+ (set-cdr! lis new-tail)
1068
+ lis)))))))
1065
1069
 
1066
1070
  ;;; alist stuff
1067
1071
  ;;;;;;;;;;;;;;;