2003/06/08 23:48:03
authormegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:00:53 +0000 (07:00 +0000)
committermegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:00:53 +0000 (07:00 +0000)
darcs-hash:20040130070053-2ba56-b43f7c42bf8c8f9566e0707c8e5c38d3a6e2f4e2.gz

src/org/xwt/js/ByteCodeBlock.java
src/org/xwt/js/ByteCodes.java
src/org/xwt/js/JS.java
src/org/xwt/js/Lexer.java
src/org/xwt/js/Parser.java
src/org/xwt/js/Tokens.java

index fb2d1f5..a0e675c 100644 (file)
@@ -4,24 +4,28 @@ package org.xwt.js;
 import org.xwt.util.*;
 import java.io.*;
 
-/**
- *  A block of JavaScript bytecode.
- *
- *  The JavaScript ByteCode runs on a very simple stack machine.
- */
+/** A block of JavaScript bytecode run on a very simple stack machine. */
 class ByteCodeBlock implements ByteCodes, Tokens {
 
-    int line;
-    String sourceName;
-    int[] op = new int[10];
-    Object[] arg = new Object[10];
-    int size = 0;
+    // FIXME: this should be line-by-line
+    private int line;
+    private String sourceName;
+
+    /** the instructions */
+    private int[] op = new int[10];
+
+    /** the arguments to the instructions */
+    private Object[] arg = new Object[10];
+
+    /** the number of instruction/argument pairs */
+    private int size = 0;
 
     public ByteCodeBlock(int line, String sourceName) { this.line = line; this.sourceName = sourceName; }
-    public ByteCodeBlock(int line, String sourceName, int op_, Object arg_) { this(line, sourceName); add(op_, arg_); }
+    public String getSourceName() { return sourceName; }
 
     public int size() { return size; }
     public void set(int pos, int op_, Object arg_) { op[pos] = op_; arg[pos] = arg_; }
+    public void set(int pos, Object arg_) { arg[pos] = arg_; }
     public void paste(ByteCodeBlock other) { for(int i=0; i<other.size; i++) add(other.op[i], other.arg[i]); }
     public ByteCodeBlock add(int op_) { return add(op_, null); }
     public ByteCodeBlock add(int op_, Object arg_) {
@@ -55,12 +59,11 @@ class ByteCodeBlock implements ByteCodes, Tokens {
             case RETURN: throw new ReturnException(t.pop());
             case THROW: throw new JS.Exn(t.pop());
             case TRY: break;
-            case INSTANCEOF: break;
             case TYPEOF: break;
-            case BITNOT: t.push(new Long(~JS.toLong(t.pop()))); break;
-            case BANG: t.push(new Boolean(!JS.toBoolean(t.pop()))); break;
             case BREAK: return Boolean.FALSE;
             case CONTINUE: return Boolean.TRUE;
+            case BITNOT: t.push(new Long(~JS.toLong(t.pop()))); break;
+            case BANG: t.push(new Boolean(!JS.toBoolean(t.pop()))); break;
 
             case PUSHKEYS: {
                 Object o = t.peek();
index 8e79a9a..62908af 100644 (file)
@@ -4,15 +4,13 @@ package org.xwt.js;
 /**
  *  Constants for the various JavaScript ByteCode operations.
  *
- *  Each instruction is an opcode and an optional literal literal; the
- *  arithmetic Tokens are also valid.  They are: BITOR, BITXOR, BITAND,
- *  ADD, INC, DEC, SUB, MUL, DIV, MOD, LSH, RSH, URSH, LT, LE, GT, GE,
- *  EQ, NE
+ *  Each instruction is an opcode and an optional literal literal;
+ *  some Tokens are also valid; see Tokens.java
  */
 interface ByteCodes {
 
     /** push the literal onto the stack */
-    public static final byte LITERAL = -2;       
+    public static final byte LITERAL = -2;
 
     /** push a new array onto the stack with length equal to the literal */
     public static final byte ARRAY = -3;         
@@ -33,19 +31,19 @@ interface ByteCodes {
     public static final byte GET = -8;           
 
     /** push stack[-1].get(stack[top]) */
-    public static final byte GET_PRESERVE = -80; 
+    public static final byte GET_PRESERVE = -9; 
 
     /** pop two elements off the stack; stack[-2].put(stack[-1], stack[top]); push stack[top] */
-    public static final byte PUT = -9;           
+    public static final byte PUT = -10;           
 
     /** literal is a relative address; pop stacktop and jump if the value is true */
-    public static final byte JT = -13;           
+    public static final byte JT = -11;           
 
     /** literal is a relative address; pop stacktop and jump if the value is false */
-    public static final byte JF = -21;           
+    public static final byte JF = -12;           
 
     /** literal is a relative address; jump to it */
-    public static final byte JMP = -22;          
+    public static final byte JMP = -13;          
 
     /** discard the top stack element */
     static public final byte POP = -14;          
@@ -54,22 +52,22 @@ interface ByteCodes {
     public static final byte CALL = -15;         
 
     /** pop an element; push a JS.Array containing the keys of the popped element */
-    public static final byte PUSHKEYS = -19;     
+    public static final byte PUSHKEYS = -16;     
 
     /** swap the top two elements on the stack */
-    public static final byte SWAP = -23;         
+    public static final byte SWAP = -17;         
 
     /** execute the ForthBlock pointed to by the literal in a fresh scope with parentScope==THIS */
-    public static final byte SCOPE = -30;        
+    public static final byte SCOPE = -18;        
 
     /** push a copy of the top stack element */
-    public static final byte DUP = -50;          
+    public static final byte DUP = -19;          
 
     /** declare a label */
-    public static final byte LABEL = -60;        
+    public static final byte LABEL = -20;        
 
     /** execute the ForthBlock pointed to by the literal until BREAK encountered; push TRUE onto the stack for the first iteration
      *  and FALSE for all subsequent iterations */
-    public static final byte LOOP = -40;         
+    public static final byte LOOP = -21;         
 
 }
index c6b4c77..ea117c4 100644 (file)
@@ -156,7 +156,7 @@ public abstract class JS {
     public static class Script extends Function {
        Vector e = null;
        private Script(Vector e) { this.e = e; }
-       public String getSourceName() throws JS.Exn { return ((ByteCodeBlock)e.elementAt(0)).sourceName; }
+       public String getSourceName() throws JS.Exn { return ((ByteCodeBlock)e.elementAt(0)).getSourceName(); }
        public Object _call(JS.Array args) throws JS.Exn, ByteCodeBlock.ControlTransferException {
            Scope rootScope = (Scope)args.elementAt(0);
            for(int i=0; i<e.size(); i++) ((ByteCodeBlock)e.elementAt(i)).eval(rootScope);
index f20901b..f49310b 100644 (file)
 package org.xwt.js;
 import java.io.*;
 
+/** Lexes a stream of characters into a stream of Tokens */
 class Lexer implements Tokens {
 
+    /** for debugging */
     public static void main(String[] s) throws Exception {
        Lexer l = new Lexer(new InputStreamReader(System.in));
        int tok = 0;
-       while((tok = l.getToken()) != -1)
-           System.out.println(codeToString[tok]);
+       while((tok = l.getToken()) != -1) System.out.println(codeToString[tok]);
     }
 
-    public int op;
-    public Number number = null;
-    public String string = null;
+    /** the token that was just parsed */
+    protected int op;
 
-    public int line = 0;
-    public int col = 0;
+    /** if the token just parsed was a NUMBER, this is the numeric value */
+    protected Number number = null;
 
-    private SmartReader in;
-    public String sourceName = "unknown";
+    /** if the token just parsed was a NAME or STRING, this is the string value */
+    protected String string = null;
+
+    /** the line number of the current token */
+    protected int line = 0;
+
+    /** the column number of the current token */
+    protected int col = 0;
 
+    /** the name of the source code file being lexed */
+    protected String sourceName = "unknown";
+
+    private SmartReader in;
     public Lexer(Reader r) throws IOException { in = new SmartReader(r); }
 
 
     // Predicates ///////////////////////////////////////////////////////////////////////
 
-    protected static boolean isJSIdentifier(String s) {
-        int length = s.length();
-        if (length == 0 || !Character.isJavaIdentifierStart(s.charAt(0))) return false;
-        for (int i=1; i<length; i++) {
-            char c = s.charAt(i);
-            if (!Character.isJavaIdentifierPart(c) && c == '\\' && !((i + 5) < length) &&
-                (s.charAt(i + 1) == 'u') && 0 <= xDigitToInt(s.charAt(i + 2)) && 0 <= xDigitToInt(s.charAt(i + 3)) && 
-                0 <= xDigitToInt(s.charAt(i + 4)) && 0 <= xDigitToInt(s.charAt(i + 5)))
-                return false;
-        }
-        return true;
-    }
-
     private static boolean isAlpha(int c) { return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); }
     private static boolean isDigit(int c) { return (c >= '0' && c <= '9'); }
-    private static boolean isLineBreak(int c) { return (c == '\n' || c == '\r' || c == 0x2028 || c == 0x2029); }
     private static int xDigitToInt(int c) {
         if ('0' <= c && c <= '9') return c - '0';
-        if ('a' <= c && c <= 'f') return c - ('a' - 10);
-        if ('A' <= c && c <= 'F') return c - ('A' - 10);
-        return -1;
-    }
-    public static boolean isWhiteSpace(int c) {
-        if (c == '\u0020' || c == '\u0009' || c == '\u000C' || c == '\u000B' || c == '\u00A0') return true;
-        return Character.getType((char)c) == Character.SPACE_SEPARATOR;
+        else if ('a' <= c && c <= 'f') return c - ('a' - 10);
+        else if ('A' <= c && c <= 'F') return c - ('A' - 10);
+        else return -1;
     }
 
     
@@ -175,9 +167,9 @@ class Lexer implements Tokens {
         in.unread();
         String str = in.getString();
         int result = getKeyword(str);
-       if (result == RESERVED) throw new IOException("the reserved word \"" + str + "\" is not permitted in XWT scripts");
+       if (result == RESERVED) throw new LexerException("The reserved word \"" + str + "\" is not permitted in XWT scripts");
         if (result != -1) return result;
-        this.string = str;
+        this.string = str.intern();
         return NAME;
     }
     
@@ -201,7 +193,7 @@ class Lexer implements Tokens {
             if (c == 'e' || c == 'E') {
                 c = in.read();
                 if (c == '+' || c == '-') c = in.read();
-                if (!isDigit(c)) throw new IOException("msg.missing.exponent");
+                if (!isDigit(c)) throw new LexerException("float listeral did not have an exponent value");
                 do { c = in.read(); } while (isDigit(c));
             }
         }
@@ -210,7 +202,7 @@ class Lexer implements Tokens {
         String numString = in.getString();
         if (base == 10 && !isInteger) {
             try { dval = (Double.valueOf(numString)).doubleValue(); }
-            catch (NumberFormatException ex) { throw new IOException("msg.caught.nfe"); }
+            catch (NumberFormatException ex) { throw new LexerException("invalid numeric literal: \"" + numString + "\""); }
         } else {
             if (isInteger) {
                 longval = Long.parseLong(numString, base);
@@ -237,7 +229,7 @@ class Lexer implements Tokens {
         c = in.read();
         in.startString(); // start after the first "
         while(c != quoteChar) {
-            if (c == '\n' || c == -1) throw new IOException("msg.unterminated.string.lit");
+            if (c == '\n' || c == -1) throw new LexerException("unterminated string literal");
             if (c == '\\') {
                 if (stringBuf == null) {
                     in.unread();   // Don't include the backslash
@@ -257,7 +249,7 @@ class Lexer implements Tokens {
                    for(int i=0; i<4; i++) {
                        int ci = in.read();
                        if (!((ci >= '0' && ci <= '9') || (ci >= 'a' && ci <= 'f') || (ci >= 'A' && ci <= 'F')))
-                           throw new IOException("illegal character '" + ((char)c) + "' in \\u unicode escape sequence");
+                           throw new LexerException("illegal character '" + ((char)c) + "' in \\u unicode escape sequence");
                        v = (v << 8) | Integer.parseInt(ci + "", 16);
                    }
                    c = (char)v;
@@ -271,10 +263,10 @@ class Lexer implements Tokens {
             if (stringBuf != null) stringBuf.append((char) c);
             c = in.read();
         }
-        if (stringBuf != null) this.string = stringBuf.toString();
+        if (stringBuf != null) this.string = stringBuf.toString().intern();
         else {
             in.unread(); // miss the trailing "
-            this.string = in.getString();
+            this.string = in.getString().intern();
             in.read();
         }
         return STRING;
@@ -282,13 +274,12 @@ class Lexer implements Tokens {
 
     public int _getToken() throws IOException {
         int c;
-        do { if ((c = in.read()) == '\n') break; } while (isWhiteSpace(c) || c == '\n');
+        do { c = in.read(); } while (c == '\u0020' || c == '\u0009' || c == '\u000C' || c == '\u000B' || c == '\n' );
         if (c == -1) return -1;
         if (c == '\\' || Character.isJavaIdentifierStart((char)c)) return getIdentifier(c);
         if (isDigit(c) || (c == '.' && isDigit(in.peek()))) return getNumber(c);
         if (c == '"' || c == '\'') return getString(c);
         switch (c) {
-        case '\n': return EOL;
         case ';': return SEMI;
         case '[': return LB;
         case ']': return RB;
@@ -310,14 +301,9 @@ class Lexer implements Tokens {
         case '+': return in.match('=') ? ASSIGN_ADD : in.match('+') ? INC : ADD;
         case '-': return in.match('=') ? ASSIGN_SUB: in.match('-') ? DEC : SUB;
         case '*': return in.match('=') ? ASSIGN_MUL : MUL;
-        case '<': return !in.match('<') ?
-                             (in.match('=') ? LE : LT) :
-                             in.match('=') ? ASSIGN_LSH : LSH;
-        case '>': return !in.match('>') ?
-                             (in.match('=') ? GE : GT) :
-                             in.match('>') ?
-                                (in.match('=') ? ASSIGN_URSH : URSH) :
-                                 (in.match('=') ? ASSIGN_RSH : RSH);
+        case '<': return !in.match('<') ? (in.match('=') ? LE : LT) : in.match('=') ? ASSIGN_LSH : LSH;
+        case '>': return !in.match('>') ? (in.match('=') ? GE : GT) :
+           in.match('>') ? (in.match('=') ? ASSIGN_URSH : URSH) : (in.match('=') ? ASSIGN_RSH : RSH);
         case '/':
             if (in.match('=')) return ASSIGN_DIV;
             if (in.match('/')) { while ((c = in.read()) != -1 && c != '\n'); in.unread(); return getToken(); }
@@ -325,14 +311,18 @@ class Lexer implements Tokens {
             while ((c = in.read()) != -1 && !(c == '*' && in.match('/'))) {
                 if (c == '\n' || c != '/' || !in.match('*')) continue;
                 if (in.match('/')) return getToken();
-                throw new IOException("msg.nested.comment");
+                throw new LexerException("nested comments are not permitted");
             }
-            if (c == -1) throw new IOException("msg.unterminated.comment");
+            if (c == -1) throw new LexerException("unterminated comment");
             return getToken();  // `goto retry'
-        default: throw new IOException("illegal character: " + ((char)c));
+        default: throw new LexerException("illegal character: \'" + ((char)c) + "\'");
         }
     }
 
+
+    // SmartReader ////////////////////////////////////////////////////////////////
+
+    /** a Reader that tracks line numbers and can push back tokens */
     private class SmartReader {
         PushbackReader reader = null;
         int lastread = -1;
@@ -353,6 +343,7 @@ class Lexer implements Tokens {
             lastread = reader.read();
             if (accumulator != null) accumulator.append((char)lastread);
            if (lastread != '\n' && lastread != '\r') col++;
+           if (lastread == '\n') { line++; col = 0; }
             return lastread;
         }
 
@@ -370,12 +361,13 @@ class Lexer implements Tokens {
     }
 
 
-    // PushBack Stuff ////////////////////////////////////////////////////////////
+    // Token PushBack code ////////////////////////////////////////////////////////////
 
-    int pushBackDepth = 0;
-    int[] pushBackInts = new int[10];
-    Object[] pushBackObjects = new Object[10];
+    private int pushBackDepth = 0;
+    private int[] pushBackInts = new int[10];
+    private Object[] pushBackObjects = new Object[10];
 
+    /** push back a token */
     public void pushBackToken(int op, Object obj) {
        if (pushBackDepth >= pushBackInts.length - 1) {
            int[] newInts = new int[pushBackInts.length * 2];
@@ -390,31 +382,31 @@ class Lexer implements Tokens {
        pushBackDepth++;
     }
 
+    /** push back the most recently read token */
     public void pushBackToken() { pushBackToken(op, number != null ? (Object)number : (Object)string); }
 
+    /** read a token but leave it in the stream */
     public int peekToken() throws IOException {
        int ret = getToken();
        pushBackToken();
        return ret;
     }
 
+    /** read a token */
     public int getToken() throws IOException {
        number = null;
        string = null;
-       if (pushBackDepth > 0) {
-           pushBackDepth--;
-           op = pushBackInts[pushBackDepth];
-           if (pushBackObjects[pushBackDepth] != null) {
-               number = pushBackObjects[pushBackDepth] instanceof Number ? (Number)pushBackObjects[pushBackDepth] : null;
-               string = pushBackObjects[pushBackDepth] instanceof String ? (String)pushBackObjects[pushBackDepth] : null;
-           }
-       } else {
-           do {
-               op = _getToken();
-               if (op == EOL) { line++; col = 0; }
-           } while (op == EOL);
+       if (pushBackDepth == 0) return _getToken();
+       pushBackDepth--;
+       op = pushBackInts[pushBackDepth];
+       if (pushBackObjects[pushBackDepth] != null) {
+           number = pushBackObjects[pushBackDepth] instanceof Number ? (Number)pushBackObjects[pushBackDepth] : null;
+           string = pushBackObjects[pushBackDepth] instanceof String ? (String)pushBackObjects[pushBackDepth] : null;
        }
        return op;
     }
 
+    class LexerException extends IOException {
+       public LexerException(String s) { super(sourceName + ":" + line + "," + col + " " + s); }
+    }
 }
index ff59d3b..73b3590 100644 (file)
@@ -50,7 +50,7 @@ class Parser extends Lexer implements ByteCodes {
        precedence[LSH] = precedence[RSH] = precedence[URSH] = 12;
        precedence[ADD] = precedence[SUB] = 13;
        precedence[MUL] = precedence[DIV] = precedence[MOD] = 14;
-       precedence[BITNOT] = precedence[INSTANCEOF] = 15;
+       precedence[BITNOT] =  15;
        precedence[INC] = precedence[DEC] = 16;
        precedence[LP] = 17;
        precedence[LB] = 18;
@@ -60,6 +60,8 @@ class Parser extends Lexer implements ByteCodes {
 
     // Parsing Logic /////////////////////////////////////////////////////////
 
+    private ByteCodeBlock newbb(int line) { return new ByteCodeBlock(line, sourceName); }
+
     /** gets a token and throws an exception if it is not <tt>code</tt> */
     public void consume(int code) throws IOException {
        if (getToken() != code)
@@ -125,7 +127,7 @@ class Parser extends Lexer implements ByteCodes {
            continueExpr(b, minPrecedence);
            return;
        }
-       case BANG: case BITNOT: case INSTANCEOF: case TYPEOF: {
+       case BANG: case BITNOT: case TYPEOF: {
            startExpr(precedence[tok], b);
            b.add(tok);
            continueExpr(b, minPrecedence);
@@ -168,7 +170,7 @@ class Parser extends Lexer implements ByteCodes {
        case FUNCTION: {
            consume(LP);
            int numArgs = 0;
-           ByteCodeBlock b2 = new ByteCodeBlock(curLine, sourceName);
+           ByteCodeBlock b2 = newbb(curLine);
            b2.add(TOPSCOPE);
            b2.add(SWAP);
            b2.add(LITERAL, "arguments");
@@ -284,7 +286,7 @@ class Parser extends Lexer implements ByteCodes {
            b.add(tok == AND ? b.JF : b.JT, new Integer(0));
            int size = b.size();
            startExpr(precedence[tok], b);
-           b.arg[size - 1] = new Integer(b.size() - size + 2);
+           b.set(size - 1, new Integer(b.size() - size + 2));
            b.add(JMP, new Integer(2));
            b.add(LITERAL, tok == AND ? new Boolean(false) : new Boolean(true));
            continueExpr(b, minPrecedence);
@@ -329,12 +331,12 @@ class Parser extends Lexer implements ByteCodes {
            b.add(JF, new Integer(0));
            int size = b.size();
            startExpr(b);
-           b.arg[size - 1] = new Integer(b.size() - size + 2);
+           b.set(size - 1, new Integer(b.size() - size + 2));
            b.add(JMP, new Integer(0));
            consume(COLON);
            size = b.size();
            startExpr(b);
-           b.arg[size - 1] = new Integer(b.size() - size + 1);
+           b.set(size - 1, new Integer(b.size() - size + 1));
            continueExpr(b, minPrecedence);
            return;
        }
@@ -422,19 +424,19 @@ class Parser extends Lexer implements ByteCodes {
                
                if (peekToken() == ELSE) {
                    consume(ELSE);
-                   b.arg[size - 1] = new Integer(2 + b.size() - size);
+                   b.set(size - 1, new Integer(2 + b.size() - size));
                    b.add(JMP, new Integer(0));
                    size = b.size();
                    parseStatement(false, b);
                }
-               b.arg[size - 1] = new Integer(1 + b.size() - size);
+               b.set(size - 1, new Integer(1 + b.size() - size));
                break;
            }
 
            case WHILE: {
                consume(WHILE);
                consume(LP);
-               ByteCodeBlock loop = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock loop = newbb(curLine);
                b.add(LOOP, loop);
                
                loop.add(POP);
@@ -452,7 +454,7 @@ class Parser extends Lexer implements ByteCodes {
            case SWITCH: {
                consume(SWITCH);
                consume(LP);
-               ByteCodeBlock loop = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock loop = newbb(curLine);
                b.add(LOOP, loop);
                startExpr(loop);
                consume(RP);
@@ -471,7 +473,7 @@ class Parser extends Lexer implements ByteCodes {
                            parseStatement(false, loop);
                            if (size2 == loop.size()) break;
                        }
-                       loop.arg[size - 1] = new Integer(1 + loop.size() - size);
+                       loop.set(size - 1, new Integer(1 + loop.size() - size));
                    } else if (peekToken() == DEFAULT) {
                        consume(DEFAULT);
                        consume(COLON);
@@ -492,7 +494,7 @@ class Parser extends Lexer implements ByteCodes {
                
            case DO: {
                consume(DO);
-               ByteCodeBlock loop = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock loop = newbb(curLine);
                b.add(LOOP, loop);
                
                parseStatement(false, loop);
@@ -545,7 +547,7 @@ class Parser extends Lexer implements ByteCodes {
                b.add(LITERAL, "length");
                b.add(GET);
                consume(RP);
-               ByteCodeBlock b2 = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock b2 = newbb(curLine);
                b.add(SCOPE, b2);
                b2.add(LITERAL, new Integer(1));
                b2.add(SUB);
@@ -562,7 +564,7 @@ class Parser extends Lexer implements ByteCodes {
                break;
                
            } else {
-               ByteCodeBlock b2 = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock b2 = newbb(curLine);
                b.add(SCOPE, b2);
                b.add(POP);
 
@@ -572,9 +574,9 @@ class Parser extends Lexer implements ByteCodes {
                consume(SEMI);
                ByteCodeBlock e2 = startExpr();
                consume(SEMI);
-               if (e2 == null) e2 = new ByteCodeBlock(curLine, sourceName, b.LITERAL, null);
+               if (e2 == null) e2 = newbb(curLine).add(b.LITERAL, null);
 
-               ByteCodeBlock b3 = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock b3 = newbb(curLine);
                b2.add(LOOP, b3);
                b2.add(LITERAL, null);
 
@@ -583,7 +585,7 @@ class Parser extends Lexer implements ByteCodes {
                startExpr(b3);
                consume(RP);
                if (b3.size() - size > 0) b3.add(POP);
-               b3.arg[size - 1] = new Integer(b3.size() - size + 1);
+               b3.set(size - 1, new Integer(b3.size() - size + 1));
 
                b3.paste(e2);
                b3.add(JT, new Integer(2));
index f2187f4..11508fb 100644 (file)
-// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL]
+// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
 package org.xwt.js;
 
+/** this class contains a <tt>public static final int</tt> for each valid token */
 interface Tokens {
+
     // Token Constants //////////////////////////////////////////////////////////
 
-    public final static int
-        EOL          = 1,   // end of line
-        RETURN       = 2,   // return
-        GOTO         = 3,   // goto
-        BITOR        = 4,   // |
-        ASSIGN_BITOR = 5,   // |=
-        BITXOR       = 6,   // ^
-        ASSIGN_BITXOR= 7,   // ^=
-        BITAND       = 8,   // &
-        ASSIGN_BITAND= 9,   // &=
-        EQ           = 10,  // ==
-        NE           = 11,  // !=
-        LT           = 12,  // <
-        LE           = 13,  // <=
-        GT           = 14,  // >
-        GE           = 15,  // >=
-        LSH          = 16,  // <<
-        ASSIGN_LSH   = 17, // <<=
-        RSH          = 18,  // >>
-        ASSIGN_RSH   = 19, // >>=
-        URSH         = 20,  // >>>
-        ASSIGN_URSH  = 21, // >>>=
-        ADD          = 22,  // +
-        ASSIGN_ADD   = 23, // +=
-        SUB          = 24,  // -
-        ASSIGN_SUB   = 25, // -=
-        MUL          = 26,  // *
-        ASSIGN_MUL   = 27, // *=
-        DIV          = 28,  // /
-        ASSIGN_DIV   = 29, // /=
-        MOD          = 30,  // %
-        ASSIGN_MOD   = 31,  // %=
-        BITNOT       = 32,  // ~
-        ASSIGN_BITNOT= 33,  // ~=
-        DELPROP      = 34,  // delete
-        TYPEOF       = 35,  // typeof
-        NAME         = 36,  // *** identifiers ***
-        NUMBER       = 37,  // *** numeric literals ***
-        STRING       = 38,  // *** string literals ***
-        NULL         = 39,  // null
-        THIS         = 40,  // this
-        FALSE        = 41,  // false
-        TRUE         = 42,  // true
-        SHEQ         = 43,  // ===
-        SHNE         = 44,  // !==
-        THROW        = 45,  // throw
-        IN           = 46,  // in
-        INSTANCEOF   = 47,  // instanceof
-        TRY          = 48,  // try
-        SEMI         = 49,  // ;
-        LB           = 50,  // [
-        RB           = 51,  // ]
-        LC           = 52,  // {
-        RC           = 53,  // }
-        LP           = 54,  // (
-        RP           = 55,  // )
-        COMMA        = 56,  // ,
-        ASSIGN       = 57,  // =
-        HOOK         = 58,  // ?
-        COLON        = 59,  // :
-        OR           = 60,  // ||
-        AND          = 61,  // &&
-        INC          = 62,  // ++
-        DEC          = 63,  // --
-        DOT          = 64,  // .
-        FUNCTION     = 65,  // function
-       IF           = 66,  // if keyword
-        ELSE         = 67,  // else keyword
-        SWITCH       = 68,  // switch keyword
-        CASE         = 69,  // case keyword
-        DEFAULT      = 70,  // default keyword
-        WHILE        = 71,  // while keyword
-        DO           = 72,  // do keyword
-        FOR          = 73,  // for keyword
-        BREAK        = 74,  // break keyword
-        CONTINUE     = 75,  // continue keyword
-        VAR          = 76,  // var keyword
-        WITH         = 77,  // with keyword
-        CATCH        = 78,  // catch keyword
-        FINALLY      = 79,  // finally keyword
-        RESERVED     = 80,  // reserved keywords
-        BANG         = 84,  // !
-        ASSERT       = 85;  // assert keyword
+    public static final int EOL           = -1;  // end of line
+
+    // arithmetic operations; also valid as bytecodes
+    public static final int BITOR         = 0;   // |
+    public static final int ASSIGN_BITOR  = 1;   // |=
+    public static final int BITXOR        = 2;   // ^
+    public static final int ASSIGN_BITXOR = 3;   // ^=
+    public static final int BITAND        = 4;   // &
+    public static final int ASSIGN_BITAND = 5;   // &=
+    public static final int LSH           = 6;   // <<
+    public static final int ASSIGN_LSH    = 7;   // <<=
+    public static final int RSH           = 8;   // >>
+    public static final int ASSIGN_RSH    = 9;   // >>=
+    public static final int URSH          = 10;  // >>>
+    public static final int ASSIGN_URSH   = 11;  // >>>=
+    public static final int ADD           = 12;  // +
+    public static final int ASSIGN_ADD    = 13;  // +=
+    public static final int SUB           = 14;  // -
+    public static final int ASSIGN_SUB    = 15;  // -=
+    public static final int MUL           = 16;  // *
+    public static final int ASSIGN_MUL    = 17;  // *=
+    public static final int DIV           = 18;  // /
+    public static final int ASSIGN_DIV    = 19;  // /=
+    public static final int MOD           = 20;  // %
+    public static final int ASSIGN_MOD    = 21;  // %=
+    public static final int BITNOT        = 22;  // ~
+    public static final int ASSIGN_BITNOT = 23;  // ~=
+
+    // logical operations; also valid as bytecodes
+    public static final int OR            = 24;  // ||
+    public static final int AND           = 25;  // &&
+    public static final int BANG          = 26;  // !
+
+    // equality operations; also valid as bytecodes
+    public static final int EQ            = 27;  // ==
+    public static final int NE            = 28;  // !=
+    public static final int LT            = 29;  // <
+    public static final int LE            = 30;  // <=
+    public static final int GT            = 31;  // >
+    public static final int GE            = 32;  // >=
+    public static final int SHEQ          = 33;  // ===
+    public static final int SHNE          = 34;  // !==
 
-    public static final int MAX_TOKEN = ASSERT;
+    // other permissible bytecode tokens
+    public static final int RETURN        = 35;  // return
+    public static final int TYPEOF        = 36;  // typeof
+    public static final int BREAK         = 37;  // break keyword
+    public static final int CONTINUE      = 38;  // continue keyword
+    public static final int TRY           = 39;  // try
+    public static final int THROW         = 40;  // throw
+    public static final int ASSERT        = 41;  // assert keyword
 
+    public static final int NAME          = 42;  // *** identifiers ***
+    public static final int NUMBER        = 43;  // *** numeric literals ***
+    public static final int STRING        = 44;  // *** string literals ***
+    public static final int NULL          = 45;  // null
+    public static final int THIS          = 46;  // this
+    public static final int FALSE         = 47;  // false
+    public static final int TRUE          = 48;  // true
+    public static final int IN            = 49;  // in
+
+    public static final int SEMI          = 50;  // ;
+    public static final int LB            = 51;  // [
+    public static final int RB            = 52;  // ]
+    public static final int LC            = 53;  // {
+    public static final int RC            = 54;  // }
+    public static final int LP            = 55;  // (
+    public static final int RP            = 56;  // )
+    public static final int COMMA         = 57;  // ,
+    public static final int ASSIGN        = 58;  // =
+    public static final int HOOK          = 59;  // ?
+    public static final int COLON         = 60;  // :
+    public static final int INC           = 61;  // ++
+    public static final int DEC           = 62;  // --
+    public static final int DOT           = 63;  // .
+    public static final int FUNCTION      = 64;  // function
+    public static final int IF            = 65;  // if keyword
+    public static final int ELSE          = 66;  // else keyword
+    public static final int SWITCH        = 67;  // switch keyword
+    public static final int CASE          = 68;  // case keyword
+    public static final int DEFAULT       = 69;  // default keyword
+    public static final int WHILE         = 70;  // while keyword
+    public static final int DO            = 71;  // do keyword
+    public static final int FOR           = 74;  // for keyword
+    public static final int VAR           = 75;  // var keyword
+    public static final int WITH          = 76;  // with keyword
+    public static final int CATCH         = 77;  // catch keyword
+    public static final int FINALLY       = 78;  // finally keyword
+    public static final int RESERVED      = 79;  // reserved keyword
+    public static final int MAX_TOKEN = RESERVED;
     public final static String[] codeToString = new String[] {
-       "0", "EOL", "RETURN", "GOTO", "BITOR", "ASSIGN_BITOR",
-       "BITXOR", "ASSIGN_BITXOR", "BITAND", "ASSIGN_BITAND", "EQ",
-       "NE", "LT", "LE", "GT", "GE", "LSH", "ASSIGN_LSH", "RSH",
-       "ASSIGN_RSH", "URSH", "ASSIGN_URSH", "ADD", "ASSIGN_ADD",
-       "SUB", "ASSIGN_SUB", "MUL", "ASSIGN_MUL", "DIV", "ASSIGN_DIV",
-       "MOD", "ASSIGN_MOD", "BITNOT", "ASSIGN_BITNOT=", "DELPROP",
-       "TYPEOF", "NAME", "NUMBER", "STRING", "NULL", "THIS", "FALSE",
-       "TRUE", "SHEQ", "SHNE", "THROW", "IN", "INSTANCEOF", "TRY",
-       "SEMI", "LB", "RB", "LC", "RC", "LP", "RP", "COMMA", "ASSIGN",
-       "HOOK", "COLON", "OR", "AND", "INC", "DEC", "DOT", "FUNCTION",
-       "IF", "ELSE", "SWITCH", "CASE", "DEFAULT", "WHILE", "DO",
-       "FOR", "BREAK", "CONTINUE", "VAR", "WITH", "CATCH", "FINALLY",
-       "RESERVED", "BANG", "ASSERT" };
+        "BITOR", "ASSIGN_BITOR", "BITXOR", "ASSIGN_BITXOR", "BITAND",
+        "ASSIGN_BITAND", "LSH", "ASSIGN_LSH", "RSH", "ASSIGN_RSH",
+        "URSH", "ASSIGN_URSH", "ADD", "ASSIGN_ADD", "SUB",
+        "ASSIGN_SUB", "MUL", "ASSIGN_MUL", "DIV", "ASSIGN_DIV", "MOD",
+        "ASSIGN_MOD", "BITNOT", "ASSIGN_BITNOT", "OR", "AND", "BANG",
+        "EQ", "NE", "LT", "LE", "GT", "GE", "SHEQ", "SHNE", "RETURN",
+        "TYPEOF", "BREAK", "CONTINUE", "TRY", "THROW", "ASSERT", "NAME",
+        "NUMBER", "STRING", "NULL", "THIS", "FALSE", "TRUE", "IN",
+        "SEMI", "LB", "RB", "LC", "RC", "LP", "RP", "COMMA", "ASSIGN",
+        "HOOK", "COLON", "INC", "DEC", "DOT", "FUNCTION", "IF",
+        "ELSE", "SWITCH", "CASE", "DEFAULT", "WHILE", "DO", "FOR",
+        "VAR", "WITH", "CATCH", "FINALLY", "RESERVED" 
+    };
 
 }
+
+