[e-cvs] cvs commit: e/src/jsrc/org/erights/e/elib/tables EmptyTwine.java CompositeTwine.java Equalizer.java IdentityCacheTable.java LocatedTwine.java SimpleTwine.java Twine.java

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Tue, 4 Sep 2001 06:52:19 -0400


markm       01/09/04 06:52:19

  Modified:    src      Makefile
               src/bin/resources/org/erights/e/elang/syntax
                        ParserTables.data
               src/jsrc/org/erights/e/develop/exception ThrowableSugar.java
               src/jsrc/org/erights/e/elang/syntax ELexer.java EParser.java
                        FileFeeder.java Indenter.java SyntaxException.java
                        Token.java e.y
               src/jsrc/org/erights/e/elib/base Printable.java
               src/jsrc/org/erights/e/elib/prim MirandaMethods.java
                        Thrower.java
               src/jsrc/org/erights/e/elib/tables CompositeTwine.java
                        Equalizer.java IdentityCacheTable.java
                        LocatedTwine.java SimpleTwine.java Twine.java
  Added:       src/jsrc/org/erights/e/elib/tables EmptyTwine.java
  Log:
  good highlighting of syntax errors

Revision  Changes    Path
1.113     +2 -2      e/src/Makefile

Index: Makefile
===================================================================
RCS file: /cvs/e/src/Makefile,v
retrieving revision 1.112
retrieving revision 1.113
diff -u -r1.112 -r1.113
--- Makefile	2001/09/03 18:20:17	1.112
+++ Makefile	2001/09/04 10:52:17	1.113
@@ -7,8 +7,8 @@
 
 # Prefix tagging this release's attributes
 PREFIX=tl-E
-DOTVER=0.8.9zj
-TAGVER=0_8_9zj
+DOTVER=0.8.9zk
+TAGVER=0_8_9zk
 RELEASE=working
 
 TOP=..



1.18      +14 -15    e/src/bin/resources/org/erights/e/elang/syntax/ParserTables.data

Index: ParserTables.data
===================================================================
RCS file: /cvs/e/src/bin/resources/org/erights/e/elang/syntax/ParserTables.data,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
Binary files /tmp/cvsLWpHra and /tmp/cvs4LFbRc differ



1.9       +33 -33    e/src/jsrc/org/erights/e/develop/exception/ThrowableSugar.java

Index: ThrowableSugar.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/develop/exception/ThrowableSugar.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- ThrowableSugar.java	2001/08/17 20:59:26	1.8
+++ ThrowableSugar.java	2001/09/04 10:52:17	1.9
@@ -1,20 +1,20 @@
 package org.erights.e.develop.exception;
 
 /*
-The contents of this file are subject to the Electric Communities E Open 
-Source Code License Version 1.0 (the "License"); you may not use this file 
-except in compliance with the License. You may obtain a copy of the License 
+The contents of this file are subject to the Electric Communities E Open
+Source Code License Version 1.0 (the "License"); you may not use this file
+except in compliance with the License. You may obtain a copy of the License
 at http://www.communities.com/EL/.
 
-Software distributed under the License is distributed on an "AS IS" basis, 
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 the specific language governing rights and limitations under the License.
 
-The Original Code is the Distributed E Language Implementation, released 
-July 20, 1998. 
+The Original Code is the Distributed E Language Implementation, released
+July 20, 1998.
 
-The Initial Developer of the Original Code is Electric Communities.  
-Copyright (C) 1998 Electric Communities. All Rights Reserved. 
+The Initial Developer of the Original Code is Electric Communities.
+Copyright (C) 1998 Electric Communities. All Rights Reserved.
 
 Contributor(s): ______________________________________.
 */
@@ -33,38 +33,38 @@
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
 public class ThrowableSugar {
-    
+
     /** the standard "problem: " prefix */
     static public final String ProblemPrefix = "problem: ";
-    
+
     /** Same number of spaces as in the ProblemPrefix */
-    static public final String ProblemIndent = 
+    static public final String ProblemIndent =
         StringHelper.multiply(" ", ProblemPrefix.length());
 
     /** prevents instantiation */
     private ThrowableSugar() {}
-    
+
     /**
      * In general, a Throwable prints as 'problem: <type: msg>'.
      * <p>
-     * If the msg is null, then prints as just 'problem: <type>'.  If msg 
-     * contains multiple lines, the remaining lines are indented to line up 
+     * If the msg is null, then prints as just 'problem: <type>'.  If msg
+     * contains multiple lines, the remaining lines are indented to line up
      * with the "<type:...".
      * <p>
-     * If self is an instance of RuntimeException, but not of any subclass of 
-     * RuntimeException, then it prints as 'problem: msg' (since the type 
-     * RuntimeException isn't interesting).  This behavior really should be 
-     * in a separate RuntimeExceptionSugar class, but is placed here to avoid 
-     * creating that sugar class for this only this purpose.
+     * If self is an instance of RuntimeException, but not of any subclass of
+     * RuntimeException, then it prints as 'problem: msg' (since the type
+     * RuntimeException isn't interesting).  This behavior really should be
+     * in a separate RuntimeExceptionSugar class, but is placed here to avoid
+     * creating that sugar class for only this purpose.
      * <p>
-     * This really should be 'printOn', but because of layering issues, we 
+     * This really should be 'printOn', but because of layering issues, we
      * rename it and make a special case in the MirandaMethods.printOn().
      */
     static public void printThrowableOn(Throwable self, Writer out)
     throws IOException {
         PrintWriter pw = new PrintWriter(out);
         pw.print(ProblemPrefix);
-        
+
         self = leaf(self);
         Class type = self.getClass();
         String optMsg = self.getMessage();
@@ -84,9 +84,9 @@
             pw.print(">");
         }
     }
-    
+
     /**
-     * Returns the Throwable wrapped by self.  If self doesn't wrap a Throwable, 
+     * Returns the Throwable wrapped by self.  If self doesn't wrap a Throwable,
      * return null.
      */
     static public Throwable unwrap(Throwable self) {
@@ -103,7 +103,7 @@
             return null;
         }
     }
-    
+
     /**
      * Return the non-wrapping throwable at the end of a wrapping chain
      */
@@ -116,10 +116,10 @@
             self = sub;
         }
     }
-    
+
     /**
-     * Returns the backtrace annotations wrapping the leaf exception, one per 
-     * line.  Empty backtrace annotations are skipped.  
+     * Returns the backtrace annotations wrapping the leaf exception, one per
+     * line.  Empty backtrace annotations are skipped.
      * Each line is *preceded* by a newline.
      */
     static public String eStack(Throwable self) {
@@ -136,9 +136,9 @@
             self = sub;
         }
     }
-    
+
     /**
-     * Returns self annotated by `*** $optMsg`.  optMsg may equivalently be 
+     * Returns self annotated by `*** $optMsg`.  optMsg may equivalently be
      * null or "", in which case it will be ignored by eStack().
      */
     static public RuntimeException backtrace(Throwable self, String optMsg) {
@@ -153,15 +153,15 @@
         }
         return new NestedException(optMsg, self);
     }
-    
+
     /**
      *
      */
