jdk/src/share/classes/sun/tools/java/Parser.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1994-2004 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.tools.java;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import sun.tools.tree.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.InputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.util.Enumeration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.Vector;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * This class is used to parse Java statements and expressions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * The result is a parse tree.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * This class implements an operator precedence parser. Errors are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * reported to the Environment object, if the error can't be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * resolved immediately, a SyntaxError exception is thrown.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * Error recovery is implemented by catching SyntaxError exceptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * and discarding input tokens until an input token is reached that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * is possibly a legal continuation.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * The parse tree that is constructed represents the input
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * exactly (no rewrites to simpler forms). This is important
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * if the resulting tree is to be used for code formatting in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * a programming environment. Currently only documentation comments
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * are retained.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * The parsing algorithm does NOT use any type information. Changes
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * in the type system do not affect the structure of the parse tree.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * This restriction does introduce an ambiguity an expression of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * form: (e1) e2 is assumed to be a cast if e2 does not start with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * an operator. That means that (a) - b is interpreted as subtract
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * b from a and not cast negative b to type a. However, if a is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * simple type (byte, int, ...) then it is assumed to be a cast.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * WARNING: The contents of this source file are not part of any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * supported API.  Code that depends on them does so at its own risk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * they are subject to change or removal without notice.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * @author      Arthur van Hoff
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
public
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
class Parser extends Scanner implements ParserActions, Constants {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
     * Create a parser
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    protected Parser(Environment env, InputStream in) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        super(env, in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        this.scanner = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        this.actions = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
     * Create a parser, given a scanner.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    protected Parser(Scanner scanner) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        super(scanner.env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        this.scanner = scanner;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        ((Scanner)this).env = scanner.env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        ((Scanner)this).token = scanner.token;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        ((Scanner)this).pos = scanner.pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        this.actions = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * Create a parser, given a scanner and the semantic callback.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    public Parser(Scanner scanner, ParserActions actions) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        this(scanner);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        this.actions = actions;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * Usually <code>this.actions == (ParserActions)this</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     * However, a delegate scanner can produce tokens for this parser,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * in which case <code>(Scanner)this</code> is unused,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * except for <code>this.token</code> and <code>this.pos</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * instance variables which are filled from the real scanner
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * by <code>this.scan()</code> and the constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    ParserActions actions;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    // Note:  The duplication of methods allows pre-1.1 classes to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    // be binary compatible with the new version of the parser,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    // which now passes IdentifierTokens to the semantics phase,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    // rather than just Identifiers.  This change is necessary,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    // since the parser is no longer responsible for managing the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    // resolution of type names.  (That caused the "Vector" bug.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    // In a future release, the old "plain-Identifier" methods will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    // go away, and the corresponding "IdentifierToken" methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    // may become abstract.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * package declaration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * @deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    public void packageDeclaration(long off, IdentifierToken nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        // By default, call the deprecated version.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        // Any application must override one of the packageDeclaration methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        packageDeclaration(off, nm.id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * @deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    protected void packageDeclaration(long off, Identifier nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        throw new RuntimeException("beginClass method is abstract");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * import class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * @deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    public void importClass(long off, IdentifierToken nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        // By default, call the deprecated version.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        // Any application must override one of the packageDeclaration methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        importClass(off, nm.id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * @deprecated Use the version with the IdentifierToken arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    protected void importClass(long off, Identifier nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        throw new RuntimeException("importClass method is abstract");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * import package
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * @deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    public void importPackage(long off, IdentifierToken nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        // By default, call the deprecated version.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        // Any application must override one of the importPackage methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        importPackage(off, nm.id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * @deprecated Use the version with the IdentifierToken arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    protected void importPackage(long off, Identifier nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        throw new RuntimeException("importPackage method is abstract");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     * Define class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * @deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    public ClassDefinition beginClass(long off, String doc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                                      int mod, IdentifierToken nm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                                      IdentifierToken sup,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
                                      IdentifierToken impl[]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        // By default, call the deprecated version.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        // Any application must override one of the beginClass methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        Identifier supId = (sup == null) ? null : sup.id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        Identifier implIds[] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        if (impl != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            implIds = new Identifier[impl.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            for (int i = 0; i < impl.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                implIds[i] = impl[i].id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        beginClass(off, doc, mod, nm.id, supId, implIds);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        return getCurrentClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * @deprecated Use the version with the IdentifierToken arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    protected void beginClass(long off, String doc, int mod, Identifier nm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                              Identifier sup, Identifier impl[]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        throw new RuntimeException("beginClass method is abstract");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     * Report the current class under construction.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     * By default, it's a no-op which returns null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * It may only be called before the corresponding endClass().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    protected ClassDefinition getCurrentClass() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     * End class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     * @deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    public void endClass(long off, ClassDefinition c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        // By default, call the deprecated version.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        // Any application must override one of the beginClass methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        endClass(off, c.getName().getFlatName().getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     * @deprecated Use the version with the IdentifierToken arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    protected void endClass(long off, Identifier nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        throw new RuntimeException("endClass method is abstract");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     * Define a field
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     * @deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    public void defineField(long where, ClassDefinition c,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                            String doc, int mod, Type t,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                            IdentifierToken nm, IdentifierToken args[],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                            IdentifierToken exp[], Node val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        // By default, call the deprecated version.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        // Any application must override one of the defineField methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        Identifier argIds[] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        Identifier expIds[] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        if (args != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            argIds = new Identifier[args.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            for (int i = 0; i < args.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                argIds[i] = args[i].id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        if (exp != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
            expIds = new Identifier[exp.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            for (int i = 0; i < exp.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                expIds[i] = exp[i].id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        defineField(where, doc, mod, t, nm.id, argIds, expIds, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * @deprecated Use the version with the IdentifierToken arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    protected void defineField(long where, String doc, int mod, Type t,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                               Identifier nm, Identifier args[],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                               Identifier exp[], Node val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        throw new RuntimeException("defineField method is abstract");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     * A growable array of nodes. It is used as a growable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     * buffer to hold argument lists and expression lists.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * I'm not using Vector to make it more efficient.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    private Node args[] = new Node[32];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    protected int argIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    protected final void addArgument(Node n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        if (argIndex == args.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            Node newArgs[] = new Node[args.length * 2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            System.arraycopy(args, 0, newArgs, 0, args.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            args = newArgs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        args[argIndex++] = n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    protected final Expression exprArgs(int index)[] {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        Expression e[] = new Expression[argIndex - index];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        System.arraycopy(args, index, e, 0, argIndex - index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        argIndex = index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        return e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    protected final Statement statArgs(int index)[] {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        Statement s[] = new Statement[argIndex - index];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        System.arraycopy(args, index, s, 0, argIndex - index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        argIndex = index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        return s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     * Expect a token, return its value, scan the next token or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * throw an exception.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    protected void expect(int t) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        if (token != t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            switch (t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
              case IDENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                env.error(scanner.prevPos, "identifier.expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
              default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                env.error(scanner.prevPos, "token.expected", opNames[t]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                throw new SyntaxError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * Parse a type expression. Does not parse the []'s.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    protected Expression parseTypeExpression() throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
          case VOID:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            return new TypeExpression(scan(), Type.tVoid);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
          case BOOLEAN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            return new TypeExpression(scan(), Type.tBoolean);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
          case BYTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            return new TypeExpression(scan(), Type.tByte);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
          case CHAR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            return new TypeExpression(scan(), Type.tChar);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
          case SHORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            return new TypeExpression(scan(), Type.tShort);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
          case INT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            return new TypeExpression(scan(), Type.tInt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
          case LONG:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            return new TypeExpression(scan(), Type.tLong);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
          case FLOAT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            return new TypeExpression(scan(), Type.tFloat);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
          case DOUBLE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            return new TypeExpression(scan(), Type.tDouble);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
          case IDENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            Expression e = new IdentifierExpression(pos, scanner.idValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            while (token == FIELD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                e = new FieldExpression(scan(), e, scanner.idValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            return e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        env.error(pos, "type.expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        throw new SyntaxError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     * Parse a method invocation. Should be called when the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
     * then is the '(' of the argument list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    protected Expression parseMethodExpression(Expression e, Identifier id) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
       long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
       int i = argIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
       if (token != RPAREN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
           addArgument(parseExpression());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
           while (token == COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
               scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
               addArgument(parseExpression());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
           }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
       expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
       return new MethodExpression(p, e, id, exprArgs(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     * Parse a new instance expression.  Should be called when the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     * token is the '(' of the argument list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    protected Expression parseNewInstanceExpression(long p, Expression outerArg, Expression type) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        int i = argIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        expect(LPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        if (token != RPAREN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            addArgument(parseExpression());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            while (token == COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                addArgument(parseExpression());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        ClassDefinition body = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        if (token == LBRACE && !(type instanceof TypeExpression)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            long tp = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
            // x = new Type(arg) { subclass body ... }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            Identifier superName = FieldExpression.toIdentifier(type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
            if (superName == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                env.error(type.getWhere(), "type.expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            Vector ext = new Vector(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            Vector impl = new Vector(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            ext.addElement(new IdentifierToken(idNull));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            if (token == IMPLEMENTS || token == EXTENDS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                env.error(pos, "anonymous.extends");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                parseInheritance(ext, impl); // error recovery
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            body = parseClassBody(new IdentifierToken(tp, idNull),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                                  M_ANONYMOUS | M_LOCAL, EXPR, null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                                  ext, impl, type.getWhere());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        if (outerArg == null && body == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
            return new NewInstanceExpression(p, type, exprArgs(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        return new NewInstanceExpression(p, type, exprArgs(i), outerArg, body);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     * Parse a primary expression.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    protected Expression parseTerm() throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
          case CHARVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            char v = scanner.charValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            return new CharExpression(scan(), v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
          case INTVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            int v = scanner.intValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            long q = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            if (v < 0 && radix == 10) env.error(q, "overflow.int.dec");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            return new IntExpression(q, v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
          case LONGVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            long v = scanner.longValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            long q = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            if (v < 0 && radix == 10) env.error(q, "overflow.long.dec");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            return new LongExpression(q, v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
          case FLOATVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            float v = scanner.floatValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            return new FloatExpression(scan(), v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
          case DOUBLEVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            double v = scanner.doubleValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            return new DoubleExpression(scan(), v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
          case STRINGVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            String v = scanner.stringValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            return new StringExpression(scan(), v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
          case IDENT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
            Identifier v = scanner.idValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            return (token == LPAREN) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                        parseMethodExpression(null, v) : new IdentifierExpression(p, v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
          case TRUE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            return new BooleanExpression(scan(), true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
          case FALSE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            return new BooleanExpression(scan(), false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
          case NULL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            return new NullExpression(scan());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
          case THIS: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            Expression e = new ThisExpression(scan());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            return (token == LPAREN) ? parseMethodExpression(e, idInit) : e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
          case SUPER: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            Expression e = new SuperExpression(scan());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
            return (token == LPAREN) ? parseMethodExpression(e, idInit) : e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
          case VOID:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
          case BOOLEAN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
          case BYTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
          case CHAR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
          case SHORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
          case INT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
          case LONG:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
          case FLOAT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
          case DOUBLE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
            return parseTypeExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
          case ADD: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
            switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
              case INTVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                int v = scanner.intValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                long q = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                if (v < 0 && radix == 10) env.error(q, "overflow.int.dec");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                return new IntExpression(q, v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
              case LONGVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                long v = scanner.longValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                long q = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                if (v < 0 && radix == 10) env.error(q, "overflow.long.dec");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                return new LongExpression(q, v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
              case FLOATVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                float v = scanner.floatValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                return new FloatExpression(scan(), v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
              case DOUBLEVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                double v = scanner.doubleValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                return new DoubleExpression(scan(), v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
            return new PositiveExpression(p, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
          case SUB: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
              case INTVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                int v = -scanner.intValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                return new IntExpression(scan(), v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
              case LONGVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                long v = -scanner.longValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                return new LongExpression(scan(), v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
              case FLOATVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                float v = -scanner.floatValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                return new FloatExpression(scan(), v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
              case DOUBLEVAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                double v = -scanner.doubleValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                return new DoubleExpression(scan(), v);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            return new NegativeExpression(p, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
          case NOT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            return new NotExpression(scan(), parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
          case BITNOT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            return new BitNotExpression(scan(), parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
          case INC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            return new PreIncExpression(scan(), parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
          case DEC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            return new PreDecExpression(scan(), parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
          case LPAREN: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            // bracketed-expr: (expr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            Expression e = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            if (e.getOp() == TYPE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                // cast-expr: (simple-type) expr
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                return new CastExpression(p, e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                // We handle INC and DEC specially.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                // See the discussion in JLS section 15.14.1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                // (Part of fix for 4044502.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
              case INC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
                  // We know this must be a postfix increment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                  return new PostIncExpression(scan(), e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
              case DEC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                  // We know this must be a postfix decrement.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                  return new PostDecExpression(scan(), e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
              case LPAREN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
              case CHARVAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
              case INTVAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
              case LONGVAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
              case FLOATVAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
              case DOUBLEVAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
              case STRINGVAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
              case IDENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
              case TRUE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
              case FALSE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
              case NOT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
              case BITNOT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
              case THIS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
              case SUPER:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
              case NULL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
              case NEW:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                // cast-expr: (expr) expr
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                return new CastExpression(p, e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            return new ExprExpression(p, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
          case LBRACE: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            // array initializer: {expr1, expr2, ... exprn}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
            int i = argIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            if (token != RBRACE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
                addArgument(parseExpression());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                while (token == COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                    scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                    if (token == RBRACE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                    addArgument(parseExpression());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
            expect(RBRACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            return new ArrayExpression(p, exprArgs(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
          case NEW: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
            int i = argIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
            if (token == LPAREN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                Expression e = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                env.error(p, "not.supported", "new(...)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                return new NullExpression(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
            Expression e = parseTypeExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            if (token == LSQBRACKET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                while (token == LSQBRACKET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
                    scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                    addArgument((token != RSQBRACKET) ? parseExpression() : null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
                    expect(RSQBRACKET);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                Expression[] dims = exprArgs(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                if (token == LBRACE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                    return new NewArrayExpression(p, e, dims, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
                return new NewArrayExpression(p, e, dims);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                return parseNewInstanceExpression(p, null, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        // System.err.println("NEAR: " + opNames[token]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        env.error(scanner.prevPos, "missing.term");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        return new IntExpression(pos, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
     * Parse an expression.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
    protected Expression parseExpression() throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        for (Expression e = parseTerm() ; e != null ; e = e.order()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
            Expression more = parseBinaryExpression(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            if (more == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                return e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            e = more;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        // this return is bogus
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     * Given a left-hand term, parse an operator and right-hand term.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    protected Expression parseBinaryExpression(Expression e) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
        if (e != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
              case LSQBRACKET: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                // index: expr1[expr2]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                Expression index = (token != RSQBRACKET) ? parseExpression() : null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                expect(RSQBRACKET);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                e = new ArrayAccessExpression(p, e, index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
              case INC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                e = new PostIncExpression(scan(), e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
              case DEC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                e = new PostDecExpression(scan(), e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
              case FIELD: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
                long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                if (token == THIS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
                    // class C { class N { ... C.this ... } }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                    // class C { class N { N(C c){ ... c.this() ... } } }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                    long q = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
                    if (token == LPAREN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
                        e = new ThisExpression(q, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                        e = parseMethodExpression(e, idInit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                        e = new FieldExpression(p, e, idThis);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                if (token == SUPER) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
                    // class D extends C.N { D(C.N n) { n.super(); } }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                    // Also, 'C.super', as in:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                    // class C extends CS { class N { ... C.super.foo ... } }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
                    // class C extends CS { class N { ... C.super.foo() ... } }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
                    long q = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                    if (token == LPAREN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
                        e = new SuperExpression(q, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                        e = parseMethodExpression(e, idInit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                        // We must check elsewhere that this expression
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
                        // does not stand alone, but qualifies a member name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
                        e = new FieldExpression(p, e, idSuper);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                if (token == NEW) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                    // new C().new N()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                    scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
                    if (token != IDENT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
                        expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
                    e = parseNewInstanceExpression(p, e, parseTypeExpression());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                if (token == CLASS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                    // just class literals, really
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                    // Class c = C.class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                    scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                    e = new FieldExpression(p, e, idClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                Identifier id = scanner.idValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                if (token == LPAREN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                    e = parseMethodExpression(e, id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                    e = new FieldExpression(p, e, id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
              case INSTANCEOF:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
                e = new InstanceOfExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
              case ADD:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
                e = new AddExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
              case SUB:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
                e = new SubtractExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
              case MUL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                e = new MultiplyExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
              case DIV:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                e = new DivideExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
              case REM:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
                e = new RemainderExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
              case LSHIFT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                e = new ShiftLeftExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
              case RSHIFT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
                e = new ShiftRightExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
              case URSHIFT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
                e = new UnsignedShiftRightExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
              case LT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                e = new LessExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
              case LE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                e = new LessOrEqualExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
              case GT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                e = new GreaterExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
              case GE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                e = new GreaterOrEqualExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
              case EQ:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
                e = new EqualExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
              case NE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
                e = new NotEqualExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
              case BITAND:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
                e = new BitAndExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
              case BITXOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
                e = new BitXorExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
              case BITOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
                e = new BitOrExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
              case AND:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                e = new AndExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
              case OR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                e = new OrExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
              case ASSIGN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                e = new AssignExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
              case ASGMUL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                e = new AssignMultiplyExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
              case ASGDIV:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                e = new AssignDivideExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
              case ASGREM:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                e = new AssignRemainderExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
              case ASGADD:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                e = new AssignAddExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
              case ASGSUB:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                e = new AssignSubtractExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
              case ASGLSHIFT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                e = new AssignShiftLeftExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
              case ASGRSHIFT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                e = new AssignShiftRightExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
              case ASGURSHIFT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                e = new AssignUnsignedShiftRightExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
              case ASGBITAND:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
                e = new AssignBitAndExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
              case ASGBITOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                e = new AssignBitOrExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
              case ASGBITXOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
                e = new AssignBitXorExpression(scan(), e, parseTerm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
              case QUESTIONMARK: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                Expression second = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                expect(COLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
                Expression third = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
                // The grammar in the JLS does not allow assignment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
                // expressions as the third part of a ?: expression.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
                // Even though javac has no trouble parsing this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
                // check for this case and signal an error.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
                // (fix for bug 4092958)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
                if (third instanceof AssignExpression
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
                    || third instanceof AssignOpExpression) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
                    env.error(third.getWhere(), "assign.in.conditionalexpr");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                e = new ConditionalExpression(p, e, second, third);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
              default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                return null; // mark end of binary expressions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
        return e;           // return more binary expression stuff
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
     * Recover after a syntax error in a statement. This involves
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
     * discarding tokens until EOF or a possible continuation is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
     * encountered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
    protected boolean recoverStatement() throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
            switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
              case EOF:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
              case RBRACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
              case LBRACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
              case IF:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
              case FOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
              case WHILE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
              case DO:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
              case TRY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
              case CATCH:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
              case FINALLY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
              case BREAK:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
              case CONTINUE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
              case RETURN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                // begin of a statement, return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
              case VOID:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
              case STATIC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
              case PUBLIC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
              case PRIVATE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
              case SYNCHRONIZED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
              case INTERFACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
              case CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
              case TRANSIENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                // begin of something outside a statement, panic some more
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                expect(RBRACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
              case LPAREN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                match(LPAREN, RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
              case LSQBRACKET:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
                match(LSQBRACKET, RSQBRACKET);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
              default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
                // don't know what to do, skip
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
     * Parse declaration, called after the type expression
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
     * has been parsed and the current token is IDENT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
    protected Statement parseDeclaration(long p, int mod, Expression type) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
        int i = argIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
        if (token == IDENT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
            addArgument(new VarDeclarationStatement(pos, parseExpression()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
            while (token == COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
                addArgument(new VarDeclarationStatement(pos, parseExpression()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
        return new DeclarationStatement(p, mod, type, statArgs(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
     * Check if an expression is a legal toplevel expression.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
     * Only method, inc, dec, and new expression are allowed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    protected void topLevelExpression(Expression e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
        switch (e.getOp()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
          case ASSIGN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
          case ASGMUL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
          case ASGDIV:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
          case ASGREM:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
          case ASGADD:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
          case ASGSUB:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
          case ASGLSHIFT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
          case ASGRSHIFT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
          case ASGURSHIFT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
          case ASGBITAND:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
          case ASGBITOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
          case ASGBITXOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
          case PREINC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
          case PREDEC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
          case POSTINC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
          case POSTDEC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
          case METHOD:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
          case NEWINSTANCE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
        env.error(e.getWhere(), "invalid.expr");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
     * Parse a statement.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
    protected Statement parseStatement() throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
        switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
          case SEMICOLON:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
            return new CompoundStatement(scan(), new Statement[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
          case LBRACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
              return parseBlockStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
          case IF: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
            // if-statement: if (expr) stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
            // if-statement: if (expr) stat else stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
            expect(LPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
            Expression c = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
            expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
            Statement t = parseStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
            if (token == ELSE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
                return new IfStatement(p, c, t, parseStatement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
                return new IfStatement(p, c, t, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
          case ELSE: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
            // else-statement: else stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
            env.error(scan(), "else.without.if");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
            return parseStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
          case FOR: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
            // for-statement: for (decl-expr? ; expr? ; expr?) stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
            Statement init = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
            Expression cond = null, inc = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
            expect(LPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
            if (token != SEMICOLON) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
                long p2 = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
                int mod = parseModifiers(M_FINAL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
                Expression e = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
                if (token == IDENT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                    init = parseDeclaration(p2, mod, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
                    if (mod != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
                        expect(IDENT); // should have been a declaration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
                    topLevelExpression(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
                    while (token == COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
                        long p3 = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
                        Expression e2 = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
                        topLevelExpression(e2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
                        e = new CommaExpression(p3, e, e2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
                    init = new ExpressionStatement(p2, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
            expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
            if (token != SEMICOLON) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
                cond = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
            expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
            if (token != RPAREN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
                inc = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
                topLevelExpression(inc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
                while (token == COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
                    long p2 = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
                    Expression e2 = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
                    topLevelExpression(e2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
                    inc = new CommaExpression(p2, inc, e2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
            expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
            return new ForStatement(p, init, cond, inc, parseStatement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
          case WHILE: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
            // while-statement: while (expr) stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
            expect(LPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
            Expression cond = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
            expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
            return new WhileStatement(p, cond, parseStatement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
          case DO: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
            // do-statement: do stat while (expr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
            Statement body = parseStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
            expect(WHILE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
            expect(LPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            Expression cond = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
            expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
            expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
            return new DoStatement(p, body, cond);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
          case BREAK: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
            // break-statement: break ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
            Identifier label = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
            if (token == IDENT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
                label = scanner.idValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
            expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
            return new BreakStatement(p, label);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
          case CONTINUE: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
            // continue-statement: continue ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
            Identifier label = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
            if (token == IDENT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
                label = scanner.idValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
            expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
            return new ContinueStatement(p, label);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
          case RETURN: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
            // return-statement: return ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
            // return-statement: return expr ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
            Expression e = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
            if (token != SEMICOLON) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
                e = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
            expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
            return new ReturnStatement(p, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
          case SWITCH: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
            // switch statement: switch ( expr ) stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
            int i = argIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
            expect(LPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
            Expression e = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
            expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
            expect(LBRACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
            while ((token != EOF) && (token != RBRACE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
                int j = argIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
                    switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
                      case CASE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
                        // case-statement: case expr:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
                        addArgument(new CaseStatement(scan(), parseExpression()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
                        expect(COLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
                      case DEFAULT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
                        // default-statement: default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
                        addArgument(new CaseStatement(scan(), null));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
                        expect(COLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
                      default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
                        addArgument(parseStatement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
                } catch (SyntaxError ee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
                    argIndex = j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
                    if (!recoverStatement()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
                        throw ee;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
            expect(RBRACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
            return new SwitchStatement(p, e, statArgs(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
          case CASE: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
            // case-statement: case expr : stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
            env.error(pos, "case.without.switch");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
            while (token == CASE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
                parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
                expect(COLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
            return parseStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
          case DEFAULT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
            // default-statement: default : stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
            env.error(pos, "default.without.switch");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
            expect(COLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
            return parseStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
          case TRY: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
            // try-statement: try stat catch (type-expr ident) stat finally stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
            Statement init = null;              // try-object specification
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
            int i = argIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
            boolean catches = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
            if (false && token == LPAREN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
                expect(LPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
                long p2 = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
                int mod = parseModifiers(M_FINAL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
                Expression e = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
                if (token == IDENT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
                    init = parseDeclaration(p2, mod, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
                    // leave check for try (T x, y) for semantic phase
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
                    if (mod != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
                        expect(IDENT); // should have been a declaration
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
                    init = new ExpressionStatement(p2, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
                expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
            Statement s = parseBlockStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
            if (init != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
                // s = new FinallyStatement(p, init, s, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
            while (token == CATCH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
                long pp = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
                expect(CATCH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
                expect(LPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
                int mod = parseModifiers(M_FINAL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
                Expression t = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
                IdentifierToken id = scanner.getIdToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
                expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
                id.modifiers = mod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
                // We only catch Throwable's, so this is no longer required
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
                // while (token == LSQBRACKET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
                //    t = new ArrayAccessExpression(scan(), t, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
                //    expect(RSQBRACKET);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
                // }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
                expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
                addArgument(new CatchStatement(pp, t, id, parseBlockStatement()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
                catches = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
            if (catches)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
                s = new TryStatement(p, s, statArgs(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
            if (token == FINALLY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
                return new FinallyStatement(p, s, parseBlockStatement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
            } else if (catches || init != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
                return s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
                env.error(pos, "try.without.catch.finally");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
                return new TryStatement(p, s, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
          case CATCH: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
            // catch-statement: catch (expr ident) stat finally stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
            env.error(pos, "catch.without.try");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
            Statement s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
            do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
                expect(LPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
                parseModifiers(M_FINAL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
                parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
                expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
                expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
                s = parseBlockStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
            } while (token == CATCH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
            if (token == FINALLY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
                s = parseBlockStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
            return s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
          case FINALLY: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
            // finally-statement: finally stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
            env.error(pos, "finally.without.try");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
            return parseBlockStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
          case THROW: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
            // throw-statement: throw expr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
            Expression e = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
            expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
            return new ThrowStatement(p, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
          case GOTO: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
            expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
            expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
            env.error(p, "not.supported", "goto");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
            return new CompoundStatement(p, new Statement[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
          case SYNCHRONIZED: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
            // synchronized-statement: synchronized (expr) stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
            long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
            expect(LPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
            Expression e = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
            expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
            return new SynchronizedStatement(p, e, parseBlockStatement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
          case INTERFACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
          case CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
            // Inner class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
            return parseLocalClass(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
          case CONST:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
          case ABSTRACT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
          case FINAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
          case STRICTFP: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
            // a declaration of some sort
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
            long p = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
            // A class which is local to a block is not a member, and so
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
            // cannot be public, private, protected, or static. It is in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
            // effect private to the block, since it cannot be used outside
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
            // its scope.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
            //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
            // However, any class (if it has a name) can be declared final,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
            // abstract, or strictfp.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
            int mod = parseModifiers(M_FINAL | M_ABSTRACT
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
                                             | M_STRICTFP );
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
            switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
              case INTERFACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
              case CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
                return parseLocalClass(mod);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
              case BOOLEAN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
              case BYTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
              case CHAR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
              case SHORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
              case INT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
              case LONG:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
              case FLOAT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
              case DOUBLE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
              case IDENT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
                if ((mod & (M_ABSTRACT | M_STRICTFP )) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
                    mod &= ~ (M_ABSTRACT | M_STRICTFP );
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
                    expect(CLASS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
                Expression e = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
                if (token != IDENT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
                    expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
                // declaration: final expr expr
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
                Statement s = parseDeclaration(p, mod, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
                expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
                return s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
              default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
                env.error(pos, "type.expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
                throw new SyntaxError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
          case VOID:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
          case STATIC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
          case PUBLIC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
          case PRIVATE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
          case TRANSIENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
            // This is the start of something outside a statement
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
            env.error(pos, "statement.expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
            throw new SyntaxError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
        long p = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
        Expression e = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
        if (token == IDENT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
            // declaration: expr expr
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
            Statement s = parseDeclaration(p, 0, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
            expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
            return s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
        if (token == COLON) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
            // label: id: stat
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
            Statement s = parseStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
            s.setLabel(env, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
            return s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
        // it was just an expression...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
        topLevelExpression(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
        expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
        return new ExpressionStatement(p, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
    protected Statement parseBlockStatement() throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
        // compound statement: { stat1 stat2 ... statn }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
        if (token != LBRACE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
            // We're expecting a block statement.  But we'll probably do the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
            // least damage if we try to parse a normal statement instead.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
            env.error(scanner.prevPos, "token.expected", opNames[LBRACE]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
            return parseStatement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
        long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
        int i = argIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
        while ((token != EOF) && (token != RBRACE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
            int j = argIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
                addArgument(parseStatement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
            } catch (SyntaxError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
                argIndex = j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
                if (!recoverStatement()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
                    throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
        expect(RBRACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
        return new CompoundStatement(p, statArgs(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
     * Parse an identifier. ie: a.b.c returns "a.b.c"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
     * If star is true then "a.b.*" is allowed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
     * The return value encodes both the identifier and its location.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
    protected IdentifierToken parseName(boolean star) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
        IdentifierToken res = scanner.getIdToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
        expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
        if (token != FIELD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
            return res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
        StringBuffer buf = new StringBuffer(res.id.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
        while (token == FIELD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
            if ((token == MUL) && star) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
                buf.append(".*");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
            buf.append('.');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
            if (token == IDENT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
                buf.append(scanner.idValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
            expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
        res.id = Identifier.lookup(buf.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
        return res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
     * @deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
     * @see #parseName
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
    protected Identifier parseIdentifier(boolean star) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
        return parseName(star).id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
     * Parse a type expression, this results in a Type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
     * The parse includes trailing array brackets.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
    protected Type parseType() throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
        Type t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
        switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
          case IDENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
            t = Type.tClass(parseName(false).id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
          case VOID:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
            t = Type.tVoid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
          case BOOLEAN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
            t = Type.tBoolean;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
          case BYTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
            t = Type.tByte;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
          case CHAR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
            t = Type.tChar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
          case SHORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
            t = Type.tShort;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
          case INT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
            t = Type.tInt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
          case FLOAT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
            t = Type.tFloat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
          case LONG:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
            t = Type.tLong;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
          case DOUBLE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
            t = Type.tDouble;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
            env.error(pos, "type.expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
            throw new SyntaxError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
        return parseArrayBrackets(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
     * Parse the tail of a type expression, which might be array brackets.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
     * Return the given type, as possibly modified by the suffix.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
    protected Type parseArrayBrackets(Type t) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
        // Parse []'s
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
        while (token == LSQBRACKET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
            if (token != RSQBRACKET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
                env.error(pos, "array.dim.in.decl");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
                parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
            expect(RSQBRACKET);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
            t = Type.tArray(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
     * Dealing with argument lists, I'm not using
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
     * Vector for efficiency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
    private int aCount = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
    private Type aTypes[] = new Type[8];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
    private IdentifierToken aNames[] = new IdentifierToken[aTypes.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
    private void addArgument(int mod, Type t, IdentifierToken nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
        nm.modifiers = mod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
        if (aCount >= aTypes.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
            Type newATypes[] = new Type[aCount * 2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
            System.arraycopy(aTypes, 0, newATypes, 0, aCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
            aTypes = newATypes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
            IdentifierToken newANames[] = new IdentifierToken[aCount * 2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
            System.arraycopy(aNames, 0, newANames, 0, aCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
            aNames = newANames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
        aTypes[aCount] = t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
        aNames[aCount++] = nm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
     * Parse a possibly-empty sequence of modifier keywords.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
     * Return the resulting bitmask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
     * Diagnose repeated modifiers, but make no other checks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
     * Only modifiers mentioned in the given bitmask are scanned;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
     * an unmatched modifier must be handled by the caller.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
    protected int parseModifiers(int mask) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
        int mod = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
            if (token==CONST) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
                // const isn't in java, but handle a common C++ usage gently
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
                env.error(pos, "not.supported", "const");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
            int nextmod = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
            switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
               case PRIVATE:            nextmod = M_PRIVATE;      break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
               case PUBLIC:             nextmod = M_PUBLIC;       break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
               case PROTECTED:          nextmod = M_PROTECTED;    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
               case STATIC:             nextmod = M_STATIC;       break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
               case TRANSIENT:          nextmod = M_TRANSIENT;    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
               case FINAL:              nextmod = M_FINAL;        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
               case ABSTRACT:           nextmod = M_ABSTRACT;     break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
               case NATIVE:             nextmod = M_NATIVE;       break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
               case VOLATILE:           nextmod = M_VOLATILE;     break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
               case SYNCHRONIZED:       nextmod = M_SYNCHRONIZED; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
               case STRICTFP:           nextmod = M_STRICTFP;     break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
            if ((nextmod & mask) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
            if ((nextmod & mod) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
                env.error(pos, "repeated.modifier");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
            mod |= nextmod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
        return mod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
    private ClassDefinition curClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
     * Parse a field.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
    protected void parseField() throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
        // Empty fields are not allowed by the JLS but are accepted by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
        // the compiler, and much code has come to rely on this.  It has
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
        // been decided that the language will be extended to legitimize them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
        if (token == SEMICOLON) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
            // empty field
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
        // Optional doc comment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
        String doc = scanner.docComment;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
        // The start of the field
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
        long p = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
        // Parse the modifiers
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
        int mod = parseModifiers(MM_FIELD | MM_METHOD);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
        // Check for static initializer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
        // ie: static { ... }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
        // or an instance initializer (w/o the static).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
        if ((mod == (mod & M_STATIC)) && (token == LBRACE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
            // static initializer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
            actions.defineField(p, curClass, doc, mod,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
                                Type.tMethod(Type.tVoid),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
                                new IdentifierToken(idClassInit), null, null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
                                parseStatement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1601
        // Check for inner class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
        if (token == CLASS || token == INTERFACE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
            parseNamedClass(mod, CLASS, doc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
        // Parse the type
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
        p = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
        Type t = parseType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
        IdentifierToken id = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
        // Check that the type is followed by an Identifier
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
        // (the name of the method or the first variable),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
        // otherwise it is a constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
        switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
          case IDENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
            id = scanner.getIdToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
            p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
          case LPAREN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
            // It is a constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
            id = new IdentifierToken(idInit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
            if ((mod & M_STRICTFP) != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
                env.error(pos, "bad.constructor.modifier");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
            expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
        // If the next token is a left-bracket then we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
        // are dealing with a method or constructor, otherwise it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
        // a list of variables
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
        if (token == LPAREN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
            // It is a method or constructor declaration
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1638
            aCount = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1639
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
            if (token != RPAREN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
                // Parse argument type and identifier
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
                // (arguments (like locals) are allowed to be final)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
                int am = parseModifiers(M_FINAL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
                Type at = parseType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
                IdentifierToken an = scanner.getIdToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
                expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
                // Parse optional array specifier, ie: a[][]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
                at = parseArrayBrackets(at);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
                addArgument(am, at, an);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
                // If the next token is a comma then there are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
                // more arguments
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
                while (token == COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
                    // Parse argument type and identifier
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
                    scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
                    am = parseModifiers(M_FINAL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
                    at = parseType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
                    an = scanner.getIdToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
                    expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
                    // Parse optional array specifier, ie: a[][]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
                    at = parseArrayBrackets(at);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
                    addArgument(am, at, an);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
            expect(RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
            // Parse optional array sepecifier, ie: foo()[][]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
            t = parseArrayBrackets(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
            // copy arguments
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
            Type atypes[] = new Type[aCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
            System.arraycopy(aTypes, 0, atypes, 0, aCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
            IdentifierToken anames[] = new IdentifierToken[aCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
            System.arraycopy(aNames, 0, anames, 0, aCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
            // Construct the type signature
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
            t = Type.tMethod(t, atypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
            // Parse and ignore throws clause
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
            IdentifierToken exp[] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
            if (token == THROWS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
                Vector v = new Vector();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
                v.addElement(parseName(false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
                while (token == COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
                    scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
                    v.addElement(parseName(false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
                exp = new IdentifierToken[v.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
                v.copyInto(exp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
            // Check if it is a method definition or a method declaration
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
            // ie: foo() {...} or foo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
            switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
              case LBRACE:      // It's a method definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
                // Set the state of FP strictness for the body of the method
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
                int oldFPstate = FPstate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
                if ((mod & M_STRICTFP)!=0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
                    FPstate = M_STRICTFP;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
                    mod |= FPstate & M_STRICTFP;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1708
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1710
                actions.defineField(p, curClass, doc, mod, t, id,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
                                    anames, exp, parseStatement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
                FPstate = oldFPstate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1716
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1717
              case SEMICOLON:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1718
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1719
                actions.defineField(p, curClass, doc, mod, t, id,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1720
                                    anames, exp, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1721
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
              default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
                // really expected a statement body here
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1725
                if ((mod & (M_NATIVE | M_ABSTRACT)) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
                    expect(LBRACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1727
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1728
                    expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1729
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1730
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1731
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1732
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1733
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1734
        // It is a list of instance variables
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1735
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1736
            p = pos;            // get the current position
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1737
            // parse the array brackets (if any)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1738
            // ie: var[][][]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1739
            Type vt = parseArrayBrackets(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1740
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1741
            // Parse the optional initializer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1742
            Node init = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1743
            if (token == ASSIGN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1744
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1745
                init = parseExpression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1746
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1747
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1748
            // Define the variable
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1749
            actions.defineField(p, curClass, doc, mod, vt, id,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1750
                                null, null, init);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1751
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1752
            // If the next token is a comma, then there is more
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1753
            if (token != COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1754
                expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1755
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1756
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1757
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1758
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1759
            // The next token must be an identifier
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1760
            id = scanner.getIdToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1761
            expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1762
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1763
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1764
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1765
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1766
     * Recover after a syntax error in a field. This involves
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1767
     * discarding tokens until an EOF or a possible legal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1768
     * continuation is encountered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1769
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1770
    protected void recoverField(ClassDefinition newClass) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1771
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1772
            switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1773
              case EOF:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1774
              case STATIC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1775
              case FINAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1776
              case PUBLIC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1777
              case PRIVATE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1778
              case SYNCHRONIZED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1779
              case TRANSIENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1780
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1781
              case VOID:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1782
              case BOOLEAN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1783
              case BYTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1784
              case CHAR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1785
              case SHORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1786
              case INT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1787
              case FLOAT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1788
              case LONG:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1789
              case DOUBLE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1790
                // possible begin of a field, continue
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1791
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1792
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1793
              case LBRACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1794
                match(LBRACE, RBRACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1795
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1796
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1797
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1798
              case LPAREN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1799
                match(LPAREN, RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1800
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1801
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1802
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1803
              case LSQBRACKET:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1804
                match(LSQBRACKET, RSQBRACKET);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1805
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1806
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1807
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1808
              case RBRACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1809
              case INTERFACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1810
              case CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1811
              case IMPORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1812
              case PACKAGE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1813
                // begin of something outside a class, panic more
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1814
                actions.endClass(pos, newClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1815
                throw new SyntaxError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1816
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1817
              default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1818
                // don't know what to do, skip
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1819
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1820
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1821
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1822
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1823
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1824
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1825
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1826
     * Parse a top-level class or interface declaration.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1827
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1828
    protected void parseClass() throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1829
        String doc = scanner.docComment;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1830
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1831
        // Parse the modifiers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1832
        int mod = parseModifiers(MM_CLASS | MM_MEMBER);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1833
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1834
        parseNamedClass(mod, PACKAGE, doc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1835
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1836
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1837
    // Current strict/default state of floating point.  This is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1838
    // set and reset with a stack discipline around methods and named
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1839
    // classes.  Only M_STRICTFP may be set in this word.  try...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1840
    // finally is not needed to protect setting and resetting because
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1841
    // there are no error messages based on FPstate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1842
    private int FPstate = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1843
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1844
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1845
     * Parse a block-local class or interface declaration.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1846
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1847
    protected Statement parseLocalClass(int mod) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1848
        long p = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1849
        ClassDefinition body = parseNamedClass(M_LOCAL | mod, STAT, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1850
        Statement ds[] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1851
            new VarDeclarationStatement(p, new LocalMember(body), null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1852
        };
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1853
        Expression type = new TypeExpression(p, body.getType());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1854
        return new DeclarationStatement(p, 0, type, ds);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1855
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1856
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1857
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1858
     * Parse a named class or interface declaration,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1859
     * starting at "class" or "interface".
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1860
     * @arg ctx Syntactic context of the class, one of {PACKAGE CLASS STAT EXPR}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1861
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1862
    protected ClassDefinition parseNamedClass(int mod, int ctx, String doc) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1863
        // Parse class/interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1864
        switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1865
          case INTERFACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1866
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1867
            mod |= M_INTERFACE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1868
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1869
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1870
          case CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1871
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1872
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1873
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1874
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1875
            env.error(pos, "class.expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1876
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1877
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1878
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1879
        int oldFPstate = FPstate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1880
        if ((mod & M_STRICTFP)!=0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1881
            FPstate = M_STRICTFP;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1882
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1883
            // The & (...) isn't really necessary here because we do maintain
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1884
            // the invariant that FPstate has no extra bits set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1885
            mod |= FPstate & M_STRICTFP;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1886
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1887
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1888
        // Parse the class name
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1889
        IdentifierToken nm = scanner.getIdToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1890
        long p = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1891
        expect(IDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1892
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1893
        Vector ext = new Vector();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1894
        Vector impl = new Vector();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1895
        parseInheritance(ext, impl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1896
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1897
        ClassDefinition tmp = parseClassBody(nm, mod, ctx, doc, ext, impl, p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1898
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1899
        FPstate = oldFPstate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1900
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1901
        return tmp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1902
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1903
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1904
    protected void parseInheritance(Vector ext, Vector impl) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1905
        // Parse extends clause
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1906
        if (token == EXTENDS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1907
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1908
            ext.addElement(parseName(false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1909
            while (token == COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1910
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1911
                ext.addElement(parseName(false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1912
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1913
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1914
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1915
        // Parse implements clause
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1916
        if (token == IMPLEMENTS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1917
            scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1918
            impl.addElement(parseName(false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1919
            while (token == COMMA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1920
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1921
                impl.addElement(parseName(false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1922
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1923
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1924
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1925
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1926
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1927
     * Parse the body of a class or interface declaration,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1928
     * starting at the left brace.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1929
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1930
    protected ClassDefinition parseClassBody(IdentifierToken nm, int mod,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1931
                                             int ctx, String doc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1932
                                             Vector ext, Vector impl, long p
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1933
                                             ) throws SyntaxError, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1934
        // Decide which is the super class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1935
        IdentifierToken sup = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1936
        if ((mod & M_INTERFACE) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1937
            if (impl.size() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1938
                env.error(((IdentifierToken)impl.elementAt(0)).getWhere(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1939
                          "intf.impl.intf");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1940
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1941
            impl = ext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1942
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1943
            if (ext.size() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1944
                if (ext.size() > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1945
                    env.error(((IdentifierToken)ext.elementAt(1)).getWhere(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1946
                              "multiple.inherit");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1947
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1948
                sup = (IdentifierToken)ext.elementAt(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1949
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1950
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1951
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1952
        ClassDefinition oldClass = curClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1953
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1954
        // Begin a new class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1955
        IdentifierToken implids[] = new IdentifierToken[impl.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1956
        impl.copyInto(implids);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1957
        ClassDefinition newClass =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1958
            actions.beginClass(p, doc, mod, nm, sup, implids);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1959
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1960
        // Parse fields
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1961
        expect(LBRACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1962
        while ((token != EOF) && (token != RBRACE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1963
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1964
                curClass = newClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1965
                parseField();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1966
            } catch (SyntaxError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1967
                recoverField(newClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1968
            } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1969
                curClass = oldClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1970
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1971
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1972
        expect(RBRACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1973
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1974
        // End the class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1975
        actions.endClass(scanner.prevPos, newClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1976
        return newClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1977
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1978
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1979
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1980
     * Recover after a syntax error in the file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1981
     * This involves discarding tokens until an EOF
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1982
     * or a possible legal continuation is encountered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1983
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1984
    protected void recoverFile() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1985
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1986
            switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1987
              case CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1988
              case INTERFACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1989
                // Start of a new source file statement, continue
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1990
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1991
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1992
              case LBRACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1993
                match(LBRACE, RBRACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1994
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1995
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1996
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1997
              case LPAREN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1998
                match(LPAREN, RPAREN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1999
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2000
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2001
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2002
              case LSQBRACKET:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2003
                match(LSQBRACKET, RSQBRACKET);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2004
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2005
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2006
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2007
              case EOF:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2008
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2009
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2010
              default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2011
                // Don't know what to do, skip
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2012
                scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2013
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2014
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2015
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2016
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2017
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2018
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2019
     * Parse an Java file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2020
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2021
    public void parseFile() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2022
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2023
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2024
                if (token == PACKAGE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2025
                    // Package statement
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2026
                    long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2027
                    IdentifierToken id = parseName(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2028
                    expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2029
                    actions.packageDeclaration(p, id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2030
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2031
            } catch (SyntaxError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2032
                recoverFile();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2033
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2034
            while (token == IMPORT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2035
                try{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2036
                    // Import statement
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2037
                    long p = scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2038
                    IdentifierToken id = parseName(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2039
                    expect(SEMICOLON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2040
                    if (id.id.getName().equals(idStar)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2041
                        id.id = id.id.getQualifier();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2042
                        actions.importPackage(p, id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2043
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2044
                        actions.importClass(p, id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2045
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2046
                } catch (SyntaxError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2047
                    recoverFile();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2048
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2049
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2050
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2051
            while (token != EOF) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2052
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2053
                    switch (token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2054
                      case FINAL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2055
                      case PUBLIC:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2056
                      case PRIVATE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2057
                      case ABSTRACT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2058
                      case CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2059
                      case INTERFACE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2060
                      case STRICTFP:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2061
                        // Start of a class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2062
                        parseClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2063
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2064
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2065
                      case SEMICOLON:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2066
                        // Bogus semicolon.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2067
                        // According to the JLS (7.6,19.6), a TypeDeclaration
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2068
                        // may consist of a single semicolon, however, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2069
                        // usage is discouraged (JLS 7.6).  In contrast,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2070
                        // a FieldDeclaration may not be empty, and is flagged
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2071
                        // as an error.  See parseField above.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2072
                        scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2073
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2074
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2075
                      case EOF:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2076
                        // The end
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2077
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2078
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2079
                      default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2080
                        // Oops
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2081
                        env.error(pos, "toplevel.expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2082
                        throw new SyntaxError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2083
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2084
                } catch (SyntaxError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2085
                    recoverFile();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2086
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2087
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2088
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2089
            env.error(pos, "io.exception", env.getSource());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2090
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2091
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2092
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2093
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2094
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2095
     * Usually <code>this.scanner == (Scanner)this</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2096
     * However, a delegate scanner can produce tokens for this parser,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2097
     * in which case <code>(Scanner)this</code> is unused,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2098
     * except for <code>this.token</code> and <code>this.pos</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2099
     * instance variables which are filled from the real scanner
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2100
     * by <code>this.scan()</code> and the constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2101
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2102
    protected Scanner scanner;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2103
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2104
    // Design Note: We ought to disinherit Parser from Scanner.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2105
    // We also should split out the interface ParserActions from
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2106
    // Parser, and make BatchParser implement ParserActions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2107
    // not extend Parser.  This would split scanning, parsing,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2108
    // and class building into distinct responsibility areas.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2109
    // (Perhaps tree building could be virtualized too.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2110
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2111
    public long scan() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2112
        if (scanner != this && scanner != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2113
            long result = scanner.scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2114
            ((Scanner)this).token = scanner.token;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2115
            ((Scanner)this).pos = scanner.pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2116
            return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2117
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2118
        return super.scan();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2119
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2120
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2121
    public void match(int open, int close) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2122
        if (scanner != this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2123
            scanner.match(open, close);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2124
            ((Scanner)this).token = scanner.token;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2125
            ((Scanner)this).pos = scanner.pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2126
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2127
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2128
        super.match(open, close);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2129
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2130
}