nendo 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/nendo.rb CHANGED
@@ -1,11 +1,41 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- encoding: utf-8 -*-
3
3
  #
4
- # Nendo: "Nendo is a diarect of Lisp."
4
+ # nendo.rb - "language core of nendo"
5
5
  #
6
- #
6
+ # Copyright (c) 2000-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
+ # $Id:
7
36
  #
8
37
  require 'stringio'
38
+ #require 'profile'
9
39
 
10
40
  class Nil
11
41
  include Enumerable
@@ -903,6 +933,9 @@ module BuiltinFunctions
903
933
  end
904
934
 
905
935
  def _hash_MIMARKtable_MIMARKget( h, key, *args )
936
+ if !((key.is_a? String) or ( key.is_a? Symbol))
937
+ raise TypeError, "Error: argument key requires String or Symbol.\n"
938
+ end
906
939
  if h.has_key?( key )
907
940
  h[key]
908
941
  else
@@ -916,11 +949,23 @@ module BuiltinFunctions
916
949
  end
917
950
 
918
951
  def _hash_MIMARKtable_MIMARKput_EXMARK( h, key, value )
952
+ if !((key.is_a? String) or ( key.is_a? Symbol))
953
+ raise TypeError, "Error: argument key requires String or Symbol.\n"
954
+ end
919
955
  h[key] = value
920
956
  end
921
957
 
922
- def _raise( exception, message )
923
- raise exception, message
958
+ # backtrace expects this format "filename:lineno: place message ". e.g. "init.nnd:10: in aaa macro.".
959
+ def _raise( exception, message, backtrace )
960
+ raise exception, message, [ backtrace ]
961
+ end
962
+
963
+ def __ASMARKLINE_ASMARK()
964
+ @lastLineno
965
+ end
966
+
967
+ def __ASMARKFILE_ASMARK()
968
+ @lastSourcefile
924
969
  end
925
970
  end
926
971
 
@@ -956,10 +1001,14 @@ class Evaluator
956
1001
  }
957
1002
  @char_table_ruby_to_lisp = @char_table_lisp_to_ruby.invert
958
1003
 
1004
+ # toplevel binding
1005
+ @global_lisp_binding = Hash.new
1006
+
959
1007
  # built-in functions
960
1008
  self.methods.grep( /^_/ ) { |rubySymbol|
961
1009
  @___tmp = self.method( rubySymbol )
962
- eval( sprintf( "@%s = @___tmp", rubySymbol ), @binding )
1010
+ eval( sprintf( "@%s = @___tmp;", rubySymbol ), @binding )
1011
+ eval( sprintf( "@global_lisp_binding['%s'] = true;", rubySymbol ), @binding )
963
1012
  }
964
1013
 
965
1014
  # initialize buildin functions as Proc objects
@@ -1101,7 +1150,12 @@ class Evaluator
1101
1150
  ar = args.cdr.map { |x| x.car }
1102
1151
  variable_sym = toRubySymbol( args.car.to_s.sub( /^:/, "" ))
1103
1152
  global_cap = locals.flatten.include?( variable_sym.split( /[.]/ )[0] ) ? nil : "@"
1104
- [ sprintf( "%s%s = ", global_cap, variable_sym ), ar ]
1153
+ [ "begin",
1154
+ [
1155
+ sprintf( "@global_lisp_binding['%s'] = true", variable_sym ),
1156
+ sprintf( "%s%s = ", global_cap, variable_sym ),
1157
+ ar ],
1158
+ "end" ]
1105
1159
  when :error