-    static private final String LINE_SEP 
+    static private final String LINE_SEP
         = System.getProperty("line.separator");
 
     /**
-     * Returns the java backtrace stack of the leaf throwable with all 
+     * Returns the java backtrace stack of the leaf throwable with all
      * newlines as '\n's.
      */
     static public String javaStack(Throwable self) {



1.47      +76 -43    e/src/jsrc/org/erights/e/elang/syntax/ELexer.java

Index: ELexer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/ELexer.java,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- ELexer.java	2001/09/03 18:20:18	1.46
+++ ELexer.java	2001/09/04 10:52:17	1.47
@@ -39,7 +39,7 @@
     /**
      *
      */
-    static public final int EOF = -1;
+    static public final int EOFCHAR = -1;
 
     /**
      *
@@ -58,7 +58,7 @@
     /** position in current line of candidate character */
     private int myPos;
 
-    /** the candidate character, or EOF for end-of-file. */
+    /** the candidate character, or EOFCHAR for end-of-file. */
     private int myChar;
 
     /**
@@ -190,7 +190,7 @@
      */
     private void nextLine() throws IOException {
         if (myLTwine == null) {
-            myChar = EOF;
+            myChar = EOFCHAR;
             return;
         }
         if (-1 == myOptStartPos) {
@@ -233,7 +233,7 @@
     private void nextChar() throws IOException {
         while (true) {
             if (null == myLTwine) {
-                myChar = EOF;
+                myChar = EOFCHAR;
                 return;
             }
             myPos++;
@@ -258,9 +258,18 @@
             myOptStartPos = -1;
             myOptStartText = null;
         }
-        if (EParser.isContinuer(result.tokenType()) &&
-                isWhite(myPos, myLData.length))
-        {
+        if (EParser.isContinuer(result.tokenType())) {
+            return continuer(result);
+        } else {
+            return result;
+        }
+    }
+
+    /**
+     * Separated out for use by '>'
+     */
+    private Token continuer(Token result) throws IOException {
+        if (isWhite(myPos, myLData.length)) {
             myContinueFlag = true;
             skipLine();
         }
@@ -321,7 +330,7 @@
      */
     private void skipWhiteSpace() throws IOException {
         while (true) {
-            if (myChar == EOF) {
+            if (myChar == EOFCHAR) {
                 return;
             }
             if (Character.isWhitespace((char)myChar)) {
@@ -385,8 +394,8 @@
         startToken();
 
         switch(myChar) {
-            case EOF: {
-                return new Token(Twine.fromString(""), EParser.EOF);
+            case EOFCHAR: {
+                return new Token(Twine.fromString(""), EParser.EOFTOK);
             } case '\n': {
                 myDelayedNextChar = true;
                 return new Token(endToken(), EParser.EOL);
@@ -508,8 +517,14 @@
                         return new Token(endToken(), EParser.OpAssAsr);
                     }
                     return new Token(endToken(), EParser.OpAsr);
+                }
+                Token result = new Token(endToken(), '>');
+                if (myIndenter.getCloser() == '>') {
+                    myIndenter.pop('>');
+                    return result;
+                } else {
+                    return continuer(result);
                 }
-                return new Token(endToken(), '>');
             } case '*': {
                 nextChar();
                 if (myChar == '*') {
@@ -558,7 +573,7 @@
                     skipLine();
                     stopToken();
                     Token result = getNextToken();
-                    if (result.tokenType() == EParser.EOF) {
+                    if (result.tokenType() == EParser.EOFTOK) {
                         needMore("continued line");
                         return null; //make compiler happy
                     } else {
@@ -633,11 +648,12 @@
             } case '"': {
                 return stringLiteral();
             } case '`': {
-                myIndenter.push('`', 0);
-                nextChar();
                 //eat the backquote here so quasiPart can also
                 //be called when we're quasiAgain'ing (in which case
                 //there is no leading backquote).
+                nextChar();
+                Twine openner = (Twine)myLTwine.run(myOptStartPos, myPos);
+                myIndenter.push(openner, '`', 0);
                 return quasiPart();
             }
             case '0':
@@ -683,15 +699,16 @@
      *
      */
     private Token openBracket(char closer) throws IOException {
-        char openner = (char)myChar;
-        if (isWhite(myPos +1, myLData.length)) {
-            myIndenter.nest(closer);
+        char opennerChar = (char)myChar;
+        nextChar();
+        Twine openner = endToken();
+        if (isWhite(myPos, myLData.length)) {
+            myIndenter.nest(openner, closer);
         } else {
             //Indent the next line to right after the open.
-            myIndenter.push(closer, myPos+1);
+            myIndenter.push(openner, closer, myPos);
         }
-        nextChar();
-        return new Token(endToken(), openner);
+        return new Token(openner, opennerChar);
     }
 
     /**
@@ -700,6 +717,7 @@
     private Token closeBracket() throws IOException {
         char closer = (char)myChar;
         nextChar();
+        //throws SyntaxError at open on bad close
         myIndenter.pop(closer);
         return new Token(endToken(), closer);
     }
@@ -727,7 +745,7 @@
                     nextChar();
                     return charConstant();
                 }
-                case EOF: {
+                case EOFCHAR: {
                     syntaxError("End of file in middle of literal");
                 }
                 case 'u': {
@@ -743,7 +761,7 @@
                     }
                 }
             }
-        } else if (myChar == EOF) {
+        } else if (myChar == EOFCHAR) {
             syntaxError("End of file in middle of literal");
         } else {
             return (char)myChar;
@@ -773,7 +791,7 @@
     private Token identifier() throws IOException, SyntaxException {
         do {
             nextChar();
-        } while (myChar != EOF && isIdentifierPart((char)myChar));
+        } while (myChar != EOFCHAR && isIdentifierPart((char)myChar));
         return Identifier.make(endToken());
     }
 
@@ -888,7 +906,7 @@
      * XXX Get rid of peekChar/0 or make it work
      */
     private char peekChar() {
-        if (myChar == EOF || myChar == '\n') {
+        if (myChar == EOFCHAR || myChar == '\n') {
             throw new Error("internal: can't peek here");
         }
         int last = myLData.length -1;
@@ -904,7 +922,7 @@
      *
      */
     private boolean peekChar(char c) {
-        if (myChar == EOF || myChar == '\n') {
+        if (myChar == EOFCHAR || myChar == '\n') {
             throw new Error("internal: can't peek here");
         }
         int last = myLData.length -1;
@@ -937,7 +955,7 @@
         StringBuffer buf = new StringBuffer();
         while (true) {
             while (QUASI_ENDER.indexOf(myChar) == -1) {
-                if (myChar == EOF) {
+                if (myChar == EOFCHAR) {
                     needMore("File end inside quasi-string literal");
                 }
                 buf.append((char)myChar);
@@ -991,9 +1009,9 @@
     private void skipLine() throws IOException {
         if (null != myLTwine) {
             myPos = myLData.length -1;
+            myChar = myLData[myPos];
         }
-        //XXX todo: Use myDelayedNextChar rather than nextChar()
-        nextChar();
+        myDelayedNextChar = true;
     }
 
     /**
@@ -1019,6 +1037,10 @@
      */
     private Twine endToken() {
         Twine result;
+        int pos = myPos;
+        if (myDelayedNextChar) {
+            pos++;
+        }
         if (-1 == myOptStartPos) {
             if (null == myOptStartText) {
                 throw new Error("internal: no current token");
@@ -1026,12 +1048,12 @@
                 //started on previous line
                 result = myOptStartText;
                 if (null != myLTwine) {
-                    result = (Twine)result.add(myLTwine.run(0, myPos));
+                    result = (Twine)result.add(myLTwine.run(0, pos));
                 }
             }
         } else {
             //starts on this line
-            result = (Twine)myLTwine.run(myOptStartPos, myPos);
+            result = (Twine)myLTwine.run(myOptStartPos, pos);
         }
         stopToken();
         return result;
@@ -1041,12 +1063,13 @@
      *
      */
     private Token stringLiteral() throws IOException, SyntaxException {
-        myIndenter.push('"', 0);
         nextChar();
+        Twine openner = (Twine)myLTwine.run(myOptStartPos, myPos);
+        myIndenter.push(openner, '"', 0);
         StringBuffer value = new StringBuffer();
         while (myChar != '"') {
-            if (myChar == EOF) {
-                needMore("File end inside string literal");
+            if (myChar == EOFCHAR) {
+                needMore("File ends inside string literal");
             }
             value.append(charConstant());
             nextChar();
@@ -1079,7 +1102,11 @@
         nextChar();
         if (! URI.isURICStart((char)myChar)) {
             if (Character.isWhitespace((char)myChar)) {
-                return URI.make(endToken(), EParser.URIStart);
+                Twine openner = endToken();
+                //Indent the next line to right after the open, even if
+                //there remains only whitespace on this line
+                myIndenter.push(openner, '>', myPos);
+                return URI.make(openner, EParser.URIStart);
             } else {
                 syntaxError("Can't use \"" + (char)myChar +
                             "\" to start a URI body");
@@ -1087,7 +1114,7 @@
         }
         do {
             nextChar();
-        } while (myChar != EOF && URI.isURICPart((char)myChar));
+        } while (myChar != EOFCHAR && URI.isURICPart((char)myChar));
         if (myChar != '>') {
             syntaxError("Can't use \"" + (char)myChar +
                         "\" in a URI body");
@@ -1103,27 +1130,33 @@
     static public void main(String[] args)
     throws IOException, SyntaxException {
 
-        if (args.length != 1) {
+        TextWriter stdout = new TextWriter(PrintStreamWriter.out());
+        String url;
+        BufferedReader ins;
+        if (0 == args.length) {
+            url = "stdin";
+            ins = PrintStreamWriter.in();
+        } else if (1 == args.length) {
+            url = args[0];
+            ins = new BufferedReader(new FileReader(args[0]));
+        } else {
             throw new RuntimeException
                 ("usage: java org.erights.e.elang.syntax.ELexer file");
         }
-        Reader ins = new FileReader(args[0]);
-        TextWriter writer = new TextWriter(PrintStreamWriter.out());
-        LineFeeder lr = new FileFeeder(args[0],
-                                       new BufferedReader(ins, 1),
-                                       writer);
+        LineFeeder lr = new FileFeeder(url, ins, stdout);
         ELexer lex = new ELexer(lr, false, false);
         while (true) {
             try {
                 Token t;
                 do {
                     t = lex.nextToken();
-                    PrintStreamWriter.out().println(t + " ");
-                } while (t.tokenType() != EParser.EOF);
+                    stdout.println(t);
+                } while (t.tokenType() != EParser.EOFTOK);
                 return;
             } catch (SyntaxException sex) {
                 TextWriter err = new TextWriter(PrintStreamWriter.err());
                 err.indent("# ").print("# ", sex);
+                err.println();
             }
         }
     }



1.86      +177 -173  e/src/jsrc/org/erights/e/elang/syntax/EParser.java

Index: EParser.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/EParser.java,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -r1.85 -r1.86
--- EParser.java	2001/09/03 18:20:18	1.85
+++ EParser.java	2001/09/04 10:52:18	1.86
@@ -364,7 +364,7 @@
     3,    1,    1,    2,    1,    3,    2,    1,    1,    1,
     3,    3,    3,    4,    3,    1,    3,    1,    3,    1,
     3,    3,    3,    3,    3,    3,    3,    3,    1,    1,
-    1,    3,    3,    3,    3,    4,    1,    3,    3,    1,
+    1,    3,    3,    3,    3,    3,    1,    3,    3,    1,
     3,    3,    1,    1,    1,    3,    3,    1,    1,    1,
     3,    3,    3,    3,    3,    1,    1,    1,    3,    1,
     1,    1,    2,    2,    2,    2,    1,    1,    4,    6,
@@ -444,7 +444,7 @@
     0,    0,    0,  221,  128,    0,    0,    0,    0,    0,
   112,    0,    9,    0,   16,    0,   21,   23,    0,   18,
    22,   19,   25,   29,   31,   32,   40,   39,   36,   37,
-   38,   33,   34,   35,   43,   44,   45,   42,    0,    0,
+   38,   33,   34,   35,   43,   44,   45,   42,   46,    0,
     0,   54,    0,   51,    0,   59,    0,   56,   57,   67,
    66,   63,   65,   61,   62,   64,   71,   70,   69,    0,
     0,    0,    0,    0,    0,    0,  148,    0,  147,  192,
@@ -455,22 +455,21 @@
   227,    0,    0,  230,    0,    0,    0,    0,    0,    0,
     0,    0,  290,  281,  245,    0,  244,  242,  121,    0,
   124,    0,    0,  226,    0,    0,   24,  113,    0,  203,
-    0,   46,    0,    0,   79,    0,    0,    0,   93,  149,
-  169,  156,  171,    0,  159,   11,  152,  150,  152,  183,
-  182,    0,    0,  223,  268,    0,  199,  200,    0,    0,
-  111,  134,  133,   88,    0,   87,  272,    0,    0,  279,
-    0,    0,    0,  118,    0,    0,    0,  293,    0,  295,
-    0,    0,    0,    0,  282,    0,    0,    0,  300,  263,
-  219,    0,    0,    0,    0,   81,    0,    0,   94,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-  222,    0,   89,  264,    0,  277,  232,  229,  231,    0,
-  298,  297,    0,  294,  292,  283,  286,  288,  280,  284,
-    0,    0,  220,    0,   80,   84,   95,  151,  184,  142,
-    0,    0,    0,    0,    0,    0,    0,  269,    0,  265,
-  210,  273,    0,    0,    0,    0,    0,  291,  204,  141,
-    0,  215,    0,    0,    0,  218,  211,  213,  271,  228,
-  296,  285,  287,  289,  214,    0,  212,    0,  216,    0,
-  217,
+    0,    0,    0,   79,    0,    0,    0,   93,  149,  169,
+  156,  171,    0,  159,   11,  152,  150,  152,  183,  182,
+    0,    0,  223,  268,    0,  199,  200,    0,    0,  111,
+  134,  133,   88,    0,   87,  272,    0,    0,  279,    0,
+    0,    0,  118,    0,    0,    0,  293,    0,  295,    0,
+    0,    0,    0,  282,    0,    0,    0,  300,  263,  219,
+    0,    0,    0,    0,   81,    0,    0,   94,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,  222,
+    0,   89,  264,    0,  277,  232,  229,  231,    0,  298,
+  297,    0,  294,  292,  283,  286,  288,  280,  284,    0,
+    0,  220,    0,   80,   84,   95,  151,  184,  142,    0,
+    0,    0,    0,    0,    0,    0,  269,    0,  265,  210,
+  273,    0,    0,    0,    0,    0,  291,  204,  141,    0,
+  215,    0,    0,    0,  218,  211,  213,  271,  228,  296,
+  285,  287,  289,  214,    0,  212,    0,  216,    0,  217,
 };
 final static short yydgoto[] = {                          3,
   190,    5,  400,  178,  146,  370,  336,  147,    6,  337,
@@ -481,12 +480,12 @@
   375,  509,  231,  376,  171,  172,  236,  203,  489,  490,
   322,  344,  484,  184,  246,  186,  187,  188,  189,  107,
   108,  109,  110,  197,  198,  345,  346,  215,  216,  247,
-  499,  618,  655,  676,  356,  357,  232,  513,  514,  377,
-  248,  111,  578,  566,  620,  510,  596,  387,  597,  523,
-  519,  589,  590,
+  499,  617,  654,  675,  356,  357,  232,  513,  514,  377,
+  248,  111,  577,  565,  619,  510,  595,  387,  596,  523,
+  519,  588,  589,
 };
-final static short yysindex[] = {                      -263,
-    0, 9896,    0,12116,    0, -294,    0,14755,   80,14755,
+final static short yysindex[] = {                      -308,
+    0, 9890,    0,11763,    0, -333,    0,15878,   23,15878,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
@@ -495,70 +494,69 @@
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,13053,14755, 6886, -255,    6,
-   21,    0,    0,   96,    0, -169,    0,  101,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,12586,10240,10240,
-13517,    0, 9896, 7005,   80, 8512,   80,   56,   56,13173,
-   80,    0,   80,13517,14755,13053,13053,13053, -324, -255,
-    7, -255,  -75,14551, 9315, -255,    0,    0,  135,    0,
-    0,  364, -198, -164,    0,   71,   27, -143,  141,    2,
-    0, -156, 8846,    0,  216,    0,    0,  130,    0,    0,
-    0,    0,    0,  214, -255, -131,  236,13517,    0,    0,
-13635,    0, -114,  212,    0,  -10,  240,    3,    0,12116,
-  262,   63,   72,12586,   42,    0,    0,  138,12586,  226,
-    0,    0,   56,  -78,    0,    0,14755,14755,  213,  233,
-    0,    0,  298,   56,  -66,    0,   56, -114,  116,    0,
-   56,15009, -255,    0,  367,  281,    0,    0, -255,  372,
-   56,   16,   56,  281,14891,    0,    0,    0,    0,    0,
-14755,12116,   12,  336,   11,    0,  386,    0,  395,    0,
-    0,  182,11646,    0,  183, 9777,   -8,    0,   56,14755,
-14755,  319,  335,    0,   67,   96,13975,    0, 8970,12116,
-12586,12116,    0,    0,    0,    0,    0,12116,    0,    0,
-    0,    0,    0,    0,    0,12239,12116,12586,12586,12586,
-12709, 9896, 9896,12709,12709,12709,12586,12586,12586,12586,
- -255,12586,12586,12709,12586,12709,12709,12709,12709,12709,
-12709,12709,12709,15127, -255,14755,   75, -255,  430,    0,
-    0,  146,12586,  426, 9896,12586,   96,    0, 9896,  427,
- -255,    0,  345, -255,    0, -255,    0,    0,  346,  347,
-    0,  351,  352,    0,    0,    0,   42,    0,    0,    0,
-  206,   56, 9896, -255,  206,    0,    0,    0,    0,  220,
-  223, 9777,    0,14755,    0,12116,  205, -255,  457,    0,
-  459, -255, -255,    0, -111,    0,    0,  181, -255,    0,
-13517,    0,    0, -255, -255,  117,  118,    0,    0, -255,
-    0,    0, -324, -255,    0,  376,    0, -255,  381,    0,
-  467, 9777,12586,    0,    0,  214,  236,  254,  255,12116,
-    0,   56,    0, 9315,    0, -164,    0,    0,  -28,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,12586, -130,
- -130,    0,  141,    0,  141,    0,    2,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0, -255,
-  473,  423,  478, -255,  488,  489,    0,  430,    0,    0,
-    0,    0,    0,    0,10358, 9896,10358, 7005,    0, 8970,
-    0,    0, -255,14755, 9896,15531,    0,10240,    0,  261,
-    0,   56,    0,    0,  407,  408,  493,    0,  491,   56,
-  -60,  496, -255,    0,  497,    0, 9896,   56,    0,    0,
-    0,  128,  210,    0,  268,  264,  504,15820,  505,  -65,
- -255,14755,    0,    0,    0,   12,    0,    0,    0,  428,
-    0,  490,  510,    0,  432,  433,    0,    0,   96,    0,
-  271,    0,  519, -255,    0, -255,  520, -255,    0,    0,
-    0,    0,    0, -114,    0,    0,    0,    0,    0,    0,
-    0,  -78,10240,    0,    0, -151,    0,    0,  490, -255,
-    0,    0,    0,    0,  521,    0,    0,  -51,   56,    0,
- 9896,  490, -255,    0, 9896,  506,  506,    0,    8,    0,
-  506, -255,15245,15245,    0,  438, -255,  526,    0,    0,
-    0,  490,    0,    0, -255,    0,  528,  529,    0,  531,
-  448,  449,  206,   56,   80,15363,15363, -255, -112,  450,
-    0,14755,    0,    0, -255,    0,    0,    0,    0,  286,
-    0,    0, -255,    0,    0,    0,    0,    0,    0,    0,
- -178,  506,    0,  290,    0,    0,    0,    0,    0,    0,
-  206,  -98, 9777,  -30,   56,  120,   56,    0, -255,    0,
-    0,    0,  490,15820, -255,15245,15245,    0,    0,    0,
-   80,    0,  535,12116, 9777,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,  490,    0,  537,    0,  490,
-    0,
+    0,    0,    0,    0,    0,12703,15878, 6880, -307,  -25,
+  -14,    0,    0,   68,    0, -119,    0,  133,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,12233,10234,10234,
+13167,    0, 9890, 6999,   23, 8506,   23,   35,   35,13047,
+   23,    0,   23,13167,15878,12703,12703,12703, -273, -307,
+   -1, -307,  -77,14427, 9309, -307,    0,    0,  142,    0,
+    0,  328, -188, -163,    0,  -33,   86,   77,  180,   50,
+    0, -168, 8840,    0,  192,    0,    0,  -85,    0,    0,
+    0,    0,    0,  197, -307, -162,  201,13167,    0,    0,
+13511,    0, -149,  174,    0,  -23,  178,  -19,    0,11763,
+  237,   38,   56,12233,   12,    0,    0,  -80,12233,   73,
+    0,    0,   35,  -87,    0,    0,15878,15878,  211,  213,
+    0,    0,  275,   35,  -75,    0,   35, -149,   65,    0,
+   35,14663, -307,    0,  308,  245,    0,    0, -307,  330,
+   35,  -39,   35,  245,14545,    0,    0,    0,    0,    0,
+15878,11763,  -35,  286,   49,    0,  354,    0,  364,    0,
+    0,  150,11640,    0,  158, 9771,   66,    0,   35,15878,
+15878,  290,  302,    0,   27,   68,13629,    0, 8964,11763,
+12233,11763,    0,    0,    0,    0,    0,11763,    0,    0,
+    0,    0,    0,    0,    0,12110,11763,12233,12233,12233,
+12580, 9890, 9890,12580,12580,12580,12233,12233,12233,12233,
+12233,12233,12233,12580,12233,12580,12580,12580,12580,12580,
+12580,12580,12580,14781, -307,15878,   71, -307,  391,    0,
+    0,  102,12233,  393, 9890,12233,   68,    0, 9890,  397,
+ -307,    0,  323, -307,    0, -307,    0,    0,  321,  326,
+    0,  339,  340,    0,    0,    0,   12,    0,    0,    0,
+  194,   35, 9890, -307,  194,    0,    0,    0,    0,  218,
+  221, 9771,    0,15878,    0,11763,  203, -307,  440,    0,
+  443, -307, -307,    0,  -79,    0,    0,  239, -307,    0,
+13167,    0,    0, -307, -307,  124,  106,    0,    0, -307,
+    0,    0, -273, -307,    0,  362,    0, -307,  363,    0,
+  454, 9771,12233,    0,    0,  197,  201,  243,  248,11763,
+    0,   35,    0, 9309,    0, -163,    0,    0,  -18,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0, -222,
+ -222,    0,  180,    0,  180,    0,   50,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0, -307,
+  474,  425,  488, -307,  497,  499,    0,  391,    0,    0,
+    0,    0,    0,    0,10352, 9890,10352, 6999,    0, 8964,
+    0,    0, -307,15878, 9890,15185,    0,10234,    0,  273,
+    0,   35,    0,    0,  418,  420,  506,    0,  507,   35,
+  -49,  509, -307,    0,  511,    0, 9890,   35,    0,    0,
+    0,  143,  255,    0,  283,  285,  524,15474,  525,  125,
+ -307,15878,    0,    0,    0,  -35,    0,    0,    0,  446,
+    0,  515,  533,    0,  450,  453,    0,    0,   68,    0,
+  270,  538, -307,    0, -307,  540, -307,    0,    0,    0,
+    0,    0, -149,    0,    0,    0,    0,    0,    0,    0,
+  -87,10234,    0,    0, -115,    0,    0,  515, -307,    0,
+    0,    0,    0,  542,    0,    0,  -45,   35,    0, 9890,
+  515, -307,    0, 9890,  526,  526,    0,  -16,    0,  526,
+ -307,14899,14899,    0,  460, -307,  545,    0,    0,    0,
+  515,    0,    0, -307,    0,  546,  547,    0,  549,  466,
+  470,  194,   35,   23,15017,15017, -307,  -84,  471,    0,
+15878,    0,    0, -307,    0,    0,    0,    0,  287,    0,
+    0, -307,    0,    0,    0,    0,    0,    0,    0, -190,
+  526,    0,  300,    0,    0,    0,    0,    0,    0,  194,
+  -91, 9771,  -13,   35,  127,   35,    0, -307,    0,    0,
+    0,  515,15474, -307,14899,14899,    0,    0,    0,   23,
+    0,  558,11763, 9771,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,  515,    0,  559,    0,  515,    0,
 };
-final static short yyrindex[] = {                      6424,
-    0,  154,    0,   33,    0, 5370,    0,    0,    0,    0,
+final static short yyrindex[] = {                      6418,
+    0,  138,    0,   11,    0, 5364,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
@@ -567,82 +565,81 @@
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,  154,    0,  -58,11299,    0,
-    0,    0,    0, 5750,    0,    0,    0, 5993,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,  154,  -87,  -83,
-    0,    0,  154,  154,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,  154,  154,  154,10706,11299,
-    0,10829,    0,    0,  154,  579,    0,    0,   20,    0,
-  788, 4494,    0, 6047,    0, 5130, 5208, 4741, 4289, 4115,
-    0, 4079, 4043,    0, 2339,    0,    0,    0,    0,    0,
-    0,    0,    0, 5783,11299,    0, 5818,    0,    0,    0,
-    0,    0,  -35,    0,    0,    5,    0,  492,    0,  154,
-    0,    0,    0,  154,    0,    0,    0,    0,  154,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,14093,    0,    0,  301,    0,    0,
-    0,    0,11176,    0, 2492,    0,    0,    0,11299,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,  -11,   28,    0,    0,    0,   30,    0,    0,    0,
-    0,    0,  154,    0,    0,   -4,  460,    0,    0,    0,
-    0,    0,    0, 7467,    0,  633,    0,    0,   54,   26,
-  154,  154,    0,    0,    0,    0,    0,  154,    0,    0,
-    0,    0,    0,    0,    0,  154,  154,  154,  154,  154,
-  154,  154,  154,  154,  154,  154,  154,  154,  154,  154,
-11769,  154,  154,  154,  154,  154,  154,  154,  154,  154,
-  154,  154,  154,    0,10706,    0, 2907,11176,    0,    0,
-    0,    0,  154,    0,  154,  154,  -36,    0,  154, 5853,
- 9433,    0, 5956, 6542,    0,   98,    0,    0,    0,    0,
-    0,16224,15988,    0,    0,    0,    0,    0,    0,    0,
-  316,    0,  154,  -74,  316,    0,    0,    0,    0,    0,
-    0,   -4,    0,    0,    0,  154, 1771,11176, 3060,    0,
-    0,11176,  -40,    0, 1924,    0,    0,    0,11299,    0,
-    0,    0,    0,15702,  -56, -106,    0,    0,    0,11299,
-    0,    0,11299,11299, 1203,    0,    0,  461,    0,    0,
-    0,   -4,  154,    0,    0, 7807, 7929,    0,    0,  154,
-    0,    0,    0,  154,    0, 6247,    0,    0,11299,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,  154, 4876,
- 4912,    0, 4666,    0, 4705,    0, 4250,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,11176,
- 3475,    0, 3628,11176,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,  154,  154,  154,  154,    0,  -20,
-    0,    0,11299,    0,  154,    0,    0,  -83,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,14433,    0,
-    0,    0,11176,    0,    0,    0,  154,    0,    0,    0,
-    0,    0,    0,    0,    0, 1356,    0,  546,    0,  463,
-15702,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,  460,    0,    0,    0,    0,    0,    0, 7345,    0,
-    0,    0,    0,11176,    0,11176,    0,11176,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,  -87,    0,    0,  -42,    0,    0,  460,16342,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-  154,  460,11299,    0,  154,   -3,   -3,    0,  553,    0,
- -106,  461,    0,    0,    0,    0,  461,    0,    0,    0,
-    0,  460, 8269, 8391,11299,    0,    0,    0,    0,    0,
-    0,    0,  316,    0,    0,    0,    0,  -74,  471,    0,
-    0,    0,    0,    0,  -41,    0,    0,    0,    0,    0,
-    0,    0,16106,    0,    0,    0,    0,    0,    0,    0,
-  472, -106,    0,    0,    0,    0,    0,    0,    0,    0,
-  316,    0,   -4,  460,    0,  460,    0,    0,  461,    0,
-    0,    0,  460,    0,  461,    0,    0,    0,    0,    0,
-    0,    0,    0,  154,   -4,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,  460,    0,    0,    0,  460,
-    0,
+    0,    0,    0,    0,    0,  138,    0,  -59,11293,    0,
+    0,    0,    0, 5744,    0,    0,    0, 5987,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  138,  -29,  -42,
+    0,    0,  138,  138,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,  138,  138,  138,10700,11293,
+    0,10823,    0,    0,  138,  565,    0,    0,   24,    0,
+  782,  156,    0, 6041,    0, 5124, 5202, 4735, 4283, 4109,
+    0, 4073, 4037,    0, 2333,    0,    0,    0,    0,    0,
+    0,    0,    0, 5777,11293,    0, 5812,    0,    0,    0,
+    0,    0,  -31,    0,    0,   15,    0,  508,    0,  138,
+    0,    0,    0,  138,    0,    0,    0,    0,  138,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,13969,    0,    0,  324,    0,    0,
+    0,    0,11170,    0, 2486,    0,    0,    0,11293,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,   -3,   60,    0,    0,    0,   48,    0,    0,    0,
+    0,    0,  138,    0,    0,   13,  479,    0,    0,    0,
+    0,    0,    0, 7461,    0,  660,    0,    0,   95,  378,
+  138,  138,    0,    0,    0,    0,    0,  138,    0,    0,
+    0,    0,    0,    0,    0,  138,  138,  138,  138,  138,
+  138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+  138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+  138,  138,  138,    0,10700,    0, 2901,11170,    0,    0,
+    0,    0,  138,    0,  138,  138,  -38,    0,  138, 5847,
+ 9427,    0, 5950, 6536,    0,  -15,    0,    0,    0,    0,
+    0,15996,15642,    0,    0,    0,    0,    0,    0,    0,
+  335,    0,  138,  -72,  335,    0,    0,    0,    0,    0,
+    0,   13,    0,    0,    0,  138, 1765,11170, 3054,    0,
+    0,11170,  -37,    0, 1918,    0,    0,    0,11293,    0,
+    0,    0,    0,15356,  -73,  -83,    0,    0,    0,11293,
+    0,    0,11293,11293, 1197,    0,    0,  482,    0,    0,
+    0,   13,  138,    0,    0, 7801, 7923,    0,    0,  138,
+    0,    0,    0,  138,    0, 6241,    0,    0,11293,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0, 4870,
+ 4906,    0, 4660,    0, 4699,    0, 4244,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,11170,
+ 3469,    0, 3622,11170,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,  138,  138,  138,  138,    0,  -22,
+    0,    0,11293,    0,  138,    0,    0,  -42,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,14087,    0,
+    0,    0,11170,    0,    0,    0,  138,    0,    0,    0,
+    0,    0,    0,    0,    0, 1350,    0,  568,    0,  485,
+15356,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,  479,    0,    0,    0,    0,    0,    0, 7339,    0,
+    0,    0,11170,    0,11170,    0,11170,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,  -29,    0,    0,  -46,    0,    0,  479,16114,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,  138,
+  479,11293,    0,  138,  -26,  -26,    0,  571,    0,  -83,
+  482,    0,    0,    0,    0,  482,    0,    0,    0,    0,
+  479, 8263, 8385,11293,    0,    0,    0,    0,    0,    0,
+    0,  335,    0,    0,    0,    0,  -72,  489,    0,    0,
+    0,    0,    0,   47,    0,    0,    0,    0,    0,    0,
+    0,15760,    0,    0,    0,    0,    0,    0,    0,  492,
+  -83,    0,    0,    0,    0,    0,    0,    0,    0,  335,
+    0,   13,  479,    0,  479,    0,    0,  482,    0,    0,
+    0,  479,    0,  482,    0,    0,    0,    0,    0,    0,
+    0,    0,  138,   13,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,  479,    0,    0,    0,  479,    0,
 };
 final static short yygindex[] = {                         0,
-    1,    0,   29,   13,    0,   32,  348,  331, -140,   -2,
-    0, -210,  227,    0,  434,    0,    0,   23,  332,  314,
-  356,   46, -207,   78,  -89,    0,  114,  304,  215,  136,
-  292,    0,    0,  142,    0,    0,  250, -121, -238,   14,
-    0,   -9,    0,  -48,    0,  -55, -249,  349,    0,  378,
-  234,   97,    0,  237,  119,    0,    0, -113, -340,    0,
-    0, -254, -331, -234,  -94,   36,    0,    0, -110,  442,
- -287,    0,    0,    0,    0,  277,    0,    0,    0, -218,
-    0,    0,   10, -204, -519,    9,    0,    0,   47, -243,
-  232,    0,   65,    0,    0,    0,    0, -307,    0, -484,
-  111,    0,  -29,
+    1,    0,  128,   16,    0,  -89,  366,  351, -144,   -4,
+    0, -203,   31,    0,  455,    0,    0,   40,  350,  341,
+  383,  160,  226,   89,  -88,    0,  123,  320,  223,  250,
+  315,    0,    0,  322,    0,    0,  254,  -86, -233,   14,
+    0,   -6,    0,  280,    0,  -64, -236,  367,    0,  396,
+  251,  120,    0,  257,  137,    0,    0, -113, -312,    0,
+    0, -282, -294, -242,  -94,   55,    0,    0, -107,  459,
+ -231,    0,    0,    0,    0,  296,    0,    0,    0, -217,
+    0,    0,   28, -248, -495,   30,    0,    0,   63,   -8,
+  256,    0,   85,    0,    0,    0,    0, -492,    0, -526,
+  130,    0,   -9,
 };
-final static int YYTABLESIZE=16721;
+final static int YYTABLESIZE=16493;
 
 //These two tables are not statically initialized, but rather
 //initialized on first use, so that a failure to initialize them
@@ -664,7 +661,7 @@
         yytable = (short[])obInp.readObject();
         yycheck = (short[])obInp.readObject();
         long hash = EYaccFixer.checkhash(yytable, yycheck);
-        if (hash != 7060754014413611190L) {
+        if (hash != 1161612266412756548L) {
             throw new RuntimeException(rName + " bad checkhash: " +
                                        hash);
         }
@@ -761,7 +758,7 @@
 "order : interval OpLeq interval",
 "order : interval OpABA interval",
 "order : interval OpGeq interval",
-"order : interval '>' br interval",
+"order : interval '>' interval",
 "interval : shift",
 "interval : shift OpThru shift",
 "interval : shift OpTill shift",
@@ -1289,7 +1286,7 @@
  */
 private void yyerror(String s) throws SyntaxException {
     int ttype = ((Token)yylval).tokenType();
-    if (EParser.EOF == ttype && "syntax error".equals(s)) {
+    if (EParser.EOFTOK == ttype && "syntax error".equals(s)) {
         myLexer.needMore("Unexpected EOF");
         
     } else {
@@ -1328,14 +1325,17 @@
 static private String[] TheTokens = new String[yyname.length];
 
 /** Not provided for us */
-static /*package*/ final short EOF = 0;
+static /*package*/ final short EOFTOK = 0;
 
 static {
     System.arraycopy(yyname, 0, TheTokens, 0, yyname.length);
 
     /* printrep must not be a token */
-    TheTokens[EOF]              = "end-of-file";
 
+    TheTokens[EOFTOK]           = "end-of-file";
+    /* The magical end-of-line token, not considered whitespace */
+    TheTokens[EOL]              = "end-of-line";
+
     TheTokens[LiteralInteger]   = "literal-integer";
     TheTokens[LiteralFloat64]   = "literal-float64";
     TheTokens[LiteralChar]      = "literal-char";
@@ -1467,9 +1467,6 @@
     TheTokens[VOLATILE]         = "volatile";
     TheTokens[WSTRING]          = "wstring";
 
-    /* The magical end-of-line token, not considered whitespace */
-    TheTokens[EOL]      = "\n";
-
     /* Multi-Character Operators */
     TheTokens[OpLAnd]   = "&&";
     TheTokens[OpLOr]    = "||";
@@ -1516,11 +1513,11 @@
 static private IntTable TheTokenTable = null;
 
 /**
- * What's the token type for this literal token?  If this token isn't
+ * What's the token type for this literal tokenName?  If this tokenName isn't
  * in the table, this method returns -1.  It's up to the caller to
  * determine the types of other tokens (like Identifier).
  */
-static public int tokenType(String token) {
+static public int tokenType(String tokenName) {
     if (null == TheTokenTable) {
         TheTokenTable = new IntTable(String.class);
         for (int i = 0; i < TheTokens.length; i++) {
@@ -1529,7 +1526,14 @@
             }
         }
     }
-    return TheTokenTable.getInt(token, -1);
+    return TheTokenTable.getInt(tokenName, -1);
+}
+
+/**
+ *
+ */
+static public String tokenName(int tokenType) {
+    return TheTokens[tokenType];
 }
 
 /**
@@ -1613,7 +1617,7 @@
 static public boolean isContinuer(int tokenType) {
     return TheContinuers[tokenType];
 }
-//#line 4884 "EParser.java"
+//#line 4842 "EParser.java"
 //###############################################################
 // method: yylexdebug : check lexer state
 //###############################################################
@@ -1889,7 +1893,7 @@
 break;
 case 46:
 //#line 293 "e.y"
-{ yyval = greaterThan(val_peek(3), val_peek(0)); }
+{ yyval = greaterThan(val_peek(2), val_peek(0)); }
 break;
 case 48:
 //#line 302 "e.y"
@@ -2740,7 +2744,7 @@
 //#line 1055 "e.y"
 { yyval = val_peek(0); }
 break;
-//#line 6008 "EParser.java"
+//#line 5966 "EParser.java"
 //########## END OF USER-SUPPLIED ACTIONS ##########
     }//switch
     //#### Now let's reduce... ####



1.6       +3 -3      e/src/jsrc/org/erights/e/elang/syntax/FileFeeder.java

Index: FileFeeder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/FileFeeder.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- FileFeeder.java	2001/09/03 18:20:18	1.5
+++ FileFeeder.java	2001/09/04 10:52:18	1.6
@@ -96,9 +96,9 @@
      *
      */
     private String prompt(boolean quoted,
-                             int indent,
-                             char closer,
-                             int closeIndent)
+                          int indent,
+                          char closer,
+                          int closeIndent)
     {
         if (quoted) {
             return "> ";



1.2       +29 -11    e/src/jsrc/org/erights/e/elang/syntax/Indenter.java

Index: Indenter.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/Indenter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Indenter.java	2001/09/02 22:36:51	1.1
+++ Indenter.java	2001/09/04 10:52:18	1.2
@@ -21,6 +21,8 @@
 Contributor(s): ______________________________________.
 */
 
+import org.erights.e.elib.tables.Twine;
+
 import java.lang.reflect.Array;
 
 /**
@@ -53,6 +55,11 @@
     private int myTOS;
 
     /**
+     * The openners are Twine for reporting located errors at close time
+     */
+    private Twine[] myOpennerStack;
+
+    /**
      * The closers -- close bracketing characters that would close the
      * currently unclosed open brackets
      * <p>
@@ -80,8 +87,10 @@
     public Indenter() {
         myNest = 0;
         myTOS = 0;
+        myOpennerStack = new Twine[16];
+        myOpennerStack[0] = null;       //dummy initial openner
         myCloserStack = new char[16];
-        myCloserStack[myTOS] = 'x';    // dummy initial closer
+        myCloserStack[myTOS] = 'x';     // dummy initial closer
         myIndentStack = new int[16];
         myIndentStack[myTOS] = 0;
         myNestStack = new boolean[16];
@@ -102,13 +111,19 @@
     /**
      * Internal push
      */
-    private void push(char closer, int indent, boolean isNest) {
+    private void push(Twine openner,
+                      char closer,
+                      int indent,
+                      boolean isNest)
+    {
         myTOS++;
         if (myTOS >= myCloserStack.length) {
+            myOpennerStack = (Twine[])grow(myOpennerStack);
             myCloserStack = (char[])grow(myCloserStack);
             myIndentStack = (int[])grow(myIndentStack);
             myNestStack = (boolean[])grow(myNestStack);
         }
+        myOpennerStack[myTOS] = openner;
         myCloserStack[myTOS] = closer;
         myIndentStack[myTOS] = indent;
         myNestStack[myTOS] = isNest;
@@ -117,16 +132,16 @@
     /**
      * Push a nester
      */
-    public void nest(char closer) {
+    public void nest(Twine openner, char closer) {
         myNest++;
-        push(closer, myNest * 4, true);
+        push(openner, closer, myNest * 4, true);
     }
 
     /**
      * Push a non-nester
      */
-    public void push(char closer, int indent) {
-        push(closer, indent, false);
+    public void push(Twine openner, char closer, int indent) {
+        push(openner, closer, indent, false);
     }
 
     /**
@@ -134,18 +149,21 @@
      * <p>
      * If the opening was also a nesting, this decrements the nest level.
      *
-     * @param closer As an error check, 'closer' must be closing bracket
+     * @param closer As an error check, 'closer' must be the closing bracket
      *               character needed to close the most recent unclosed
      *               bracket.
      */
     public void pop(char closer) {
         if (myTOS <= 0) {
-            throw new RuntimeException("internal: can't pop empty stack");
+            throw new SyntaxException
+                    ("internal: can't pop empty stack",
+                     null, 0, 0);
         }
         if (myCloserStack[myTOS] != closer) {
-            throw new RuntimeException
-                    ("mismatch: closing " + myCloserStack[myTOS] +
-                     " vs " + closer);
+            Twine openner = myOpennerStack[myTOS];
+            throw new SyntaxException
+                    ("mismatch: " + myCloserStack[myTOS] + " vs " + closer,
+                     openner, 0, openner.size());
         }
         int oldTOS = myTOS;
         myTOS--;



1.16      +22 -20    e/src/jsrc/org/erights/e/elang/syntax/SyntaxException.java

Index: SyntaxException.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/SyntaxException.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- SyntaxException.java	2001/08/17 20:59:26	1.15
+++ SyntaxException.java	2001/09/04 10:52:18	1.16
@@ -1,20 +1,20 @@
 package org.erights.e.elang.syntax;
 
 /*
-The contents of this file are subject to the Electric Communities E Open 
-Source Code License Version 1.0 (the "License"); you may not use this file 
-except in compliance with the License. You may obtain a copy of the License 
+The contents of this file are subject to the Electric Communities E Open
+Source Code License Version 1.0 (the "License"); you may not use this file
+except in compliance with the License. You may obtain a copy of the License
 at http://www.communities.com/EL/.
 
-Software distributed under the License is distributed on an "AS IS" basis, 
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 the specific language governing rights and limitations under the License.
 
-The Original Code is the Distributed E Language Implementation, released 
-July 20, 1998. 
+The Original Code is the Distributed E Language Implementation, released
+July 20, 1998.
 
-The Initial Developer of the Original Code is Electric Communities.  
-Copyright (C) 1998 Electric Communities. All Rights Reserved. 
+The Initial Developer of the Original Code is Electric Communities.
+Copyright (C) 1998 Electric Communities. All Rights Reserved.
 
 Contributor(s): ______________________________________.
 */
@@ -24,20 +24,22 @@
 import org.erights.e.develop.exception.ExceptionMgr;
 import org.erights.e.elib.base.SourceSpan;
 import org.erights.e.elib.base.TextWriter;
+import org.erights.e.elib.base.Printable;
 import org.erights.e.develop.format.StringHelper;
 import org.erights.e.elib.tables.Twine;
 
 /**
- * Thrown if there's a grammatical error in the input
+ * Thrown if there's a grammatical error in the input.
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
-public class SyntaxException extends RuntimeException {
-    
+public class SyntaxException
+extends RuntimeException implements Printable {
+
     private Twine myOptLine;
     private int myStart;
     private int myBound;
-    
+
     /**
      *
      */
@@ -51,22 +53,22 @@
         myStart = start;
         myBound = bound;
     }
-    
+
     /**
      *
      */
     public Twine optLine()  { return myOptLine; }
-    
+
     /**
      *
      */
     public int getStart()   { return myStart; }
-    
+
     /**
      *
      */
     public int getBound()   { return myBound; }
-    
+
     /**
      *
      */
@@ -77,14 +79,14 @@
             return (Twine)myOptLine.run(myStart, myBound);
         }
     }
-    
+
     static private final String ErrPrefix = "syntax error: ";
     /** Same number of spaces as in the ErrPrefix */
-    static private final String ErrIndent = 
+    static private final String ErrIndent =
         StringHelper.multiply(" ", ErrPrefix.length());
 
     /**
-     * Prints as "syntax error: " followed by an optional message, and then 
+     * Prints as "syntax error: " followed by an optional message, and then
      * an optional indication of the location of the error.
      */
     public void printOn(TextWriter out) throws IOException {



1.9       +11 -11    e/src/jsrc/org/erights/e/elang/syntax/Token.java

Index: Token.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/Token.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- Token.java	2001/02/03 18:32:06	1.8
+++ Token.java	2001/09/04 10:52:18	1.9
@@ -1,20 +1,20 @@
 package org.erights.e.elang.syntax;
 
 /*
-The contents of this file are subject to the Electric Communities E Open 
-Source Code License Version 1.0 (the "License"); you may not use this file 
-except in compliance with the License. You may obtain a copy of the License 
+The contents of this file are subject to the Electric Communities E Open
+Source Code License Version 1.0 (the "License"); you may not use this file
+except in compliance with the License. You may obtain a copy of the License
 at http://www.communities.com/EL/.
 
-Software distributed under the License is distributed on an "AS IS" basis, 
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 the specific language governing rights and limitations under the License.
 
-The Original Code is the Distributed E Language Implementation, released 
-July 20, 1998. 
+The Original Code is the Distributed E Language Implementation, released
+July 20, 1998.
 
-The Initial Developer of the Original Code is Electric Communities.  
-Copyright (C) 1998 Electric Communities. All Rights Reserved. 
+The Initial Developer of the Original Code is Electric Communities.
+Copyright (C) 1998 Electric Communities. All Rights Reserved.
 
 Contributor(s): ______________________________________.
 */
@@ -59,7 +59,7 @@
      *
      */
     public String toString() {
-        String result = tokenType() + ": \"" + token() + "\"";
-        return result + " @ " + myTok.optSourceSpan();
+        return EParser.tokenName(myTokenType) + ": \"" +
+                token() + "\"" + " @ " + myTok.optSourceSpan();
     }
 }



1.81      +20 -13    e/src/jsrc/org/erights/e/elang/syntax/e.y

Index: e.y
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/e.y,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -r1.80 -r1.81
--- e.y	2001/09/03 18:20:18	1.80
+++ e.y	2001/09/04 10:52:18	1.81
@@ -276,9 +276,9 @@
 /**
  * &lt;, &lt;= &lt;=&gt;, &gt;=, &gt; are all non associative.
  * <p>
- * &gt; is not listed as a continuation operator, but is instead
- * followed by a 'br' production here, because it also has a role in
- * closing a calculated URI expression.
+ * &gt; is not listed as a continuation operator, because it also has
+ * a role in closing a calculated URI expression.  ELexer must handle
+ * its use as a continuation specially.
  */
 nOrder:
         order                           { $$ = list($1); }
@@ -290,7 +290,7 @@
  |      interval OpLeq interval         { $$ = leq($1, $3); }
  |      interval OpABA interval         { $$ = asBigAs($1, $3); }
  |      interval OpGeq interval         { $$ = geq($1, $3); }
- |      interval '>' br interval        { $$ = greaterThan($1, $4); }
+ |      interval '>'   interval         { $$ = greaterThan($1, $3); }
  ;
 
 
@@ -1268,7 +1268,7 @@
  */
 private void yyerror(String s) throws SyntaxException {
     int ttype = ((Token)yylval).tokenType();
-    if (EParser.EOF == ttype && "syntax error".equals(s)) {
+    if (EParser.EOFTOK == ttype && "syntax error".equals(s)) {
         myLexer.needMore("Unexpected EOF");
         
     } else {
@@ -1307,14 +1307,17 @@
 static private String[] TheTokens = new String[yyname.length];
 
 /** Not provided for us */
-static /*package*/ final short EOF = 0;
+static /*package*/ final short EOFTOK = 0;
 
 static {
     System.arraycopy(yyname, 0, TheTokens, 0, yyname.length);
 
     /* printrep must not be a token */
-    TheTokens[EOF]              = "end-of-file";
 
+    TheTokens[EOFTOK]           = "end-of-file";
+    /* The magical end-of-line token, not considered whitespace */
+    TheTokens[EOL]              = "end-of-line";
+
     TheTokens[LiteralInteger]   = "literal-integer";
     TheTokens[LiteralFloat64]   = "literal-float64";
     TheTokens[LiteralChar]      = "literal-char";
@@ -1446,9 +1449,6 @@
     TheTokens[VOLATILE]         = "volatile";
     TheTokens[WSTRING]          = "wstring";
 
-    /* The magical end-of-line token, not considered whitespace */
-    TheTokens[EOL]      = "\n";
-
     /* Multi-Character Operators */
     TheTokens[OpLAnd]   = "&&";
     TheTokens[OpLOr]    = "||";
@@ -1495,11 +1495,11 @@
 static private IntTable TheTokenTable = null;
 
 /**
- * What's the token type for this literal token?  If this token isn't
+ * What's the token type for this literal tokenName?  If this tokenName isn't
  * in the table, this method returns -1.  It's up to the caller to
  * determine the types of other tokens (like Identifier).
  */
-static public int tokenType(String token) {
+static public int tokenType(String tokenName) {
     if (null == TheTokenTable) {
         TheTokenTable = new IntTable(String.class);
         for (int i = 0; i < TheTokens.length; i++) {
@@ -1508,7 +1508,14 @@
             }
         }
     }
-    return TheTokenTable.getInt(token, -1);
+    return TheTokenTable.getInt(tokenName, -1);
+}
+
+/**
+ *
+ */
+static public String tokenName(int tokenType) {
+    return TheTokens[tokenType];
 }
 
 /**



1.6       +8 -3      e/src/jsrc/org/erights/e/elib/base/Printable.java

Index: Printable.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/Printable.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Printable.java	2001/08/29 00:20:17	1.5
+++ Printable.java	2001/09/04 10:52:18	1.6
@@ -18,17 +18,22 @@
 The Initial Developer of the Original Code is Mark S. Miller.
 Copyright (C) 1999 Mark S. Miller. All Rights Reserved.
 
-Contributor(s): ______________________________________. 
+Contributor(s): ______________________________________.
 */
 
 import java.io.IOException;
 
 /**
- * Non-public classes that would introduce printOn/1 should instead implement 
+ * Non-public classes that would introduce printOn/1 should instead implement
  * Printable so that their printOn/1 is callable from E.call*.
+ * <p>
+ * Throwables that do their own printOn must also implement Printable, so
+ * the Miranda unwrapping happens right.
+ *
+ * @author Mark S. Miller
  */
 public interface Printable {
-    
+
     /**
      *
      */



1.37      +66 -62    e/src/jsrc/org/erights/e/elib/prim/MirandaMethods.java

Index: MirandaMethods.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/MirandaMethods.java,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- MirandaMethods.java	2001/08/20 05:07:44	1.36
+++ MirandaMethods.java	2001/09/04 10:52:19	1.37
@@ -1,20 +1,20 @@
 package org.erights.e.elib.prim;
 
 /*
-The contents of this file are subject to the Electric Communities E Open 
-Source Code License Version 1.0 (the "License"); you may not use this file 
-except in compliance with the License. You may obtain a copy of the License 
+The contents of this file are subject to the Electric Communities E Open
+Source Code License Version 1.0 (the "License"); you may not use this file
+except in compliance with the License. You may obtain a copy of the License
 at http://www.communities.com/EL/.
 
-Software distributed under the License is distributed on an "AS IS" basis, 
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 the specific language governing rights and limitations under the License.
 
-The Original Code is the Distributed E Language Implementation, released 
-July 20, 1998. 
+The Original Code is the Distributed E Language Implementation, released
+July 20, 1998.
 
-The Initial Developer of the Original Code is Electric Communities.  
-Copyright (C) 1998 Electric Communities. All Rights Reserved. 
+The Initial Developer of the Original Code is Electric Communities.
+Copyright (C) 1998 Electric Communities. All Rights Reserved.
 
 Contributor(s): ______________________________________.
 */
@@ -23,21 +23,21 @@
 import org.erights.e.develop.exception.ExceptionMgr;
 import org.erights.e.develop.exception.ThrowableSugar;
 import org.erights.e.elib.base.Ejection;
+import org.erights.e.elib.base.TypeDesc;
 import org.erights.e.elib.base.Callable;
 import org.erights.e.elib.base.ClassDesc;
 import org.erights.e.elib.base.Script;
+import org.erights.e.elib.base.Printable;
 import org.erights.e.elib.base.TextWriter;
-import org.erights.e.elib.base.TypeDesc;
 import org.erights.e.elib.ref.Resolver;
 import org.erights.e.elib.sealing.Brand;
 import org.erights.e.elib.sealing.SealedBox;
-import org.erights.e.develop.exception.ThrowableSugar;
 import org.erights.e.elib.sealing.Amplifiable;
 import org.erights.e.elib.sealing.Brand;
 import org.erights.e.elib.sealing.SealedBox;
 
 /**
- * A sweetener defining default behavior for messages that may be e-called 
+ * A sweetener defining default behavior for messages that may be e-called
  * or e-sent to any methodical object.  These methods apply directly
  * to null or a "new Object()".  Therefore, they must work when self
  * is null.
@@ -63,12 +63,12 @@
         Object result = null;
         try {
             result = E.callAll(self, nestedVerb, nestedArgs);
-            
+
         } catch (Throwable t) {
             Throwable leaf = ThrowableSugar.leaf(t);
             if (leaf instanceof Ejection) {
-                //an escaped Ejection should never happen, but does not stop 
-                //successor messages 
+                //an escaped Ejection should never happen, but does not stop
+                //successor messages
                 after.resolve(self);
             } else {
                 after.smash(t);
@@ -82,14 +82,14 @@
     /**
      * Generic object-level rights amplification protocol. <p>
      *
-     * Dispatch on the brand much as one would dispatch on a message name.  
-     * If we recognize the brand and we have the corresponding sealer, then 
+     * Dispatch on the brand much as one would dispatch on a message name.
+     * If we recognize the brand and we have the corresponding sealer, then
      * we may return something meaningful inside a SealedBox sealed with that
      * Sealer.  If we have nothing to return, given the meaning we associate
      * with that brand as a request, then we return null.
-     * 
-     * The default implementation: If self is Amplifiable, delegate to it.  
-     * Otherwise, return null.  For object written in the E language, the 
+     *
+     * The default implementation: If self is Amplifiable, delegate to it.
+     * Otherwise, return null.  For object written in the E language, the
      * default is simply to return null.
      */
     static public SealedBox optMeta(Object self, Brand brand) {
@@ -133,58 +133,62 @@
     }
 
     /**
-     * For E, this is the method should be widely overridden, rather
+     * For E, this is the method that should be widely overridden, rather
      * than toString(), since composition via toString() cannot break
      * cycles.  The Miranda method defaults to java-calling
      * String.valueOf(self) and write()ing the result on out.
      * String.valueOf(self) is java's null-safe form of self.toString();
      */
-    static public void printOn(Object self, TextWriter out) 
-         throws IOException
-    {
+    static public void printOn(Object self, TextWriter out)
+    throws IOException {
         if (self instanceof Throwable) {
-            //XXX we engage in this horrible kludge because ThrowableSugar 
-            //exists in a layer prior to TextWriter
-            ThrowableSugar.printThrowableOn((Throwable)self, out);
+            Throwable leaf = ThrowableSugar.leaf((Throwable)self);
+            if (leaf instanceof Printable) {
+                ((Printable)leaf).printOn(out);
+            } else {
+                //XXX we engage in this horrible kludge because ThrowableSugar
+                //exists in a layer prior to TextWriter
+                ThrowableSugar.printThrowableOn((Throwable)self, out);
+            }
         } else {
             out.write(String.valueOf(self));
         }
     }
-    
+
     /**
-     * When someone was holding a partitionable eventual reference to this 
-     * object, and it sufferes a partition, then inform this object that one 
+     * When someone was holding a partitionable eventual reference to this
+     * object, and it sufferes a partition, then inform this object that one
      * of its clients may no longer be able to talk to it, and why.  <p>
      *
-     * The Miranda behavior is to do nothing, but objects may override this 
-     * to provide DeadManSwitch behavior.  For example, a revoking facet of a 
-     * revokable service may decide that if its client may no longer be able 
-     * to talk to it, that it should auto-revoke.  However inconvenient this 
+     * The Miranda behavior is to do nothing, but objects may override this
+     * to provide DeadManSwitch behavior.  For example, a revoking facet of a
+     * revokable service may decide that if its client may no longer be able
+     * to talk to it, that it should auto-revoke.  However inconvenient this
      * solution, it is failsafe.
      */
     static public void reactToLostClient(Object self, Throwable problem) {
-        self = self; //Just something to breakpoint on   
+        self = self; //Just something to breakpoint on
     }
 
     /**
-     * Used to implement when-catch and the "Ref whenResolved/2"; it should 
+     * Used to implement when-catch and the "Ref whenResolved/2"; it should
      * not be called directly. <p>
      *
-     * The Miranda behavior responds by doing 'reactor <- run(self)'.  If the 
+     * The Miranda behavior responds by doing 'reactor <- run(self)'.  If the
      * reference never becomes resolved, the reactor is not invoked. <p>
      *
-     * In the cooperative (non-malicious) case, the reactor will not be 
+     * In the cooperative (non-malicious) case, the reactor will not be
      * invoked more than once.
      *
-     * When sent on a reference, once the reference becomes resolved the 
+     * When sent on a reference, once the reference becomes resolved the
      * reactor will be invoked with the resolution.  Should the reactor be
-     * invoked with a non-broken reference, all earlier messages are 
+     * invoked with a non-broken reference, all earlier messages are
      * guaranteed to have been successfully delivered. <p>
      *
-     * Should the reference become broken, or should breakage prevent the 
-     * reporting of fulfillment to the reactor, the reactor will be invoked 
-     * with a broken reference.  The reactor may be invoked more than once.  
-     * In particular, if the reference becomes fulfilled and then broken, 
+     * Should the reference become broken, or should breakage prevent the
+     * reporting of fulfillment to the reactor, the reactor will be invoked
+     * with a broken reference.  The reactor may be invoked more than once.
+     * In particular, if the reference becomes fulfilled and then broken,
      * the reactor may hear of either or both of these events.
      *
      * @see org.erights.e.elib.ref.Ref#whenBroken
@@ -192,43 +196,43 @@
     static public void whenMoreResolved(Object self, Object reactor) {
         E.sendOnly(reactor, "run", self);
     }
-    
+
     /**
-     * Used to implement "Ref whenBroken/2"; it should not be called 
-     * directly. 
+     * Used to implement "Ref whenBroken/2"; it should not be called
+     * directly.
      * <p>
-     * The Miranda behavior ignores the message, as only breakable ref 
+     * The Miranda behavior ignores the message, as only breakable ref
      * implementations ever respond to this message.
-     * 
+     *
      * @see org.erights.e.elib.ref.Ref#whenBroken(Object, OneArgFunc)
      */
     static public void whenBroken(Object self, Object reactor) {
-        self = self; //Just something to breakpoint on   
+        self = self; //Just something to breakpoint on
     }
 
     /**
-     * When invoked on a methodical object, the object simply returns 
-     * itself.  Although the name and the semantics are borrowed from 
-     * Smalltalk, the purpose is completely different.  This method is used 
-     * by distributed three party handoff to implement the poE ordering 
+     * When invoked on a methodical object, the object simply returns
+     * itself.  Although the name and the semantics are borrowed from
+     * Smalltalk, the purpose is completely different.  This method is used
+     * by distributed three party handoff to implement the poE ordering
      * guarantees: When Alice sends to Bob a reference to Carol
      * <p><pre>
      *          E.sendOnly(bob, "foo", carol);
      * </pre>
-     * when each is on a different machine, the encoding of Alice's Far 
+     * when each is on a different machine, the encoding of Alice's Far
      * reference to Carol instead encodes the value returned by
      * <p><pre>
      *          E.send(carol, "yourself")
      * </pre>
-     * Any messages sent to this result will only be received by Carol after 
-     * Carol receives the "yourself" message, and therefore after Carol has 
-     * received all messages which precede the "youself" message.  This is 
-     * true even if the messages sent to the result are sent from another 
+     * Any messages sent to this result will only be received by Carol after
+     * Carol receives the "yourself" message, and therefore after Carol has
+     * received all messages which precede the "youself" message.  This is
+     * true even if the messages sent to the result are sent from another
      * machine, as would be the case in distributed three party handoff. <p>
      *
-     * Since all this results in a system which successfully implements poE, 
-     * users of ELib other than captp should never need to invoke this method 
-     * (and no one should ever need to override it). 
+     * Since all this results in a system which successfully implements poE,
+     * users of ELib other than captp should never need to invoke this method
+     * (and no one should ever need to override it).
      */
     static public Object yourself(Object self) {
         return self;



1.4       +29 -22    e/src/jsrc/org/erights/e/elib/prim/Thrower.java

Index: Thrower.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/Thrower.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Thrower.java	2001/08/29 00:20:17	1.3
+++ Thrower.java	2001/09/04 10:52:19	1.4
@@ -18,7 +18,7 @@
 The Initial Developer of the Original Code is Mark S. Miller.
 Copyright (C) 1999 Mark S. Miller. All Rights Reserved.
 
-Contributor(s): ______________________________________. 
+Contributor(s): ______________________________________.
 */
 
 import java.io.IOException;
@@ -28,22 +28,22 @@
 import org.erights.e.elib.util.OneArgFunc;
 
 /**
- * An StaticMaker on this class is the function named "throw" in the 
+ * An StaticMaker on this class is the function named "throw" in the
  * universalScope. <p>
  *
  * When called with an object, it throws that object coerced to an Exception.
- * 
+ *
  * @author Mark S. Miller
  */
 public class Thrower implements OneArgFunc {
-    
+
     static public final Thrower THE_ONE = new Thrower();
-    
-    /** 
+
+    /**
      *
      */
     private Thrower() {}
-    
+
     /**
      * Throws problem (coerced to a RuntimeException).
      *
@@ -52,34 +52,34 @@
     public Object run(Object problem) {
         throw ExceptionMgr.asSafe(E.toThrowable(problem));
     }
-    
+
     /**
-     * Exits according to optEjector with the provided value, for use from E. <p>
-     *
-     * If optEjector is null, then throws 'value' as a throwable problem 
-     * that doesn't need to be declared.  Otherwise, optEjector should eject 
-     * rather than returning.  If it does return, then 'eject' does its own 
+     * Exits according to optEjector with the provided value, for use from E.
+     * <p>
+     * If optEjector is null, then throws 'value' as a throwable problem
+     * that doesn't need to be declared.  Otherwise, optEjector should eject
+     * rather than returning.  If it does return, then 'eject' does its own
      * (backtraced) throw rather than returning.
      */
     public void eject(OneArgFunc optEjector, Object value) {
         throw toEject(optEjector, value);
     }
-    
+
     /**
-     * Exits according to optEjector with the provided value, for use from 
+     * Exits according to optEjector with the provided value, for use from
      * Java. <p>
      *
-     * If optEjector is null, then returns 'value' as a throwable problem 
-     * that doesn't need to be declared.  Otherwise, optEjector should eject 
-     * rather than returning.  If it does return, then 'toEject' does its own 
+     * If optEjector is null, then returns 'value' as a throwable problem
+     * that doesn't need to be declared.  Otherwise, optEjector should eject
+     * rather than returning.  If it does return, then 'toEject' does its own
      * (backtraced) throw rather than returning. <p>
      *
      * The caller should typically say <pre>
      *
      *     throw Thrower.toEject(optEjector, problem);
      * </pre>
-     * One of the reasons why 'toEject' has its caller do a throw is to provide 
-     * the Java compiler with better control flow information.
+     * One of the reasons why 'toEject' has its caller do a throw is to
+     * provide the Java compiler with better control flow information.
      */
     static public RuntimeException toEject(OneArgFunc optEjector,
                                            Object value)
@@ -88,10 +88,17 @@
             return ExceptionMgr.asSafe(E.toThrowable(value));
         }
         optEjector.run(value);
-        throw ThrowableSugar.backtrace(E.toThrowable(value), 
+        throw ThrowableSugar.backtrace(E.toThrowable(value),
                                        "optEjector returned");
+    }
+
+    /**
+     * Just something callable from E to breakpoint on in Java.
+     */
+    public void breakpoint(Object diagnostic) {
+        diagnostic = diagnostic;
     }
-    
+
     /**
      * Prints as "throw", the name by which it's known in the universalScope.
      */



1.8       +14 -14    e/src/jsrc/org/erights/e/elib/tables/CompositeTwine.java

Index: CompositeTwine.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/CompositeTwine.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- CompositeTwine.java	2001/08/20 21:17:50	1.7
+++ CompositeTwine.java	2001/09/04 10:52:19	1.8
@@ -30,9 +30,9 @@
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
 /*package*/ final class CompositeTwine extends Twine {
-    
+
     static private final long serialVersionUID = -4692386437819865069L;
-    
+
     private transient int mySizeCache = -1;
 
     /**
@@ -46,7 +46,7 @@
     /*package*/ CompositeTwine(ConstList parts) {
         myParts = parts;
     }
-    
+
     /**
      * 'TwineMaker fromParts(myParts)'
      */
@@ -54,7 +54,7 @@
         Object[] result = { TwineMaker, "fromParts", myParts };
         return result;
     }
-    
+
     /**
      *
      */
@@ -64,30 +64,30 @@
         int offset = pair[1];
         return ((AtomicTwine)myParts.get(index)).charAt(offset);
     }
-    
+
     /**
      *
      */
     public ConstList run(int start, int bound)
     throws IndexOutOfBoundsException{
-        
+
         int len = size();
         if (start < 0 || bound > len || start > bound) {
             throw new IndexOutOfBoundsException("twine run");
         }
         if (start == bound) {
-            return SimpleTwine.EmptyTwine;
+            return EmptyTwine.THE_ONE;
         }
-        
+
         int[] leftPair = getPartAt(start);
         int leftIndex = leftPair[0];
         int leftOffset = leftPair[1];
         Twine left = (AtomicTwine)myParts.get(leftIndex);
-        
+
         int[] rightPair = getPartAt(bound -1);
         int rightIndex = rightPair[0];
         int rightOffset = rightPair[1];
-        
+
         if (leftIndex == rightIndex) {
             return left.run(leftOffset, rightOffset +1);
         } else {
@@ -100,7 +100,7 @@
             return result;
         }
     }
-    
+
     /**
      *
      */
@@ -115,7 +115,7 @@
         }
         return mySizeCache;
     }
-    
+
     /**
      *
      */
@@ -128,7 +128,7 @@
     }
 
     /**
-     * 
+     *
      */
     public boolean isBare() {
         return false;
@@ -150,7 +150,7 @@
             out.print(myParts.get(i));
         }
     }
-    
+
     /**
      *
      */



1.24      +54 -52    e/src/jsrc/org/erights/e/elib/tables/Equalizer.java

Index: Equalizer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/Equalizer.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- Equalizer.java	2001/08/17 03:11:33	1.23
+++ Equalizer.java	2001/09/04 10:52:19	1.24
@@ -14,51 +14,53 @@
 
 
 /**
- * Implements E's sameness semantics, which should be used only through the 
+ * Implements E's sameness semantics, which should be used only through the
  * Ref class.  <p>
  *
- * The static methods are the recursive cycle-breaking sameness algorithm.  
- * An Equalizer instance is a  hypothetical comparison pair as used by the 
- * algorithm.  Equalizer instances are honorary Selfless objects, so that 
+ * The static methods are the recursive cycle-breaking sameness algorithm.
+ * An Equalizer instance is a  hypothetical comparison pair as used by the
+ * algorithm.  Equalizer instances are honorary Selfless objects, so that
  * their .equals() and .hashCode() will be used to compare them.
  *
  * @see org.erights.e.elib.ref.Ref
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
 public final class Equalizer {
-        
+
     /**
      * A random guess at a good value
      */
     static private final int HASH_DEPTH = 20;
 
     /**
-     * All instances of the left hand (key) types simplify (for purposes of 
+     * All instances of the left hand (key) types simplify (for purposes of
      * sameness comparison) to instances of the right hand (value) types. <p>
      *
-     * This is much like the Promotions in ScriptMaker, with some 
-     * differences. 
+     * This is much like the Promotions in ScriptMaker, with some
+     * differences.
      */
     static private String[][] Simplifications = {
         { "java.lang.Byte",                         "java.math.BigInteger" },
         { "java.lang.Short",                        "java.math.BigInteger" },
         { "java.lang.Integer",                      "java.math.BigInteger" },
         { "java.lang.Long",                         "java.math.BigInteger" },
-        
+
         { "java.lang.Float",                        "java.lang.Double" },
-        
+
         { "org.erights.e.elib.base.ClassDesc",      "java.lang.Class" },
-        //Though String promotes to Twine, only SimpleTwine simplifies back 
-        //to String.  This is less irregular than it seems, since Twine with 
-        //no extra info will actually be a SimpleTwine.
+        //Though String promotes to Twine, only SimpleTwine and EmptyTwine
+        //simplify back to String.  This is less irregular than it seems,
+        //since Twine with no extra info will actually be a SimpleTwine or
+        //EmptyTwine.
+        { "org.erights.e.elib.tables.EmptyTwine",   "java.lang.String" },
         { "org.erights.e.elib.tables.SimpleTwine",  "java.lang.String" },
     };
 
-    /** 
+    /**
      * Maps fq class names to the fqn of the classes they simplify to. <p>
      *
-     * TheSimplifications is initialized lazily in order to avoid possible 
-     * circular static initialization dependencies.  Uses legacy HashMap 
+     * TheSimplifications is initialized lazily in order to avoid possible
+     * circular static initialization dependencies.  Uses legacy HashMap
      * rather than EMap in order to avoid a circular dependency.
      */
     static private HashMap TheSimplifications = null;
@@ -86,18 +88,18 @@
     }
 
     private final Object myLeft;
-    private final Object myRight;    
-    
-    /** 
+    private final Object myRight;
+
+    /**
      *
      */
     private Equalizer(Object left, Object right) {
         myLeft = left;
         myRight = right;
     }
-    
+
     /**
-     * Two Equalizers are the same if their two objects are EQ (Java's "=="), 
+     * Two Equalizers are the same if their two objects are EQ (Java's "=="),
      * independent of order.
      */
     public boolean equals(Object other) {
@@ -110,22 +112,22 @@
         return (myLeft == oth.myLeft && myRight == oth.myRight)
             || (myLeft == oth.myRight && myRight == oth.myLeft);
     }
-    
+
     /**
-     * The hashCode() must depend only on the EQ identities of myLeft and 
+     * The hashCode() must depend only on the EQ identities of myLeft and
      * myRight independent of their order.
      */
     public int hashCode() {
         return System.identityHashCode(myLeft)
              ^ System.identityHashCode(myRight);
     }
-    
+
     /**
      * The implementation of Ref.same(left, right)
      *
      * @see org.erights.e.elib.ref.Ref#same
      */
-    static public boolean same(Object left, Object right) 
+    static public boolean same(Object left, Object right)
     throws NotSettledException {
         FlexMap sofar = FlexMap.fromTypes(Equalizer.class, Void.TYPE);
         return same(left, right, sofar);
@@ -152,18 +154,18 @@
      */
     static private boolean same(Object left, Object right, FlexMap sofar)
     throws NotSettledException {
-        
+
         if (left == right) {
             if (Ref.isResolved(left) && Ref.isResolved(right)) {
                 //sameness of resolved objects is reflexive
                 return true;
             } else {
-                //XXX controversial: Should unresolved references have 
+                //XXX controversial: Should unresolved references have
                 //reflexive sameness?
                 throw new NotSettledException("it must be Resolved");
             }
         }
-        
+
         // null is only the same as itself
         if (null == left || null == right) {
             return false;
@@ -175,11 +177,11 @@
         if (sofar.maps(hypothesis)) {
             return true;
         }
-        
+
         // rest of sameness happens after simplification.
         left = simplify(left);
         right = simplify(right);
-        
+
         // sameness is recursive thru arrays
         if (left.getClass().isArray() && right.getClass().isArray()) {
             int len = Array.getLength(left);
@@ -217,9 +219,9 @@
             return false;
         }
 
-        // sameness defaults to .equals() for honorary Selfless objects.  
-        // Note that we check this after "instanceof Selfless", so if it's 
-        // both, it's considered to be really Selfless (as opposed to 
+        // sameness defaults to .equals() for honorary Selfless objects.
+        // Note that we check this after "instanceof Selfless", so if it's
+        // both, it's considered to be really Selfless (as opposed to
         // honorarily Selfless)
         Class leftClass = left.getClass();
         Class rightClass = right.getClass();
@@ -227,46 +229,46 @@
             && Selfless.HONORARY.has(rightClass))
         {
             return left.equals(right);
-            
-        /* unnecessary: 
+
+        /* unnecessary:
          * } else if (Selfless.HONORARY.has(leftClass)
          *            || Selfless.HONORARY.has(rightClass))
          * {
          *     return false;
          */
         }
-        
+
         // sameness is synchronous but monotonic
         if (!Ref.isResolved(left) || !Ref.isResolved(right)) {
             throw new NotSettledException("both must be Resolved");
         }
 
-        // otherwise, sameness is identical to Java's '==' which we've 
+        // otherwise, sameness is identical to Java's '==' which we've
         // already tested.  If we arrive here, it must've been false.
         return false;
     }
 
     /**
      * The implementation of 'Ref isSettled(ref)'
-     * 
+     *
      * @see org.erights.e.elib.ref.Ref#isSettled(Object)
      */
     static public boolean isSettled(Object obj) {
         IdentityMap sofar = new IdentityMap(Object.class, Void.TYPE);
         return isSettled(obj, sofar);
     }
-    
+
     /**
-     * Parallels the recursive logic of same/3, except that it only makes 
+     * Parallels the recursive logic of same/3, except that it only makes
      * things more efficient if we leave objects in sofar, so we do.
      */
     static private boolean isSettled(Object original, IdentityMap sofar) {
-        
+
         // null is NEAR and settled
         if (null == original) {
             return true;
         }
-        
+
         // It's the hypothesis we're already investigating.
         // Must happen before simplification, since it depends on EQ.
         if (sofar.maps(original)) {
@@ -275,9 +277,9 @@
 
         // rest of isSettled happens after simplification.
         Object obj = simplify(original);
-        
+
         // isSettled is recursive thru arrays
-        if (obj.getClass().isArray()) {            
+        if (obj.getClass().isArray()) {
             sofar.put(original, null);
             int len = Array.getLength(obj);
             for (int i = 0; i < len; i++) {
@@ -305,18 +307,18 @@
     }
 
     /**
-     * Two settled objects that are the same() must have the same 
+     * Two settled objects that are the same() must have the same
      * sameHash().  Only settled objects may be hashed.
      */
     static /*package*/ int sameHash(Object obj) throws NotSettledException {
         return sameHash(obj, HASH_DEPTH);
     }
-    
+
     /**
-     * Parallels the recursive logic of same/3, but uses a depth limit rather 
+     * Parallels the recursive logic of same/3, but uses a depth limit rather
      * than EQ to deal with cycles.
      */
-    static private int sameHash(Object obj, int hashDepth) 
+    static private int sameHash(Object obj, int hashDepth)
     throws NotSettledException {
         if (hashDepth < 0) {
             if (! isSettled(obj)) {
@@ -324,15 +326,15 @@
             }
             return -1;
         }
-        
+
         // null is only the same as itself
         if (null == obj) {
             return 0;
         }
-        
+
         // rest of sameness happens after simplification.
         obj = simplify(obj);
-        
+
         // sameness is recursive thru arrays
         if (obj.getClass().isArray()) {
             int len = Array.getLength(obj);
@@ -353,7 +355,7 @@
         if (Selfless.HONORARY.has(obj.getClass())) {
             return obj.hashCode();
         }
-        
+
         // sameness is synchronous but monotonic
         if (!Ref.isResolved(obj)) {
             throw new NotSettledException("must be resolved");



1.10      +20 -20    e/src/jsrc/org/erights/e/elib/tables/IdentityCacheTable.java

Index: IdentityCacheTable.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/IdentityCacheTable.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- IdentityCacheTable.java	2001/07/14 12:57:24	1.9
+++ IdentityCacheTable.java	2001/09/04 10:52:19	1.10
@@ -1,36 +1,36 @@
 package org.erights.e.elib.tables;
 
 /*
-The contents of this file are subject to the Electric Communities E Open 
-Source Code License Version 1.0 (the "License"); you may not use this file 
-except in compliance with the License. You may obtain a copy of the License 
+The contents of this file are subject to the Electric Communities E Open
+Source Code License Version 1.0 (the "License"); you may not use this file
+except in compliance with the License. You may obtain a copy of the License
 at http://www.communities.com/EL/.
 
-Software distributed under the License is distributed on an "AS IS" basis, 
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 the specific language governing rights and limitations under the License.
 
-The Original Code is the Distributed E Language Implementation, released 
-July 20, 1998. 
+The Original Code is the Distributed E Language Implementation, released
+July 20, 1998.
 
-The Initial Developer of the Original Code is Electric Communities.  
-Copyright (C) 1998 Electric Communities. All Rights Reserved. 
+The Initial Developer of the Original Code is Electric Communities.
+Copyright (C) 1998 Electric Communities. All Rights Reserved.
 
 Contributor(s): ______________________________________.
 */
 
 
 /**
- * Used to memoize the source strings/twine fed to QuasiParsers, and the 
- * mapping to the ValueMaker or MatchMaker it generated.  
+ * Used to memoize the source strings/twine fed to QuasiParsers, and the
+ * mapping to the ValueMaker or MatchMaker it generated.
  *
- * Once we go to the new hole-array protocol, this will have to be added to 
- * the memoization as well.  
+ * Once we go to the new hole-array protocol, this will have to be added to
+ * the memoization as well.
  *
- * Because IdentityCacheTable exposes EQ-ness of the keys, it is 
- * unsafe, and so (until we can audit for determinism) can only be used by 
- * trusted quasiParsers. 
- * 
+ * Because IdentityCacheTable exposes EQ-ness of the keys, it is
+ * unsafe, and so (until we can audit for determinism) can only be used by
+ * trusted quasiParsers.
+ *
  * Note: keys may not be null, but values may be null
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
@@ -39,7 +39,7 @@
 
     static private final int POSITIVE_MASK = 0x7FFFFFFF;
 
-    /** String or Twine other than SimpleTwine */
+    /** String or Twine other than SimpleTwine or EmptyTwine */
     private Object[] myKeys;
     private Column myValues;
     private int mySize;
@@ -52,7 +52,7 @@
         myValues = Column.values(valueType, size);
         mySize = size;
     }
-    
+
     /**
      *
      */
@@ -60,7 +60,7 @@
         if (key == null) {
             throw new NullPointerException("key may not be null");
         }
-        if (key instanceof SimpleTwine) {
+        if (key instanceof SimpleTwine || key instanceof EmptyTwine) {
             return key.bare();
         } else {
             return key;



1.6       +19 -11    e/src/jsrc/org/erights/e/elib/tables/LocatedTwine.java

Index: LocatedTwine.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/LocatedTwine.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- LocatedTwine.java	2001/08/20 21:17:50	1.5
+++ LocatedTwine.java	2001/09/04 10:52:19	1.6
@@ -30,14 +30,14 @@
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
 /*package*/ final class LocatedTwine extends AtomicTwine {
-    
+
     static private final long serialVersionUID = 2201288242995979823L;
-    
+
     /**
      *
      */
     private final SourceSpan mySpan;
-    
+
     /**
      *
      */
@@ -50,7 +50,7 @@
             throw new RuntimeException("one to one must have matching size");
         }
     }
-    
+
     /**
      * 'TwineMaker fromString(myStr, mySpan)'
      */
@@ -58,19 +58,27 @@
         Object[] result = { TwineMaker, "fromString", myStr, mySpan };
         return result;
     }
-    
+
     /**
-     * 
+     *
      */
     public boolean isBare() {
         return false;
     }
 
     /**
-     * Returns a Twine which is either empty or is a LocatedTwine describing 
-     * where the extracted run cam from.
+     * Returns a Twine which is either empty or is a LocatedTwine describing
+     * where the extracted run came from.
      */
     public ConstList run(int start, int bound) {
+        if (0 == start) {
+            //special cases worth checking
+            if (0 == bound) {
+                return EmptyTwine.THE_ONE;
+            } else if (size() == bound) {
+                return this;
+            }
+        }
         String str = myStr.substring(start, bound);
         SourceSpan span;
         if (mySpan.isOneToOne()) {
@@ -84,7 +92,7 @@
         }
         return Twine.fromString(str, span);
     }
-    
+
     /**
      * Just prints the string part.
      */
@@ -93,7 +101,7 @@
     }
 
     /**
-     * Two LocatedTwines can merge if the joining of their spans looses no 
+     * Two LocatedTwines can merge if the joining of their spans looses no
      * information.
      */
     /*package*/ ConstList mergedParts(AtomicTwine other) {
@@ -115,7 +123,7 @@
         Object[] parts = { this, other };
         return ConstList.fromArray(parts);
     }
-    
+
     /**
      *
      */



1.7       +18 -20    e/src/jsrc/org/erights/e/elib/tables/SimpleTwine.java

Index: SimpleTwine.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/SimpleTwine.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- SimpleTwine.java	2001/08/20 21:17:50	1.6
+++ SimpleTwine.java	2001/09/04 10:52:19	1.7
@@ -24,27 +24,25 @@
 import org.erights.e.elib.base.TextWriter;
 
 /**
- * A Twine containing only a String (possibly the empty string). <p>
+ * A Twine containing only a non-empty String. <p>
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
 /*package*/ final class SimpleTwine extends AtomicTwine {
-    
+
     static private final long serialVersionUID = -6842512130437927421L;
-    
-    /**
-     * The empty Twine.
-     */
-    static public final Twine EmptyTwine =
-        new SimpleTwine("");
-        
+
     /**
      *
      */
     /*package*/ SimpleTwine(String str) {
         super(str);
+        if (str.length() <= 0) {
+            throw new RuntimeException
+                    ("internal: SimpleTwine must be non-empty");
+        }
     }
-    
+
     /**
      * 'TwineMaker fromString(myStr)'
      */
@@ -54,12 +52,12 @@
     }
 
     /**
-     * 
+     *
      */
     public boolean isBare() {
         return true;
     }
-    
+
 
     /**
      *
@@ -67,13 +65,6 @@
     public ConstList run(int start, int bound) {
         return Twine.fromString(myStr.substring(start, bound));
     }
-    
-    /**
-     *
-     */
-    public void printOn(TextWriter out) throws IOException {
-        out.print(myStr);
-    }
 
     /**
      *
@@ -86,11 +77,18 @@
         Object[] parts = { this, other };
         return ConstList.fromArray(parts);
     }
-    
+
     /**
      *
      */
     public SourceSpan optSourceSpan() {
         return null;
+    }
+
+    /**
+     *
+     */
+    public void printOn(TextWriter out) throws IOException {
+        out.print(myStr);
     }
 }



1.17      +123 -122  e/src/jsrc/org/erights/e/elib/tables/Twine.java

Index: Twine.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/Twine.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- Twine.java	2001/08/21 13:36:19	1.16
+++ Twine.java	2001/09/04 10:52:19	1.17
@@ -1,20 +1,20 @@
 package org.erights.e.elib.tables;
 
 /*
-The contents of this file are subject to the Electric Communities E Open 
-Source Code License Version 1.0 (the "License"); you may not use this file 
-except in compliance with the License. You may obtain a copy of the License 
+The contents of this file are subject to the Electric Communities E Open
+Source Code License Version 1.0 (the "License"); you may not use this file
+except in compliance with the License. You may obtain a copy of the License
 at http://www.communities.com/EL/.
 
-Software distributed under the License is distributed on an "AS IS" basis, 
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 the specific language governing rights and limitations under the License.
 
-The Original Code is the Distributed E Language Implementation, released 
-July 20, 1998. 
+The Original Code is the Distributed E Language Implementation, released
+July 20, 1998.
 
-The Initial Developer of the Original Code is Electric Communities.  
-Copyright (C) 1998 Electric Communities. All Rights Reserved. 
+The Initial Developer of the Original Code is Electric Communities.
+Copyright (C) 1998 Electric Communities. All Rights Reserved.
 
 Contributor(s): ______________________________________.
 */
@@ -27,94 +27,95 @@
 /**
  * Like a String, except that it keeps track of original source positions.
  * <p>
- * Twine has exactly two immediate subclasses -- AtomicTwine and 
- * CompositeTwine.  Both will give their contents as a list of AtomicTwine.  
- * Only AtomicTwine gives accurate source positions, so to be accurate you 
- * have to enumerate these.
- *
- * To the E programmer, Twine will act like a String and automagically coerce 
- * to String (the String part of the twine).  A String will also 
- * automagically coerce to a SimpleTwine (an AtomicTwine with no source 
- * info).  As a ConstList, Twine acts just like a list of the Characters from 
- * the String part. <p>
- *
- * Twine and its subclasses replace the old ConstString and StringSugar while 
- * doing a lot more. <p> 
- *
- * Implementation note: The Equalizer's simplification rules depend on Twine 
- * that's the same() as a String actually being a SimpleTwine.
+ * Twine has exactly three immediate subclasses -- EmptyTwine, AtomicTwine
+ * and CompositeTwine.  These will give their contents as a list of
+ * AtomicTwine.  Only AtomicTwine gives accurate source positions, so to be
+ * accurate you have to enumerate these.  (EmptyTwine has no source
+ * position.)
+ * <p>
+ * To the E programmer, Twine will act like a String and automagically coerce
+ * to String (the String part of the twine).  A String will also
+ * automagically coerce to a SimpleTwine (an AtomicTwine with no source
+ * info) or an EmptyTwine.  As a ConstList, Twine acts just like a list of
+ * the Characters from the String part.
+ * <p>
+ * Twine and its subclasses replace the old ConstString and StringSugar while
+ * doing a lot more.
+ * <p>
+ * Implementation note: The Equalizer's simplification rules depend on Twine
+ * that's the same() as a String actually being a SimpleTwine or EmptyTwine.
  *
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
  */
 public abstract class Twine extends ConstList {
-    
+
     static private final long serialVersionUID = 5436911677426527143L;
-    
+
     /**
      *
      */
     static public final StaticMaker TwineMaker =
         StaticMaker.make(Twine.class);
-        
+
     /**
-     * Package scoped to deter the creation of any other immediate subclasses 
+     * Package scoped to deter the creation of any other immediate subclasses
      * besides AtomicTwine and CompositeTwine.
      */
     /*package*/ Twine() {}
-    
+
     /**
      * Make a Twine whose parts are this list of AtomicTwines. <p>
      *
-     * The list of parts is assumed to already be maximally merged.  If it's 
-     * an empty list, return the empty SimpleTwine.  If it's
-     * a singleton list, return that part.  Otherwise return a CompositeTwine 
+     * The list of parts is assumed to already be maximally merged.  If it's
+     * an empty list, return the EmptyTwine.  If it's
+     * a singleton list, return that part.  Otherwise return a CompositeTwine
      * on these parts.
      */
     static public Twine fromParts(ConstList parts) {
         if (parts.size() == 0) {
-            return SimpleTwine.EmptyTwine;
+            return EmptyTwine.THE_ONE;
         } else if (parts.size() == 1) {
             return (Twine)parts.get(0);
         } else {
             return new CompositeTwine(parts);
         }
     }
-    
+
     /**
      * Makes a Twine with no information besides str. <p>
      *
-     * If str is empty, returns the empty CompositeTwine.  Otherwise, returns 
+     * If str is empty, returns the empty CompositeTwine.  Otherwise, returns
      * a new SimpleTwine on str.
      */
     static public Twine fromString(String str) {
         return fromString(str, null);
     }
-    
+
     /**
      * Makes a Twine on str from optSourceSpan. <p>
      *
-     * If str is empty, returns the empty CompositeTwine.  Otherwise, returns 
-     * a new SimpleTwine on str.
+     * If str is empty, returns the EmptyTwine.  Otherwise, returns
+     * a new SimpleTwine on str or a LocatedTwine on both args.
      */
     static public Twine fromString(String str, SourceSpan optSourceSpan) {
         if (str.length() == 0) {
-            return SimpleTwine.EmptyTwine;
+            return EmptyTwine.THE_ONE;
         } else if (null == optSourceSpan) {
             return new SimpleTwine(str);
         } else {
             return new LocatedTwine(str, optSourceSpan);
         }
     }
-    
+
     /**
-     * @return a list of AtomicTwines.  An empty Twine is represented by a 
-     * CompositeTwine with no parts, which therefore returns the empty list.
+     * @return A list of AtomicTwines.  An empty Twine returns the empty
+     *         list.
      */
     public abstract ConstList getParts();
-    
+
     /**
-     * If pos is a position within this Twine, return a pair consisting of 
-     * the index in the getParts() list of the AtomicTwine containing this 
+     * If pos is a position within this Twine, return a pair consisting of
+     * the index in the getParts() list of the AtomicTwine containing this
      * position, and the offset into this part of this position.
      */
     public int[] getPartAt(int pos)
@@ -136,20 +137,20 @@
         throw new IndexOutOfBoundsException
             ("" + pos + " bigger than " + sofar);
     }
-    
+
     /**
-     * Returns a mapping from intervals in the Twine to spans showing where 
+     * Returns a mapping from intervals in the Twine to spans showing where
      * they came from. <p>
      *
-     * Unfortunately, because of the way the E implementation is layered, the 
-     * keys in this mapping cannot be integer-regions (as these are 
-     * implemented in the E language, which is in a layer that depends on 
-     * this layer, and we're trying to avoid inter-layer cyclic 
-     * dependencies).  Instead, the keys are represented as a pair of ints 
-     * representing start..!bound.  Note that this is inclusive-exclusive, 
+     * Unfortunately, because of the way the E implementation is layered, the
+     * keys in this mapping cannot be integer-regions (as these are
+     * implemented in the E language, which is in a layer that depends on
+     * this layer, and we're trying to avoid inter-layer cyclic
+     * dependencies).  Instead, the keys are represented as a pair of ints
+     * representing start..!bound.  Note that this is inclusive-exclusive,
      * while the info in the spans are inclusive-inclusive. <p>
      *
-     * The mapping is ordered to facilitate binary search.  Intervals with no 
+     * The mapping is ordered to facilitate binary search.  Intervals with no
      * SourceSpan information are left out of the map.
      */
     public ConstMap getSourceMap() {
@@ -171,43 +172,43 @@
         }
         return result.snapshot();
     }
-    
+
     /**
      * Explicitly gets the String part of the twine.  <p>
-     * 
-     * When using this call, this call itself will be the top level construct 
+     *
+     * When using this call, this call itself will be the top level construct
      * for breaking cycles.  XXX where & what do we stabilize?
      */
     public abstract String bare();
-    
+
     /**
      * Is the bare string all the info there is?
      */
     public abstract boolean isBare();
-    
+
     /**
      * Gets the sourceSpan part of the twine, if it's there. <p>
      *
-     * If this is an AtomicTwine, then, if the SourceSpan is there, it's as 
-     * accurate as you're going to get.  If this is a CompositeTwine, then, 
-     * if the SourceSpan is there, it describes a span that includes all the 
-     * individual spans.  If a CompositeTwine returns null, there may still 
-     * be SourceSpans on the atomic parts, but they couldn't all be 
+     * If this is an AtomicTwine, then, if the SourceSpan is there, it's as
+     * accurate as you're going to get.  If this is a CompositeTwine, then,
+     * if the SourceSpan is there, it describes a span that includes all the
+     * individual spans.  If a CompositeTwine returns null, there may still
+     * be SourceSpans on the atomic parts, but they couldn't all be
      * summarized into one covering span.
      */
     public abstract SourceSpan optSourceSpan();
-    
+
     /**
-     * Returns a Twine with str as the string part, and the source info from 
-     * this Twine.  The default implementation here drops all source info. 
+     * Returns a Twine with str as the string part, and the source info from
+     * this Twine.  The default implementation here drops all source info.
      * XXX make abstract and implement overrides
      */
     public Twine infect(String str) {
         return Twine.fromString(str);
     }
-    
+
     /**
-     * Return a new Twine that represents a concatenation of the parts of 
+     * Return a new Twine that represents a concatenation of the parts of
      * this and other.  <p>
      *
      * The last part of this may be merged with the first part of other.
@@ -225,7 +226,7 @@
         int mineSize = mine.size();
         ConstList his = otherTwine.getParts();
         int hisSize = his.size();
-        
+
         if (mineSize >= 1 && hisSize >= 1) {
             mineSize--;
             AtomicTwine lastMine = (AtomicTwine)mine.get(mineSize);
@@ -233,25 +234,25 @@
             AtomicTwine firstHis = (AtomicTwine)his.get(0);
             his = his.run(1, hisSize);
             hisSize--;
-            
+
             mine = mine.add(lastMine.mergedParts(firstHis));
         }
         return Twine.fromParts(mine.add(his));
     }
-    
+
     /**
      * The result will be a Twine
      */
     public ConstList multiply(int reps) {
-        Twine result = SimpleTwine.EmptyTwine;
+        Twine result = EmptyTwine.THE_ONE;
         for (int i = 0; i < reps; i++) {
             result = (Twine)result.add(this);
         }
         return result;
     }
-    
+
     /**
-     * Each crlf is turned into an lf to deal with MSWindows, and then each 
+     * Each crlf is turned into an lf to deal with MSWindows, and then each
      * remaining cr is turned into an lf to deal with Mac.
      */
     public Twine canonical() {
@@ -261,7 +262,7 @@
             return replaceAll("\r\n", "\n").replaceAll("\r", "\n");
         }
     }
-    
+
     /**
      * Returns a Twine.
      */
@@ -273,9 +274,9 @@
      * Returns a Twine.
      */
     public abstract ConstList run(int start, int bound);
-    
+
     /**
-     * Returns a string that, when interpreted as a literal, represents the 
+     * Returns a string that, when interpreted as a literal, represents the
      * original string.
      */
     public Twine quote() {
@@ -313,21 +314,21 @@
         }
         result = (Twine)result.add(run(p1, len)).add("\"");
         return result;
-    }        
+    }
 
     /******************** ConstList methods *********************/
-    
+
     /**
      *
      */
     public Object get(int index) throws IndexOutOfBoundsException {
-        //It's surprising there's no "Character.valueOf(char)", so there 
+        //It's surprising there's no "Character.valueOf(char)", so there
         //could be a cache, as with BigInteger.
         return new Character(charAt(index));
     }
-    
+
     /**
-     * Optimized for the case where both are Twine.  Otherwise should be 
+     * Optimized for the case where both are Twine.  Otherwise should be
      * identical.
      */
     public double compareTo(ConstList other) {
@@ -337,52 +338,52 @@
             return super.compareTo(other);
         }
     }
-    
+
     /**
      * @return Character.class
      */
     public Class valueType() {
         return Character.class;
     }
-    
+
     /******************** Imitation of String methods *********************/
-    
+
     /**
-     * From the E language, this is identical to get/1.  But we provide it so 
+     * From the E language, this is identical to get/1.  But we provide it so
      * the ELib programmer can avoid boxing the character.
      *
      * @see String#charAt
      */
     public abstract char charAt(int index) throws IndexOutOfBoundsException;
-    
+
     /**
      * @see String#compareToIgnoreCase
      */
     public int compareToIgnoreCase(String other) {
         return bare().compareToIgnoreCase(other);
     }
-    
+
     /**
      * @see String#startsWith
      */
     public boolean startsWith(String prefix) {
         return bare().startsWith(prefix);
     }
-    
+
     /**
      * @see String#startsWith
      */
     public boolean startsWith(String prefix, int offset) {
         return bare().startsWith(prefix, offset);
     }
-    
+
     /**
      * @see String#endsWith
      */
     public boolean endsWith(String suffix) {
         return bare().endsWith(suffix);
     }
-    
+
     /**
      * In E, the encoding always defaults to "UTF-8", period.
      *
@@ -391,17 +392,17 @@
     public byte[] getBytes() throws UnsupportedEncodingException {
         return getBytes("UTF-8");
     }
-    
+
     /**
      * @see String#getBytes
      */
     public byte[] getBytes(String enc) throws UnsupportedEncodingException {
         return bare().getBytes(enc);
     }
-    
+
     /**
-     * Twine only support the *indexOf(...) operations that take a String, 
-     * not those that take a character (in order to avoid type-based 
+     * Twine only support the *indexOf(...) operations that take a String,
+     * not those that take a character (in order to avoid type-based
      * overloading).
      *
      * @see String#indexOf
@@ -409,44 +410,44 @@
     public int indexOf(String str) {
         return bare().indexOf(str);
     }
-    
+
     /**
      * @see String#indexOf
      */
     public int indexOf(String str, int fromIndex) {
         return bare().indexOf(str, fromIndex);
     }
-    
+
     /**
      * @see String#lastIndexOf
      */
     public int lastIndexOf(String str) {
         return bare().lastIndexOf(str);
     }
-    
+
     /**
      * @see String#lastIndexOf
      */
     public int lastIndexOf(String str, int fromIndex) {
         return bare().lastIndexOf(str, fromIndex);
     }
-    
+
     /**
-     * In E, we have the string-based replaceAll() rather than the 
+     * In E, we have the string-based replaceAll() rather than the
      * character-based replace(). <p>
      *
-     * For each match, the source info from the twine matching oldStr infects 
-     * the substituted newStr.  Ignoring the source info, 
-     * 'str replaceAll(oldStr, newStr)' should be equivalent to 
+     * For each match, the source info from the twine matching oldStr infects
+     * the substituted newStr.  Ignoring the source info,
+     * 'str replaceAll(oldStr, newStr)' should be equivalent to
      * 'newStr rjoin(str split(oldStr))'. <p>
      *
-     * If oldStr is the null string (""), replaceAll() throws an 
-     * IllegalArgumentException. 
+     * If oldStr is the null string (""), replaceAll() throws an
+     * IllegalArgumentException.
      *
      * @see String#replace
      */
     public Twine replaceAll(String oldStr, String newStr) {
-        Twine result = SimpleTwine.EmptyTwine;
+        Twine result = EmptyTwine.THE_ONE;
         int oldLen = oldStr.length();
         if (0 == oldLen) {
             throw new IllegalArgumentException
@@ -462,16 +463,16 @@
         result = (Twine)result.add(run(p1, size()));
         return result;
     }
-    
+
     /**
-     * Like Python's splitFields(), this returns a list of the "fields" of 
+     * Like Python's splitFields(), this returns a list of the "fields" of
      * this twine (substrings of this twine), using 'sep' as a separator. <p>
      *
-     * The returned list will have one more element than the number of 
+     * The returned list will have one more element than the number of
      * non-overlapping occurrences of 'sep'. <p>
      *
      * Unlike Python, if sep is the null string (""), split() throws an
-     * IllegalArgumentException. 
+     * IllegalArgumentException.
      */
     public ConstList split(String sep) {
         FlexList result = FlexList.fromType(Twine.class);
@@ -488,18 +489,18 @@
         result.push(run(p1, size()));
         return result.snapshot();
     }
-    
+
     /**
-     * Like Python's joinFields(), but with the receiver and argument 
-     * reversed (hense the initial "r"). <p>
+     * Like Python's joinFields(), but with the receiver and argument
+     * reversed (hence the initial "r"). <p>
      *
-     * Concatenates the fields with this twine as the intervening separator.  
-     * Ignoring source info, and if 'sep' is not the null string, 
+     * Concatenates the fields with this twine as the intervening separator.
+     * Ignoring source info, and if 'sep' is not the null string,
      * 'sep rjoin(str split(sep))' should be equivalent to 'str'.
      */
     public Twine rjoin(Twine[] fields) {
         if (0 == fields.length) {
-            return SimpleTwine.EmptyTwine;
+            return EmptyTwine.THE_ONE;
         }
         Twine result = fields[0];
         for (int i = 1; i < fields.length; i++) {
@@ -507,28 +508,28 @@
         }
         return result;
     }
-    
+
     /**
      *
      */
     public String toString() {
         return bare();
     }
-    
+
     /**
      *
      */
     public String toLowerCase() {
         return bare().toLowerCase();
     }
-    
+
     /**
      *
      */
     public String toUpperCase() {
         return bare().toUpperCase();
     }
-    
+
     /**
      *
      */



1.1                  e/src/jsrc/org/erights/e/elib/tables/EmptyTwine.java

Index: EmptyTwine.java
===================================================================
package org.erights.e.elib.tables;

import org.erights.e.elib.base.TextWriter;
import org.erights.e.elib.base.SourceSpan;

import java.io.IOException;

/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.

The Original Code is the Distributed E Language Implementation, released
July 20, 1998.

The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.

Contributor(s): ______________________________________.
*/


/**
 * The canonical empty Twine.
 * <p>
 * The EmptyTwine is always bare.
 *
 * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
 */
/*package*/ class EmptyTwine extends Twine {

    //static private final long serialVersionUID = ???;

    /**
     * The canonical instance
     */
    static /*package*/ Twine THE_ONE = new EmptyTwine();

    /**
     *
     */
    static private Object[] CanonicalState =
            { TwineMaker, "fromString", "" };

    /**
     *
     */
    private EmptyTwine() {}

    /**
     * 'TwineMaker fromString("")'
     */
    public Object[] getCanonicalState() {
        return CanonicalState;
    }

    /**
     *
     */
    public char charAt(int index) throws IndexOutOfBoundsException {
        throw new IndexOutOfBoundsException("out of range: " + index);
    }

    /**
     *
     */
    public int size() {
        return 0;
    }

    /**
     *
     */
    public String bare() {
        return "";
    }

    /**
     *
     */
    public boolean isBare() {
        return true;
    }

    /**
     *
     */
    public ConstList run(int start, int bound) {
        if (0 == start && 0 == bound) {
            return this;
        } else {
            throw new IndexOutOfBoundsException
                    ("running on empty " + start + "..!" + bound);
        }
    }

    /**
     *
     */
    public ConstList getParts() {
        return ConstList.EmptyList;
    }

    /**
     *
     */
    public SourceSpan optSourceSpan() {
        return null;
    }

    /**
     *
     */
    public void printOn(TextWriter out) throws IOException {
        //XXX is this the same as printing nothing?
        out.print("");
    }
}