nendo 0.5.0 → 0.5.1
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/emacs/nendo-mode.el +2 -0
- data/lib/init.nnd +51 -35
- data/lib/init.nndc +3371 -2920
- data/lib/nendo.rb +463 -194
- data/lib/srfi-2.nndc +48 -165
- data/lib/srfi-26.nndc +142 -511
- data/lib/text/html-lite.nndc +23 -1
- data/lib/util/combinations.nnd +290 -0
- data/lib/util/combinations.nndc +7218 -0
- data/lib/util/list.nndc +138 -387
- data/lib/util/match.nnd +672 -0
- data/lib/util/match.nndc +81024 -0
- data/test/match-test.nnd +186 -0
- data/test/nendo-util-test.nnd +5 -7
- data/test/nendo_spec.rb +697 -235
- data/test/syntax_spec.rb +561 -52
- data/test/util-combinations-test.nnd +383 -0
- metadata +9 -4
- data/example/scratch.nnd +0 -119
data/lib/nendo.rb
CHANGED
@@ -34,13 +34,11 @@
|
|
34
34
|
#
|
35
35
|
# $Id:
|
36
36
|
#
|
37
|
-
|
38
|
-
require 'pp'
|
39
|
-
|
40
37
|
module Nendo
|
41
38
|
require 'stringio'
|
42
39
|
require 'digest/sha1'
|
43
|
-
|
40
|
+
require 'pp'
|
41
|
+
|
44
42
|
class Nil
|
45
43
|
include Enumerable
|
46
44
|
def each() end
|
@@ -83,10 +81,10 @@ module Nendo
|
|
83
81
|
end
|
84
82
|
attr_reader :syntaxName
|
85
83
|
end
|
86
|
-
|
84
|
+
|
87
85
|
class Cell
|
88
86
|
include Enumerable
|
89
|
-
|
87
|
+
|
90
88
|
def initialize( car = Nil.new, cdr = Nil.new )
|
91
89
|
@car = car
|
92
90
|
@cdr = cdr
|
@@ -151,6 +149,21 @@ module Nendo
|
|
151
149
|
self.map {|x| x.car}
|
152
150
|
end
|
153
151
|
end
|
152
|
+
|
153
|
+
def first
|
154
|
+
self.car
|
155
|
+
end
|
156
|
+
|
157
|
+
def second
|
158
|
+
self.cdr.car
|
159
|
+
end
|
160
|
+
|
161
|
+
def third
|
162
|
+
self.cdr.cdr.car
|
163
|
+
end
|
164
|
+
|
165
|
+
alias :cdar :second
|
166
|
+
alias :cddar :third
|
154
167
|
end
|
155
168
|
|
156
169
|
class LispValues
|
@@ -202,6 +215,34 @@ module Nendo
|
|
202
215
|
attr_reader :key
|
203
216
|
end
|
204
217
|
|
218
|
+
class SyntacticClosure
|
219
|
+
def initialize( originalSymbol, renamedSymbol )
|
220
|
+
@originalSymbol = originalSymbol
|
221
|
+
@renamedSymbol = renamedSymbol
|
222
|
+
end
|
223
|
+
|
224
|
+
def to_s
|
225
|
+
@renamedSymbol.to_s
|
226
|
+
end
|
227
|
+
|
228
|
+
def intern
|
229
|
+
@renamedSymbol
|
230
|
+
end
|
231
|
+
|
232
|
+
# def ==(other_sc)
|
233
|
+
# if other_sc.is_a? SyntacticClosure
|
234
|
+
# @renamedSymbol == other_sc.renamedSymbol
|
235
|
+
# else
|
236
|
+
# false
|
237
|
+
# end
|
238
|
+
# end
|
239
|
+
|
240
|
+
def sourcefile() "dynamic S-expression ( no source )" end
|
241
|
+
def lineno() 1 end
|
242
|
+
|
243
|
+
attr_reader :originalSymbol, :renamedSymbol
|
244
|
+
end
|
245
|
+
|
205
246
|
class SourceInfo
|
206
247
|
def initialize
|
207
248
|
@varname = nil
|
@@ -330,6 +371,7 @@ module Nendo
|
|
330
371
|
T_LINEFEED = :t_linefeed
|
331
372
|
T_COMMENT = :t_comment
|
332
373
|
T_DEBUG_PRINT = :t_debug_print
|
374
|
+
T_MACRO_DEBUG_PRINT = :t_macro_debug_print
|
333
375
|
T_REGEXP = :t_regexp
|
334
376
|
|
335
377
|
# inport is IO class
|
@@ -498,10 +540,13 @@ module Nendo
|
|
498
540
|
if peekchar( /[=]/ )
|
499
541
|
str = ""
|
500
542
|
T_DEBUG_PRINT
|
543
|
+
elsif peekchar( /[.]/ )
|
544
|
+
str = ""
|
545
|
+
T_MACRO_DEBUG_PRINT
|
501
546
|
else
|
502
547
|
str += readwhile( /[^ \t\r\n]/ )
|
503
548
|
raise NameError, sprintf( "Error: unknown #xxxx syntax for Nendo %s", str )
|
504
|
-
end
|
549
|
+
end
|
505
550
|
when "!"
|
506
551
|
readwhile( /[^\r\n]/ )
|
507
552
|
str = ""
|
@@ -638,6 +683,8 @@ module Nendo
|
|
638
683
|
:feedto
|
639
684
|
when T_DEBUG_PRINT
|
640
685
|
"debug-print".intern
|
686
|
+
when T_MACRO_DEBUG_PRINT
|
687
|
+
LispString.new( sprintf( "%s:%d", cur.sourcefile, cur.lineno ))
|
641
688
|
when T_KEYWORD
|
642
689
|
LispKeyword.new( cur.str )
|
643
690
|
else
|
@@ -833,12 +880,14 @@ module Nendo
|
|
833
880
|
def _equal_QUMARK( a, b )
|
834
881
|
if a.is_a? String and b.is_a? String
|
835
882
|
a === b
|
836
|
-
elsif _null_QUMARK( a ) and _null_QUMARK( b )
|
837
|
-
true
|
838
883
|
elsif a.class != b.class
|
839
884
|
false
|
840
|
-
elsif a.
|
885
|
+
elsif a.is_a? Cell
|
841
886
|
_equal_QUMARK( a.car, b.car ) and _equal_QUMARK( a.cdr, b.cdr )
|
887
|
+
elsif _null_QUMARK( a ) and _null_QUMARK( b )
|
888
|
+
true
|
889
|
+
elsif a.is_a? Proc
|
890
|
+
a == b
|
842
891
|
else
|
843
892
|
(a === b)
|
844
893
|
end
|
@@ -1045,15 +1094,22 @@ module Nendo
|
|
1045
1094
|
def _le_QUMARK( a,b ) a <= b end
|
1046
1095
|
def _eqv_QUMARK( a,b ) a === b end
|
1047
1096
|
def _car( cell ) cell.car end
|
1048
|
-
def _cdr( cell )
|
1097
|
+
def _cdr( cell )
|
1098
|
+
if cell.cdr.is_a? Nil
|
1099
|
+
Cell.new
|
1100
|
+
else
|
1101
|
+
cell.cdr
|
1102
|
+
end
|
1103
|
+
end
|
1049
1104
|
def _write( arg ) printer = Printer.new ; print printer._write( arg ) ; arg end
|
1050
1105
|
def _write_MIMARKto_MIMARKstring( arg ) printer = Printer.new ; printer._write( arg ) end
|
1106
|
+
alias write_to_string _write_MIMARKto_MIMARKstring
|
1051
1107
|
def _display( arg ) printer = Printer.new ; print printer._print( arg ) ; arg end
|
1052
1108
|
def _print( arg ) self._display( arg ) ; self._newline() ; arg end
|
1053
1109
|
def _newline( ) print "\n" end
|
1054
1110
|
def _procedure_QUMARK( arg ) ((Proc == arg.class) or (Method == arg.class)) end
|
1055
1111
|
def _macro_QUMARK( arg ) (LispMacro == arg.class) end
|
1056
|
-
def _symbol_QUMARK( arg ) (Symbol
|
1112
|
+
def _symbol_QUMARK( arg ) (arg.is_a? Symbol or arg.is_a? SyntacticClosure) end
|
1057
1113
|
def _keyword_QUMARK( arg ) (arg.is_a? LispKeyword) end
|
1058
1114
|
def _syntax_QUMARK( arg ) (arg.is_a? LispSyntax) end
|
1059
1115
|
def _core_MIMARKsyntax_QUMARK( arg )
|
@@ -1083,7 +1139,7 @@ module Nendo
|
|
1083
1139
|
def _macroexpand_MIMARK1( arg )
|
1084
1140
|
if _pair_QUMARK( arg )
|
1085
1141
|
macroexpandInit( 1 )
|
1086
|
-
macroexpandEngine( arg )
|
1142
|
+
macroexpandEngine( arg, [], [] )
|
1087
1143
|
else
|
1088
1144
|
arg
|
1089
1145
|
end
|
@@ -1273,6 +1329,8 @@ module Nendo
|
|
1273
1329
|
@binding = binding
|
1274
1330
|
@debug = debug
|
1275
1331
|
@trace_debug = false
|
1332
|
+
@lexicalVars = []
|
1333
|
+
@syntaxHash = {}
|
1276
1334
|
@char_table_lisp_to_ruby = {
|
1277
1335
|
# list (! $ % & * + - . / : < = > ? @ ^ _ ~ ...)
|
1278
1336
|
'!' => '_EXMARK',
|
@@ -1297,7 +1355,7 @@ module Nendo
|
|
1297
1355
|
}
|
1298
1356
|
@char_table_ruby_to_lisp = @char_table_lisp_to_ruby.invert
|
1299
1357
|
|
1300
|
-
@core_syntax_list = [ :quote, :"syntax-quote", :if , :begin , :lambda , :macro , :"&block" , :let , :letrec , :define, :set!, :error, :"%syntax", :"define-syntax" ]
|
1358
|
+
@core_syntax_list = [ :quote, :"syntax-quote", :if , :begin , :lambda , :macro , :"&block" , :"%let" , :letrec , :define, :set!, :error, :"%syntax", :"define-syntax", :"let-syntax" ]
|
1301
1359
|
@core_syntax_hash = Hash.new
|
1302
1360
|
@core_syntax_list.each { |x|
|
1303
1361
|
renamed = ("/nendo/core/" + x.to_s).intern
|
@@ -1419,29 +1477,33 @@ module Nendo
|
|
1419
1477
|
end
|
1420
1478
|
|
1421
1479
|
def toRubySymbol( name )
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
tmp = arr[0]
|
1429
|
-
tmp.gsub!( /[:][:]/, " " ) # save '::'
|
1430
|
-
@char_table_lisp_to_ruby.each_pair { |key,val|
|
1431
|
-
tmp.gsub!( Regexp.new( Regexp.escape( key )), val )
|
1432
|
-
}
|
1433
|
-
arr[0] = tmp.gsub( /[ ][ ]/, "::" )
|
1434
|
-
if arr[0].match( /^[A-Z]/ )
|
1435
|
-
# nothing to do
|
1436
|
-
elsif arr[0] == ""
|
1437
|
-
arr[0] = 'Kernel'
|
1480
|
+
if SyntacticClosure == name.class
|
1481
|
+
"_" + name.to_s
|
1482
|
+
else
|
1483
|
+
name = name.to_s if Symbol == name.class
|
1484
|
+
if 0 == name.length
|
1485
|
+
""
|
1438
1486
|
else
|
1439
|
-
|
1487
|
+
name.gsub!( Regexp.new( Regexp.escape( '...' )), @char_table_lisp_to_ruby[ '...' ] )
|
1488
|
+
arr = name.gsub( /["]/, '' ).split( /[.]/ )
|
1489
|
+
tmp = arr[0]
|
1490
|
+
tmp.gsub!( /[:][:]/, " " ) # save '::'
|
1491
|
+
@char_table_lisp_to_ruby.each_pair { |key,val|
|
1492
|
+
tmp.gsub!( Regexp.new( Regexp.escape( key )), val )
|
1493
|
+
}
|
1494
|
+
arr[0] = tmp.gsub( /[ ][ ]/, "::" )
|
1495
|
+
if arr[0].match( /^[A-Z]/ )
|
1496
|
+
# nothing to do
|
1497
|
+
elsif arr[0] == ""
|
1498
|
+
arr[0] = 'Kernel'
|
1499
|
+
else
|
1500
|
+
arr[0] = '_' + arr[0]
|
1501
|
+
end
|
1502
|
+
arr.join( "." )
|
1440
1503
|
end
|
1441
|
-
arr.join( "." )
|
1442
1504
|
end
|
1443
1505
|
end
|
1444
|
-
|
1506
|
+
|
1445
1507
|
def isRubyInterface( name )
|
1446
1508
|
name.to_s.match( /[.]/ )
|
1447
1509
|
end
|
@@ -1550,9 +1612,12 @@ module Nendo
|
|
1550
1612
|
}
|
1551
1613
|
end
|
1552
1614
|
|
1615
|
+
def isDefines( sym )
|
1616
|
+
[ :define, :set!, :"define-syntax", @core_syntax_hash[ :define ], @core_syntax_hash[ :set! ], @core_syntax_hash[ :"define-syntax" ] ].include?( sym )
|
1617
|
+
end
|
1618
|
+
|
1553
1619
|
def execFunc( funcname, args, sourcefile, lineno, locals, sourceInfo, execType )
|
1554
|
-
|
1555
|
-
when :define, :set!, :"define-syntax", @core_syntax_hash[ :define ], @core_syntax_hash[ :set! ], @core_syntax_hash[ :"define-syntax" ] # `define' special form
|
1620
|
+
if isDefines( funcname )
|
1556
1621
|
ar = args.cdr.map { |x| x.car }
|
1557
1622
|
variable_sym = toRubySymbol( args.car.to_s.sub( /^:/, "" ))
|
1558
1623
|
global_cap = locals.flatten.include?( variable_sym.split( /[.]/ )[0] ) ? nil : "@"
|
@@ -1573,7 +1638,7 @@ module Nendo
|
|
1573
1638
|
"trampCall(", [ ar ], ")"],
|
1574
1639
|
"end"
|
1575
1640
|
]
|
1576
|
-
|
1641
|
+
elsif :error == funcname or @core_syntax_hash[ :error ] == funcname
|
1577
1642
|
arr = if args.length < 2
|
1578
1643
|
args.car
|
1579
1644
|
else
|
@@ -1626,20 +1691,29 @@ module Nendo
|
|
1626
1691
|
end
|
1627
1692
|
end
|
1628
1693
|
end
|
1629
|
-
|
1694
|
+
|
1695
|
+
def makeSetVariable( car, cdr, locals, sourceInfo )
|
1696
|
+
cdr.cdr.each { |x|
|
1697
|
+
if Cell == x.class
|
1698
|
+
x.car = translate( x.car, locals, sourceInfo )
|
1699
|
+
end
|
1700
|
+
}
|
1701
|
+
execFunc( car, cdr, car.sourcefile, car.lineno, locals, sourceInfo, EXEC_TYPE_ANONYMOUS )
|
1702
|
+
end
|
1703
|
+
|
1630
1704
|
def makeBegin( args, locals )
|
1631
1705
|
ar = args.map { |e|
|
1632
1706
|
translate( e.car, locals )
|
1633
1707
|
}
|
1634
1708
|
["begin", ar, "end"]
|
1635
1709
|
end
|
1636
|
-
|
1710
|
+
|
1637
1711
|
# returns [ argsyms[], string ]
|
1638
1712
|
def toRubyParameter( argform )
|
1639
1713
|
argsyms = []
|
1640
1714
|
locals = []
|
1641
1715
|
rest = false
|
1642
|
-
if
|
1716
|
+
if _symbol_QUMARK( argform )
|
1643
1717
|
rest = argform
|
1644
1718
|
else
|
1645
1719
|
argsyms = argform.map { |x| toRubySymbol( x.car ) }
|
@@ -1649,7 +1723,7 @@ module Nendo
|
|
1649
1723
|
end
|
1650
1724
|
end
|
1651
1725
|
if rest
|
1652
|
-
rest = toRubySymbol( rest )
|
1726
|
+
rest = toRubySymbol( rest )
|
1653
1727
|
locals << rest
|
1654
1728
|
argsyms << "*__rest__"
|
1655
1729
|
[ locals, sprintf( "|%s| %s = __rest__[0] ; ", argsyms.join( "," ), rest ) ]
|
@@ -1657,13 +1731,10 @@ module Nendo
|
|
1657
1731
|
[ locals, sprintf( "|%s|", argsyms.join( "," )) ]
|
1658
1732
|
end
|
1659
1733
|
end
|
1660
|
-
|
1734
|
+
|
1661
1735
|
def makeClosure( sym, args, locals )
|
1662
1736
|
first = args.car
|
1663
|
-
|
1664
|
-
first = args.car.cdr.car
|
1665
|
-
end
|
1666
|
-
rest = args.cdr
|
1737
|
+
rest = args.cdr
|
1667
1738
|
( _locals, argStr ) = toRubyParameter( first )
|
1668
1739
|
str = case sym
|
1669
1740
|
when :macro
|
@@ -1707,12 +1778,12 @@ module Nendo
|
|
1707
1778
|
_name = "___lambda"
|
1708
1779
|
argvals = []
|
1709
1780
|
rest = args.cdr
|
1710
|
-
if args.car
|
1781
|
+
if _null_QUMARK( args.car )
|
1711
1782
|
# nothing to do
|
1712
1783
|
lambda_head = sprintf( "%s = lambda { || ", _name )
|
1713
1784
|
else
|
1714
1785
|
argsyms = args.car.map { |x|
|
1715
|
-
toRubySymbol( x.car.car.
|
1786
|
+
toRubySymbol( x.car.car.to_s )
|
1716
1787
|
}
|
1717
1788
|
argvals = args.car.map.with_index { |x,i|
|
1718
1789
|
translate( x.car.cdr.car, locals )
|
@@ -1733,12 +1804,12 @@ module Nendo
|
|
1733
1804
|
argvals = []
|
1734
1805
|
argsyms = []
|
1735
1806
|
rest = args.cdr
|
1736
|
-
if args.car
|
1807
|
+
if _null_QUMARK( args.car )
|
1737
1808
|
# nothing to do
|
1738
1809
|
lambda_head = sprintf( "%s = lambda { || ", _name )
|
1739
1810
|
else
|
1740
1811
|
argsyms = args.car.map { |x|
|
1741
|
-
toRubySymbol( x.car.car.
|
1812
|
+
toRubySymbol( x.car.car.to_s )
|
1742
1813
|
}
|
1743
1814
|
argvals = args.car.map { |x|
|
1744
1815
|
translate( x.car.cdr.car, locals.clone + [argsyms] )
|
@@ -1754,7 +1825,7 @@ module Nendo
|
|
1754
1825
|
sprintf( " )")],
|
1755
1826
|
"end"]
|
1756
1827
|
end
|
1757
|
-
|
1828
|
+
|
1758
1829
|
def apply( car, cdr, sourcefile, lineno, locals, sourceInfo, execType )
|
1759
1830
|
cdr.each { |x|
|
1760
1831
|
if Cell == x.class
|
@@ -1763,7 +1834,7 @@ module Nendo
|
|
1763
1834
|
}
|
1764
1835
|
execFunc( car, cdr, sourcefile, lineno, locals, sourceInfo, execType )
|
1765
1836
|
end
|
1766
|
-
|
1837
|
+
|
1767
1838
|
def genQuote( sexp, str = "" )
|
1768
1839
|
origStr = str
|
1769
1840
|
case sexp
|
@@ -1788,6 +1859,8 @@ module Nendo
|
|
1788
1859
|
str += sprintf( "LispKeyword.new( \"%s\" )", sexp.key.to_s )
|
1789
1860
|
when TrueClass, FalseClass, NilClass # reserved symbols
|
1790
1861
|
str += toRubyValue( sexp )
|
1862
|
+
when SyntacticClosure
|
1863
|
+
str += sprintf( ":\"%s\"", sexp.originalSymbol.to_s )
|
1791
1864
|
when Nil
|
1792
1865
|
str += "Cell.new()"
|
1793
1866
|
else
|
@@ -1852,14 +1925,16 @@ module Nendo
|
|
1852
1925
|
else
|
1853
1926
|
sexp.car
|
1854
1927
|
end
|
1855
|
-
if :quote == car
|
1856
|
-
genQuote( sexp.
|
1928
|
+
if :quote == car
|
1929
|
+
genQuote( sexp.second )
|
1930
|
+
elsif :"syntax-quote" == car
|
1931
|
+
[ "Cell.new(:\"syntax-quote\", ", genQuote( sexp.cdr ), ")" ]
|
1857
1932
|
elsif sexp.isDotted
|
1858
1933
|
raise NameError, "Error: can't eval dotted pair."
|
1859
1934
|
elsif sexp.isNull
|
1860
1935
|
[ "Cell.new()" ]
|
1861
|
-
elsif
|
1862
|
-
self.
|
1936
|
+
elsif isDefines( car )
|
1937
|
+
self.makeSetVariable( car, sexp.cdr, locals, sourceInfo )
|
1863
1938
|
elsif :begin == car
|
1864
1939
|
self.makeBegin( sexp.cdr, locals )
|
1865
1940
|
elsif :lambda == car
|
@@ -1872,17 +1947,27 @@ module Nendo
|
|
1872
1947
|
self.makeClosure( :"&block", sexp.cdr, locals )
|
1873
1948
|
elsif :if == car
|
1874
1949
|
self.makeIf( sexp.cdr, locals )
|
1875
|
-
elsif :let == car
|
1950
|
+
elsif :"%let" == car
|
1876
1951
|
self.makeLet( sexp.cdr, locals )
|
1877
1952
|
elsif :letrec == car
|
1878
1953
|
self.makeLetrec( sexp.cdr, locals )
|
1879
1954
|
elsif :"%tailcall" == car
|
1880
1955
|
if sexp.cdr.car.is_a? Cell
|
1881
1956
|
sexp = sexp.cdr.car
|
1882
|
-
|
1957
|
+
if isDefines( sexp.car )
|
1958
|
+
translate( sexp, locals, sourceInfo )
|
1959
|
+
else
|
1960
|
+
if sexp.car.is_a? Cell
|
1961
|
+
self.apply( translate( sexp.car, locals, sourceInfo ), sexp.cdr, sexp.car.car.sourcefile, sexp.car.car.lineno, locals, sourceInfo, EXEC_TYPE_ANONYMOUS )
|
1962
|
+
else
|
1963
|
+
self.apply( sexp.car, sexp.cdr, sexp.car.sourcefile, sexp.car.lineno, locals, sourceInfo, EXEC_TYPE_TAILCALL )
|
1964
|
+
end
|
1965
|
+
end
|
1883
1966
|
else
|
1884
1967
|
raise RuntimeError, "Error: special form tailcall expects function call expression."
|
1885
1968
|
end
|
1969
|
+
elsif Cell == sexp.car.class
|
1970
|
+
self.apply( translate( sexp.car, locals, sourceInfo ), sexp.cdr, sexp.car.car.sourcefile, sexp.car.car.lineno, locals, sourceInfo, EXEC_TYPE_ANONYMOUS )
|
1886
1971
|
else
|
1887
1972
|
self.apply( sexp.car, sexp.cdr, sexp.car.sourcefile, sexp.car.lineno, locals, sourceInfo, EXEC_TYPE_NORMAL )
|
1888
1973
|
end
|
@@ -1910,139 +1995,233 @@ module Nendo
|
|
1910
1995
|
"Nil.new"
|
1911
1996
|
when TrueClass, FalseClass, NilClass # reserved symbols
|
1912
1997
|
toRubyValue( sexp )
|
1998
|
+
when SyntacticClosure
|
1999
|
+
toRubySymbol( sexp )
|
1913
2000
|
else
|
1914
2001
|
sexp.to_s
|
1915
2002
|
end
|
1916
2003
|
end
|
1917
2004
|
end
|
1918
|
-
|
1919
|
-
|
1920
|
-
#
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
2005
|
+
|
2006
|
+
|
2007
|
+
# warp sexp by lexicalVars
|
2008
|
+
def __wrapNestedLet( sexp, lexicalVars )
|
2009
|
+
if 0 == lexicalVars.size
|
2010
|
+
sexp
|
2011
|
+
else
|
2012
|
+
elem = lexicalVars.shift
|
2013
|
+
Cell.new( :"%let",
|
2014
|
+
Cell.new(
|
2015
|
+
Cell.new(
|
2016
|
+
Cell.new( elem[0], elem[1] )),
|
2017
|
+
Cell.new( __wrapNestedLet( sexp, lexicalVars ) )))
|
2018
|
+
end
|
2019
|
+
end
|
2020
|
+
|
2021
|
+
def __removeSameLexicalScopeVariables( frame )
|
2022
|
+
frame.select {|x|
|
2023
|
+
# search same varname and different value
|
2024
|
+
found = frame.any? {|y|
|
2025
|
+
x[0] == y[0] and (not _equal_QUMARK( x[1], y[1] ))
|
2026
|
+
}
|
2027
|
+
if found
|
2028
|
+
x
|
2029
|
+
else
|
2030
|
+
false
|
2031
|
+
end
|
1931
2032
|
}
|
2033
|
+
end
|
2034
|
+
|
2035
|
+
def macroexpandInit( initVal )
|
2036
|
+
@macroExpandCount = initVal
|
2037
|
+
end
|
2038
|
+
|
2039
|
+
def macroexpandEngineLoop( sexp, syntaxArray, lexicalVars )
|
2040
|
+
converge = true
|
2041
|
+
begin
|
2042
|
+
newSexp = macroexpandEngine( sexp, syntaxArray, lexicalVars )
|
2043
|
+
converge = _equal_QUMARK( newSexp, sexp )
|
2044
|
+
sexp = newSexp
|
2045
|
+
end until converge or (@macroExpandCount <= 0)
|
1932
2046
|
sexp
|
1933
2047
|
end
|
1934
|
-
|
1935
|
-
def
|
1936
|
-
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
2048
|
+
|
2049
|
+
def macroexpandEngine( sexp, syntaxArray, lexicalVars )
|
2050
|
+
if @macroExpandCount <= 0
|
2051
|
+
sexp
|
2052
|
+
else
|
2053
|
+
__macroexpandEngine( sexp, syntaxArray, lexicalVars )
|
2054
|
+
end
|
2055
|
+
end
|
2056
|
+
|
2057
|
+
#
|
2058
|
+
# expand (syntax-rules ...) => (%syntax-rules ...)
|
2059
|
+
#
|
2060
|
+
def __expandSyntaxRules( rules, syntaxArray, lexicalVars )
|
2061
|
+
if :"%syntax-rules" == rules.car
|
2062
|
+
rules
|
2063
|
+
else
|
2064
|
+
ellipse = rules.second
|
2065
|
+
pattern_body_list = rules.cdr.cdr
|
2066
|
+
|
2067
|
+
lst = []
|
2068
|
+
lst << :"syntax-rules"
|
2069
|
+
lst << ellipse
|
2070
|
+
pattern_body_list.each {|xx|
|
2071
|
+
pattern_body = xx.car
|
2072
|
+
pattern = pattern_body.first
|
2073
|
+
body = pattern_body.second
|
2074
|
+
new_pattern_body = [ pattern, macroexpandEngine( body, syntaxArray, lexicalVars ) ].to_list
|
2075
|
+
lst << new_pattern_body
|
2076
|
+
}
|
2077
|
+
lst.to_list
|
2078
|
+
end
|
2079
|
+
end
|
2080
|
+
|
2081
|
+
# eval (syntax-rules ...) sexp
|
2082
|
+
#
|
2083
|
+
# return:
|
2084
|
+
# (%syntax-rules
|
2085
|
+
# ((v1 <<@syntaxHash's key1>>)
|
2086
|
+
# (v2 <<@syntaxHash's key2>>)
|
2087
|
+
# body))
|
2088
|
+
#
|
2089
|
+
# example:
|
2090
|
+
# (%syntax-rules
|
2091
|
+
# ((v1 "x = 10 // (+ x v1)")
|
2092
|
+
# (v2 "y = 20 // (+ y v2)"))
|
2093
|
+
# (+ v1 v2))
|
2094
|
+
#
|
2095
|
+
def __evalSyntaxRules( rules, lexicalVars )
|
2096
|
+
if :"%syntax-rules" == rules.car
|
2097
|
+
rules.second
|
2098
|
+
else
|
2099
|
+
lexvars = lexicalVars.select { |x|
|
2100
|
+
if _symbol_MIMARKinclude_QUMARK( rules, x[0].intern )
|
2101
|
+
x
|
2102
|
+
elsif lexicalVars.find {|y| _symbol_MIMARKinclude_QUMARK( y[1], x[0].intern ) }
|
2103
|
+
x
|
1989
2104
|
else
|
1990
|
-
|
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
|
2105
|
+
false
|
1997
2106
|
end
|
1998
|
-
|
2107
|
+
}
|
2108
|
+
|
2109
|
+
__setupLexicalScopeVariables( lexvars )
|
2110
|
+
keyStr = lexvars.map {|z|
|
2111
|
+
z[0].to_s + " / " + write_to_string( z[1] )
|
2112
|
+
}.join( " / " )
|
2113
|
+
keyStr += " // " + write_to_string( rules )
|
2114
|
+
if @syntaxHash.has_key?( keyStr )
|
2115
|
+
true
|
1999
2116
|
else
|
2000
|
-
|
2117
|
+
@syntaxHash[ keyStr ] = [ lexvars,
|
2118
|
+
self.lispEval( rules, "dynamic syntax-rules sexp (no source) ", 1 ) ]
|
2001
2119
|
end
|
2002
|
-
|
2003
|
-
|
2120
|
+
__setupLexicalScopeVariables( [] )
|
2121
|
+
keyStr
|
2004
2122
|
end
|
2005
2123
|
end
|
2006
|
-
|
2007
|
-
def macroexpandInit( initVal )
|
2008
|
-
@macroExpandCount = initVal
|
2009
|
-
end
|
2010
2124
|
|
2011
|
-
|
2125
|
+
# args:
|
2126
|
+
#
|
2127
|
+
# syntaxArray ... let-syntax's identifiers
|
2128
|
+
# [
|
2129
|
+
# [ identifier-name, key of @syntaxHash, sexp of (syntax-rules ...), frame_of_let-syntax ],
|
2130
|
+
# .
|
2131
|
+
# .
|
2132
|
+
# ]
|
2133
|
+
# lexicalVars ... let's identifiers
|
2134
|
+
# [
|
2135
|
+
# [ identifier-name, macroexpandEngine( let's body ) ],
|
2136
|
+
# ]
|
2137
|
+
#
|
2138
|
+
#
|
2139
|
+
def __macroexpandEngine( sexp, syntaxArray, lexicalVars )
|
2012
2140
|
case sexp
|
2013
2141
|
when Cell
|
2014
2142
|
car = sexp.car
|
2015
2143
|
if :quote == car or :"syntax-quote" == car or @core_syntax_hash[ :quote ] == car or @core_syntax_hash[ :"syntax-quote" ] == car
|
2016
2144
|
sexp
|
2145
|
+
elsif :"%let" == car or :letrec == car or @core_syntax_hash[ :"%let" ] == car or @core_syntax_hash[ :letrec ] == car
|
2146
|
+
# catch lexical identifiers of `let' and `letrec'.
|
2147
|
+
arr = sexp.second.map { |x|
|
2148
|
+
[ x.car.car, macroexpandEngine( x.car.cdr, syntaxArray, lexicalVars ) ]
|
2149
|
+
}
|
2150
|
+
lst = arr.map {|x| Cell.new( x[0], x[1] ) }.to_list
|
2151
|
+
ret = Cell.new( car,
|
2152
|
+
Cell.new( lst,
|
2153
|
+
macroexpandEngine( sexp.cdr.cdr, syntaxArray, lexicalVars + arr )))
|
2154
|
+
ret
|
2155
|
+
elsif :"let-syntax" == car
|
2156
|
+
sexp.second.each {|x|
|
2157
|
+
if not x.car.second.is_a? Cell
|
2158
|
+
raise SyntaxError, "Error: let-syntax get only '((name (syntax-rules ...)))' form but got: " + write_to_string( x )
|
2159
|
+
elsif not ( x.car.second.first == :"syntax-rules" or x.car.second.first == :"%syntax-rules")
|
2160
|
+
raise SyntaxError, "Error: let-syntax get only '((name (syntax-rules ...)))' form but got: " + write_to_string( x )
|
2161
|
+
end
|
2162
|
+
}
|
2163
|
+
arr_tmp = sexp.second.map { |x|
|
2164
|
+
[ x.car.first, __expandSyntaxRules( x.car.second, syntaxArray, lexicalVars ) ]
|
2165
|
+
}
|
2166
|
+
arr = arr_tmp.map {|x|
|
2167
|
+
[ x[0], __evalSyntaxRules( x[1], lexicalVars ), x[1], lexicalVars ]
|
2168
|
+
}
|
2169
|
+
|
2170
|
+
# trial (expand recursively)
|
2171
|
+
arr_tmp = arr.map { |x|
|
2172
|
+
[ x[0], __expandSyntaxRules( x[2], syntaxArray + arr, lexicalVars ) ]
|
2173
|
+
}
|
2174
|
+
arr = arr_tmp.map {|x|
|
2175
|
+
[ x[0], __evalSyntaxRules( x[1], lexicalVars ), x[1], lexicalVars ]
|
2176
|
+
}
|
2177
|
+
|
2178
|
+
# keywords = ((let-syntax-keyword ( let-syntax-body ))
|
2179
|
+
# (let-syntax-keyword ( let-syntax-body ))
|
2180
|
+
# ..)
|
2181
|
+
newKeywords = arr.map { |e|
|
2182
|
+
[ e[0], [ :"%syntax-rules", e[1]].to_list ].to_list
|
2183
|
+
}.to_list
|
2184
|
+
|
2185
|
+
ret = Cell.new( :"let-syntax",
|
2186
|
+
Cell.new( newKeywords, macroexpandEngine( sexp.cdr.cdr, syntaxArray + arr, lexicalVars )))
|
2187
|
+
|
2188
|
+
ret
|
2017
2189
|
else
|
2018
|
-
sym =
|
2019
|
-
p 'macroexpandEngine' if @debug
|
2020
|
-
p sexp.car.class if @debug
|
2021
|
-
p sym if @debug
|
2022
|
-
sym = toRubySymbol( sym )
|
2190
|
+
sym = toRubySymbol( car.to_s )
|
2023
2191
|
newSexp = sexp
|
2024
2192
|
if isRubyInterface( sym )
|
2025
2193
|
# do nothing
|
2026
2194
|
sexp
|
2027
|
-
elsif
|
2195
|
+
elsif _symbol_QUMARK( car ) and eval( sprintf( "(defined? @%s and LispMacro == @%s.class)", sym,sym ), @binding )
|
2028
2196
|
eval( sprintf( "@__macro = @%s", sym ), @binding )
|
2029
2197
|
newSexp = trampCall( callProcedure( sym, @__macro, sexp.cdr.to_arr ))
|
2030
|
-
elsif
|
2198
|
+
elsif _symbol_QUMARK( car ) and eval( sprintf( "(defined? @%s and LispSyntax == @%s.class)", sym,sym ), @binding )
|
2031
2199
|
# expected input is
|
2032
2200
|
# (syntaxName arg1 arg2 ...)
|
2033
2201
|
# will be transformed
|
2034
2202
|
# (syntaxName (syntaxName arg1 arg2 ...) () (global-variables))
|
2035
2203
|
eval( sprintf( "@__syntax = @%s", sym ), @binding )
|
2036
2204
|
newSexp = trampCall( callProcedure( sym, @__syntax, [ sexp, Cell.new(), _global_MIMARKvariables( ) ] ))
|
2205
|
+
elsif _symbol_QUMARK( car ) and syntaxArray.map {|arr| arr[0].intern}.include?( car.intern )
|
2206
|
+
# lexical macro expandeding
|
2207
|
+
symbol_and_syntaxObj = syntaxArray.reverse.find {|arr| car == arr[0]}
|
2208
|
+
keys = syntaxArray.reverse.map { |arr| arr[0] }
|
2209
|
+
if not symbol_and_syntaxObj
|
2210
|
+
raise "can't find valid syntaxObject"
|
2211
|
+
end
|
2212
|
+
vars = symbol_and_syntaxObj[3].map { |arr| arr[0] }
|
2213
|
+
lexvars = @syntaxHash[ symbol_and_syntaxObj[1] ][0]
|
2214
|
+
lispSyntax = @syntaxHash[ symbol_and_syntaxObj[1] ][1]
|
2215
|
+
newSexp = trampCall( callProcedure( symbol_and_syntaxObj[0], lispSyntax, [
|
2216
|
+
sexp,
|
2217
|
+
Cell.new(),
|
2218
|
+
(_global_MIMARKvariables( ).to_arr + keys + vars).to_list ] ))
|
2219
|
+
newSexp = __wrapNestedLet( newSexp, __removeSameLexicalScopeVariables( lexicalVars + lexvars ))
|
2037
2220
|
end
|
2038
2221
|
if _equal_QUMARK( newSexp, sexp )
|
2039
2222
|
sexp.map { |x|
|
2040
2223
|
if x.car.is_a? Cell
|
2041
|
-
|
2042
|
-
macroexpandEngine( x.car )
|
2043
|
-
else
|
2044
|
-
x.car
|
2045
|
-
end
|
2224
|
+
macroexpandEngine( x.car, syntaxArray, lexicalVars )
|
2046
2225
|
else
|
2047
2226
|
x.car
|
2048
2227
|
end
|
@@ -2056,18 +2235,14 @@ module Nendo
|
|
2056
2235
|
sexp
|
2057
2236
|
end
|
2058
2237
|
end
|
2059
|
-
|
2060
|
-
def
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
|
2065
|
-
converge = _equal_QUMARK( newSexp, sexp )
|
2066
|
-
sexp = newSexp
|
2067
|
-
end until converge
|
2068
|
-
sexp
|
2238
|
+
|
2239
|
+
def macroexpandPhase( sexp )
|
2240
|
+
macroexpandInit( 100000 )
|
2241
|
+
_strip_MIMARKlet_MIMARKsyntax_MIMARKkeyword(
|
2242
|
+
_strip_MIMARKsyntax_MIMARKquote(
|
2243
|
+
macroexpandEngineLoop( sexp, [], [] )))
|
2069
2244
|
end
|
2070
|
-
|
2245
|
+
|
2071
2246
|
def ppRubyExp( level, exp )
|
2072
2247
|
indent = @indent * level
|
2073
2248
|
exp.map { |x|
|
@@ -2083,7 +2258,7 @@ module Nendo
|
|
2083
2258
|
end
|
2084
2259
|
}
|
2085
2260
|
end
|
2086
|
-
|
2261
|
+
|
2087
2262
|
def displayTopOfCalls( exception )
|
2088
2263
|
STDERR.puts( "\n <<< Top of calls >>>" )
|
2089
2264
|
strs = []
|
@@ -2096,29 +2271,31 @@ module Nendo
|
|
2096
2271
|
STDERR.puts( str )
|
2097
2272
|
}
|
2098
2273
|
end
|
2099
|
-
|
2274
|
+
|
2100
2275
|
def lispEval( sexp, sourcefile, lineno )
|
2101
2276
|
begin
|
2102
2277
|
sourceInfo = SourceInfo.new
|
2103
2278
|
@lastSourcefile = sourcefile
|
2104
2279
|
@lastLineno = lineno
|
2105
2280
|
sourceInfo.setSource( sourcefile, lineno, sexp )
|
2106
|
-
|
2107
|
-
|
2281
|
+
|
2282
|
+
# macro expand phase
|
2283
|
+
sexp = macroexpandPhase( sexp )
|
2108
2284
|
if @debug
|
2109
|
-
printf( "\n
|
2285
|
+
printf( "\n expaneded=<<< %s >>>\n", (Printer.new())._print(sexp))
|
2110
2286
|
end
|
2111
|
-
|
2287
|
+
|
2288
|
+
# compiling phase written
|
2112
2289
|
sym = toRubySymbol( "%compile-phase" )
|
2113
2290
|
if ( eval( sprintf( "(defined? @%s and Proc == @%s.class)", sym,sym ), @binding ))
|
2114
2291
|
eval( sprintf( "@___tmp = @%s", sym ), @binding )
|
2115
2292
|
sexp = trampCall( callProcedure( sym, @___tmp, [ sexp ]))
|
2116
2293
|
if @debug
|
2117
|
-
printf( "\n compiled
|
2294
|
+
printf( "\n compiled= <<< %s >>>\n", (Printer.new())._print(sexp))
|
2118
2295
|
end
|
2119
2296
|
end
|
2120
2297
|
sourceInfo.setExpanded( sexp )
|
2121
|
-
|
2298
|
+
|
2122
2299
|
arr = [ "trampCall( ", translate( sexp, [], sourceInfo ), " )" ]
|
2123
2300
|
rubyExp = ppRubyExp( 0, arr ).flatten.join
|
2124
2301
|
sourceInfo.setCompiled( rubyExp )
|
@@ -2154,23 +2331,23 @@ module Nendo
|
|
2154
2331
|
}
|
2155
2332
|
forward_gensym_counter()
|
2156
2333
|
end
|
2157
|
-
|
2334
|
+
|
2158
2335
|
def _load_MIMARKcompiled_MIMARKcode_MIMARKfrom_MIMARKstring( rubyExp )
|
2159
2336
|
eval( rubyExp, @binding )
|
2160
2337
|
forward_gensym_counter()
|
2161
2338
|
end
|
2162
|
-
|
2339
|
+
|
2163
2340
|
def __PAMARKload_MIMARKcompiled_MIMARKcode( filename )
|
2164
2341
|
open( filename, "r:utf-8" ) { |f|
|
2165
2342
|
eval( f.read, @binding )
|
2166
2343
|
}
|
2167
2344
|
forward_gensym_counter()
|
2168
2345
|
end
|
2169
|
-
|
2346
|
+
|
2170
2347
|
def _clean_MIMARKcompiled_MIMARKcode
|
2171
2348
|
@compiled_code = Hash.new
|
2172
2349
|
end
|
2173
|
-
|
2350
|
+
|
2174
2351
|
def _get_MIMARKcompiled_MIMARKcode
|
2175
2352
|
@compiled_code
|
2176
2353
|
ret = Hash.new
|
@@ -2180,11 +2357,11 @@ module Nendo
|
|
2180
2357
|
}
|
2181
2358
|
ret.to_list
|
2182
2359
|
end
|
2183
|
-
|
2360
|
+
|
2184
2361
|
def _eval( sexp )
|
2185
2362
|
self.lispEval( sexp, "dynamic S-expression ( no source )", 1 )
|
2186
2363
|
end
|
2187
|
-
|
2364
|
+
|
2188
2365
|
def _enable_MIMARKidebug()
|
2189
2366
|
@debug = true
|
2190
2367
|
end
|
@@ -2246,21 +2423,116 @@ module Nendo
|
|
2246
2423
|
true
|
2247
2424
|
end
|
2248
2425
|
|
2426
|
+
def __setupLexicalScopeVariables( lexicalVars )
|
2427
|
+
@lexicalVars = lexicalVars.clone
|
2428
|
+
end
|
2429
|
+
|
2249
2430
|
def _make_MIMARKsyntactic_MIMARKclosure( mac_env, use_env, identifier )
|
2250
2431
|
if _pair_QUMARK( identifier )
|
2251
|
-
|
2252
|
-
else
|
2253
|
-
if mac_env.to_arr.include?( identifier )
|
2432
|
+
if :"syntax-quote" == identifier.car
|
2254
2433
|
identifier
|
2255
2434
|
else
|
2256
|
-
|
2257
|
-
sym.intern
|
2435
|
+
raise TypeError, "make-syntactic-closure requires symbol or (syntax-quote sexp) only. but got: " + write_to_string( identifier )
|
2258
2436
|
end
|
2437
|
+
elsif _symbol_QUMARK( identifier )
|
2438
|
+
# pp [ "identifier: ", identifier, "include?=", mac_env.to_arr.include?( identifier.intern ) ]
|
2439
|
+
# pp [ "mac_env: ", mac_env.to_arr ]
|
2440
|
+
if mac_env.to_arr.include?( identifier.intern )
|
2441
|
+
found = @lexicalVars.find { |x| identifier == x[0] }
|
2442
|
+
if found
|
2443
|
+
lexvars = @lexicalVars.clone
|
2444
|
+
__wrapNestedLet( identifier, lexvars )
|
2445
|
+
else
|
2446
|
+
identifier
|
2447
|
+
end
|
2448
|
+
else
|
2449
|
+
SyntacticClosure.new( identifier, (toRubySymbol( identifier ) + _gensym( ).to_s).intern )
|
2450
|
+
end
|
2451
|
+
else
|
2452
|
+
raise TypeError, "make-syntactic-closure requires symbol or (syntax-quote sexp) type."
|
2453
|
+
end
|
2454
|
+
end
|
2455
|
+
|
2456
|
+
def _strip_MIMARKsyntax_MIMARKquote( sexp )
|
2457
|
+
case sexp
|
2458
|
+
when Cell
|
2459
|
+
if _null_QUMARK( sexp )
|
2460
|
+
sexp
|
2461
|
+
else
|
2462
|
+
car = sexp.car
|
2463
|
+
if :"syntax-quote" == car or @core_syntax_hash[ :"syntax-quote" ] == car
|
2464
|
+
Cell.new( :quote, sexp.cdr )
|
2465
|
+
else
|
2466
|
+
Cell.new(
|
2467
|
+
_strip_MIMARKsyntax_MIMARKquote( sexp.car ),
|
2468
|
+
_strip_MIMARKsyntax_MIMARKquote( sexp.cdr ))
|
2469
|
+
end
|
2470
|
+
end
|
2471
|
+
else
|
2472
|
+
sexp
|
2473
|
+
end
|
2474
|
+
end
|
2475
|
+
|
2476
|
+
def _strip_MIMARKlet_MIMARKsyntax_MIMARKkeyword( sexp )
|
2477
|
+
case sexp
|
2478
|
+
when Cell
|
2479
|
+
if _null_QUMARK( sexp )
|
2480
|
+
sexp
|
2481
|
+
else
|
2482
|
+
car = sexp.car
|
2483
|
+
if :"quote" == car or @core_syntax_hash[ :"quote" ] == car
|
2484
|
+
sexp
|
2485
|
+
elsif :"let-syntax" == car or @core_syntax_hash[ :"let-syntax" ] == car
|
2486
|
+
Cell.new( :begin,
|
2487
|
+
_strip_MIMARKlet_MIMARKsyntax_MIMARKkeyword( sexp.cdr.cdr ))
|
2488
|
+
else
|
2489
|
+
Cell.new(
|
2490
|
+
_strip_MIMARKlet_MIMARKsyntax_MIMARKkeyword( sexp.car ),
|
2491
|
+
_strip_MIMARKlet_MIMARKsyntax_MIMARKkeyword( sexp.cdr ))
|
2492
|
+
end
|
2493
|
+
end
|
2494
|
+
else
|
2495
|
+
sexp
|
2259
2496
|
end
|
2260
2497
|
end
|
2261
2498
|
|
2499
|
+
def _strip_MIMARKsyntactic_MIMARKclosures( sexp )
|
2500
|
+
case sexp
|
2501
|
+
when Cell
|
2502
|
+
if _null_QUMARK( sexp )
|
2503
|
+
sexp
|
2504
|
+
else
|
2505
|
+
Cell.new(
|
2506
|
+
_strip_MIMARKsyntactic_MIMARKclosures( sexp.car ),
|
2507
|
+
_strip_MIMARKsyntactic_MIMARKclosures( sexp.cdr ))
|
2508
|
+
end
|
2509
|
+
else
|
2510
|
+
if sexp.is_a? SyntacticClosure
|
2511
|
+
sexp.intern
|
2512
|
+
else
|
2513
|
+
sexp
|
2514
|
+
end
|
2515
|
+
end
|
2516
|
+
end
|
2517
|
+
|
2518
|
+
def _symbol_MIMARKinclude_QUMARK( sexp, sym )
|
2519
|
+
case sexp
|
2520
|
+
when Cell
|
2521
|
+
if _null_QUMARK( sexp )
|
2522
|
+
false
|
2523
|
+
else
|
2524
|
+
_symbol_MIMARKinclude_QUMARK( sexp.car, sym ) or _symbol_MIMARKinclude_QUMARK( sexp.cdr, sym )
|
2525
|
+
end
|
2526
|
+
else
|
2527
|
+
if _symbol_QUMARK( sexp )
|
2528
|
+
sym.intern == sexp.intern
|
2529
|
+
else
|
2530
|
+
false
|
2531
|
+
end
|
2532
|
+
end
|
2533
|
+
end
|
2262
2534
|
end
|
2263
|
-
|
2535
|
+
|
2264
2536
|
class Printer
|
2265
2537
|
def initialize( debug = false )
|
2266
2538
|
@debug = debug
|
@@ -2269,14 +2541,6 @@ module Nendo
|
|
2269
2541
|
def __write( sexp, readable )
|
2270
2542
|
getQuoteKeyword = lambda { |x|
|
2271
2543
|
case x
|
2272
|
-
when :quote
|
2273
|
-
"'"
|
2274
|
-
when :quasiquote
|
2275
|
-
"`"
|
2276
|
-
when :unquote
|
2277
|
-
","
|
2278
|
-
when :"unquote-splicing"
|
2279
|
-
",@"
|
2280
2544
|
when :"dot-operator"
|
2281
2545
|
"."
|
2282
2546
|
else
|
@@ -2314,6 +2578,8 @@ module Nendo
|
|
2314
2578
|
else
|
2315
2579
|
sexp.to_s
|
2316
2580
|
end
|
2581
|
+
when SyntacticClosure
|
2582
|
+
sprintf( "#<SyntacticClosure[%s:%s]>", sexp.originalSymbol, sexp.renamedSymbol )
|
2317
2583
|
when Regexp
|
2318
2584
|
"#/" + sexp.source + "/" + (sexp.casefold? ? "i" : "")
|
2319
2585
|
when LispKeyword
|
@@ -2344,9 +2610,11 @@ module Nendo
|
|
2344
2610
|
end
|
2345
2611
|
|
2346
2612
|
def self.version
|
2347
|
-
"0.5.
|
2613
|
+
"0.5.1" ##NENDO-VERSION
|
2348
2614
|
end
|
2349
|
-
|
2615
|
+
|
2616
|
+
attr_reader :evaluator
|
2617
|
+
|
2350
2618
|
def loadInitFile( use_compiled = true )
|
2351
2619
|
done = false
|
2352
2620
|
if use_compiled
|
@@ -2477,3 +2745,4 @@ class Hash
|
|
2477
2745
|
arr.to_list
|
2478
2746
|
end
|
2479
2747
|
end
|
2748
|
+
|