1106
1160
  [
1107
1161
  'begin raise RuntimeError, ',
@@ -1318,7 +1372,7 @@ class Evaluator
1318
1372
  end
1319
1373
  if global_cap
1320
1374
  ["begin",
1321
- [sprintf( 'if (self.instance_variables.include?(:@%s)) then', variable_sym ),
1375
+ [sprintf( "if @global_lisp_binding.has_key?('%s') then", variable_sym ),
1322
1376
  expression,
1323
1377
  sprintf( 'else raise NameError.new( "Error: undefined variable %s", "%s" ) end', variable_sym, variable_sym ),
1324
1378
  sprintf( 'rescue => __e ; __e.set_backtrace( ["%s:%d"] + __e.backtrace ) ; raise __e', sourcefile, lineno )],
@@ -1493,11 +1547,43 @@ class Evaluator
1493
1547
  @expand_flag = true
1494
1548
  macroexpand_1_check( sexp )
1495
1549
  end
1496
-
1550
+
1551
+ def macroexpand( sexp )
1552
+ case sexp
1553
+ when Cell
1554
+ if :quote == sexp.car
1555
+ sexp
1556
+ else
1557
+ sym = sexp.car.to_s
1558
+ sym = toRubySymbol( sym )
1559
+ newSexp = sexp
1560
+ if isRubyInterface( sym )
1561
+ # do nothing
1562
+ elsif sexp.car.class == Symbol and eval( sprintf( "(defined? @%s and LispMacro == @%s.class)", sym,sym ), @binding )
1563
+ eval( sprintf( "@__macro = @%s", sym ), @binding )
1564
+ newSexp = callProcedure( sym, @__macro, sexp.cdr )
1565
+ end
1566
+ if _equal_QUMARK( newSexp, sexp )
1567
+ sexp.map { |x|
1568
+ if x.car.is_a? Cell
1569
+ macroexpand( x.car )
1570
+ else
1571
+ x.car
1572
+ end
1573
+ }.to_list( sexp.lastAtom )
1574
+ else
1575
+ newSexp
1576
+ end
1577
+ end
1578
+ else
1579
+ sexp
1580
+ end
1581
+ end
1582
+
1497
1583
  def lispCompile( sexp )
1498
1584
  converge = true
1499
1585
  begin
1500
- newSexp = macroexpand_1( sexp )
1586
+ newSexp = macroexpand( sexp )
1501
1587
  converge = _equal_QUMARK( newSexp, sexp )
1502
1588
  sexp = newSexp
1503
1589
  end until converge
@@ -1521,6 +1607,8 @@ class Evaluator
1521
1607
  end
1522
1608
 
1523
1609
  def lispEval( sexp, sourcefile, lineno )
1610
+ @lastSourcefile = sourcefile
1611
+ @lastLineno = lineno
1524
1612
  sexp = lispCompile( sexp )
1525
1613
  sexp = quoting( sexp );
1526
1614
  if @debug
@@ -1533,7 +1621,7 @@ class Evaluator
1533
1621
  end
1534
1622
  @compiled_code[ sourcefile ] << rubyExp
1535
1623
  printf( " rubyExp=<<<\n%s\n>>>\n", rubyExp ) if @debug
1536
- eval( rubyExp, @binding, sourcefile, lineno );
1624
+ eval( rubyExp, @binding, @lastSourcefile, @lastLineno )
1537
1625
  end
1538
1626
 
1539
1627
  def _load( filename )
@@ -1551,6 +1639,7 @@ class Evaluator
1551
1639
  end
1552
1640
  end
1553
1641
  }
1642
+ forward_gensym_counter()
1554
1643
  end
1555
1644
 
1556
1645
  def _load_MIMARKcompiled_MIMARKcode( filename )
@@ -1,5 +1,6 @@
1
+ ;;-*- mode: nendo; syntax: scheme -*-;;
1
2
  ;;;
2
- ;;; html-lite.scm - lightweight HTML construction
3
+ ;;; html-lite.nnd - lightweight HTML construction
3
4
  ;;;
4
5
  ;;; Copyright (c) 2000-2009 Shiro Kawai <shiro@acm.org>
5
6
  ;;;
@@ -30,7 +31,7 @@
30
31
  ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
32
  ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33
  ;;;
33
- ;;; $Id: html-lite.scm,v 1.19 2008-05-10 13:36:11 shirok Exp $
34
+ ;;; $Id:
34
35
  ;;;
35
36
  ;;;
36
37
  ;;; ported for Nendo language by Kiyoka Nishiyama.