src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Lexer.java
author hannesw
Wed, 07 Mar 2018 18:36:21 +0100
changeset 49145 2854589fd853
parent 47337 079a87f87518
permissions -rw-r--r--
8199236: Nashorn uses deprecated HTML tags in Javadoc Reviewed-by: jlaskey, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
32321
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
     2
 * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.parser;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    28
import static jdk.nashorn.internal.parser.TokenType.ADD;
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
    29
import static jdk.nashorn.internal.parser.TokenType.BINARY_NUMBER;
19089
51cfdcf21d35 8021130: Comments need to be tokens
jlaskey
parents: 19083
diff changeset
    30
import static jdk.nashorn.internal.parser.TokenType.COMMENT;
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
    31
import static jdk.nashorn.internal.parser.TokenType.DECIMAL;
22390
1d2d88e478ea 8032068: implement @sourceURL and #sourceURL directives
sundar
parents: 21437
diff changeset
    32
import static jdk.nashorn.internal.parser.TokenType.DIRECTIVE_COMMENT;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import static jdk.nashorn.internal.parser.TokenType.EOF;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import static jdk.nashorn.internal.parser.TokenType.EOL;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    35
import static jdk.nashorn.internal.parser.TokenType.ERROR;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    36
import static jdk.nashorn.internal.parser.TokenType.ESCSTRING;
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16233
diff changeset
    37
import static jdk.nashorn.internal.parser.TokenType.EXECSTRING;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
import static jdk.nashorn.internal.parser.TokenType.FLOATING;
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
    39
import static jdk.nashorn.internal.parser.TokenType.FUNCTION;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
import static jdk.nashorn.internal.parser.TokenType.HEXADECIMAL;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
import static jdk.nashorn.internal.parser.TokenType.LBRACE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    42
import static jdk.nashorn.internal.parser.TokenType.LPAREN;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import static jdk.nashorn.internal.parser.TokenType.OCTAL;
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
    44
import static jdk.nashorn.internal.parser.TokenType.OCTAL_LEGACY;
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
    45
import static jdk.nashorn.internal.parser.TokenType.RBRACE;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    46
import static jdk.nashorn.internal.parser.TokenType.REGEX;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    47
import static jdk.nashorn.internal.parser.TokenType.RPAREN;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    48
import static jdk.nashorn.internal.parser.TokenType.STRING;
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
    49
import static jdk.nashorn.internal.parser.TokenType.TEMPLATE;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
    50
import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_HEAD;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
    51
import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_MIDDLE;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
    52
import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_TAIL;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
import static jdk.nashorn.internal.parser.TokenType.XML;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26505
diff changeset
    55
import java.io.Serializable;
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
    56
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    57
import jdk.nashorn.internal.runtime.ECMAErrors;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    58
import jdk.nashorn.internal.runtime.ErrorManager;
16256
f2d9a0c49914 8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents: 16234
diff changeset
    59
import jdk.nashorn.internal.runtime.JSErrorType;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
    60
import jdk.nashorn.internal.runtime.JSType;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    61
import jdk.nashorn.internal.runtime.ParserException;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
import jdk.nashorn.internal.runtime.Source;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
import jdk.nashorn.internal.runtime.options.Options;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    64
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    66
 * Responsible for converting source content into a stream of tokens.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    67
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    68
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
@SuppressWarnings("fallthrough")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    70
public class Lexer extends Scanner {
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
    71
    private static final long MIN_INT_L = Integer.MIN_VALUE;
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
    72
    private static final long MAX_INT_L = Integer.MAX_VALUE;
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
    73
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
    private static final boolean XML_LITERALS = Options.getBooleanProperty("nashorn.lexer.xmlliterals");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
    /** Content source. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
    private final Source source;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
    /** Buffered stream for tokens. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
    private final TokenStream stream;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    82
    /** True if here and edit strings are supported. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    83
    private final boolean scripting;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    84
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
    85
    /** True if parsing in ECMAScript 6 mode. */
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
    86
    private final boolean es6;
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
    87
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    88
    /** True if a nested scan. (scan to completion, no EOF.) */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
    private final boolean nested;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    91
    /** Pending new line number and position. */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
    92
    int pendingLine;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    93
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    94
    /** Position of last EOL + 1. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    95
    private int linePosition;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    96
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    97
    /** Type of last token added. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
    private TokenType last;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    99
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   100
    private final boolean pauseOnFunctionBody;
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   101
    private boolean pauseOnNextLeftBrace;
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   102
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   103
    private int templateExpressionOpenBraces;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   104
41982
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   105
    private static final String JAVASCRIPT_OTHER_WHITESPACE =
19083
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   106
        "\u2028" + // line separator
41982
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   107
        "\u2029" + // paragraph separator
19083
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   108
        "\u00a0" + // Latin-1 space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   109
        "\u1680" + // Ogham space mark
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   110
        "\u180e" + // separator, Mongolian vowel
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   111
        "\u2000" + // en quad
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   112
        "\u2001" + // em quad
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   113
        "\u2002" + // en space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   114
        "\u2003" + // em space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   115
        "\u2004" + // three-per-em space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   116
        "\u2005" + // four-per-em space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   117
        "\u2006" + // six-per-em space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   118
        "\u2007" + // figure space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   119
        "\u2008" + // punctuation space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   120
        "\u2009" + // thin space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   121
        "\u200a" + // hair space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   122
        "\u202f" + // narrow no-break space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   123
        "\u205f" + // medium mathematical space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   124
        "\u3000" + // ideographic space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   125
        "\ufeff"   // byte order mark
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   126
        ;
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   127
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   128
    private static final String JAVASCRIPT_WHITESPACE_IN_REGEXP =
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   129
        "\\u000a" + // line feed
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   130
        "\\u000d" + // carriage return (ctrl-m)
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   131
        "\\u2028" + // line separator
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   132
        "\\u2029" + // paragraph separator
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   133
        "\\u0009" + // tab
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   134
        "\\u0020" + // ASCII space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   135
        "\\u000b" + // tabulation line
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   136
        "\\u000c" + // ff (ctrl-l)
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   137
        "\\u00a0" + // Latin-1 space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   138
        "\\u1680" + // Ogham space mark
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   139
        "\\u180e" + // separator, Mongolian vowel
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   140
        "\\u2000" + // en quad
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   141
        "\\u2001" + // em quad
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   142
        "\\u2002" + // en space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   143
        "\\u2003" + // em space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   144
        "\\u2004" + // three-per-em space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   145
        "\\u2005" + // four-per-em space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   146
        "\\u2006" + // six-per-em space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   147
        "\\u2007" + // figure space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   148
        "\\u2008" + // punctuation space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   149
        "\\u2009" + // thin space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   150
        "\\u200a" + // hair space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   151
        "\\u202f" + // narrow no-break space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   152
        "\\u205f" + // medium mathematical space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   153
        "\\u3000" + // ideographic space
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   154
        "\\ufeff"   // byte order mark
971f4e311234 8020596: Initialization of white space strings in scanner should be done with \u strings
jlaskey
parents: 18870
diff changeset
   155
        ;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   156
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   157
    static String unicodeEscape(final char ch) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   158
        final StringBuilder sb = new StringBuilder();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   159
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   160
        sb.append("\\u");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   161
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   162
        final String hex = Integer.toHexString(ch);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   163
        for (int i = hex.length(); i < 4; i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   164
            sb.append('0');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   165
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   166
        sb.append(hex);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   167
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   168
        return sb.toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   169
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   170
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   171
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   172
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   173
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   174
     * @param source    the source
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   175
     * @param stream    the token stream to lex
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   176
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   177
    public Lexer(final Source source, final TokenStream stream) {
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
   178
        this(source, stream, false, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   179
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   180
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   181
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   182
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   183
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
     * @param source    the source
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
     * @param stream    the token stream to lex
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   186
     * @param scripting are we in scripting mode
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
   187
     * @param es6       are we in ECMAScript 6 mode
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
     */
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
   189
    public Lexer(final Source source, final TokenStream stream, final boolean scripting, final boolean es6) {
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
   190
        this(source, 0, source.getLength(), stream, scripting, es6, false);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   191
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   192
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   193
    /**
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   194
     * Constructor
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   195
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   196
     * @param source    the source
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   197
     * @param start     start position in source from which to start lexing
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   198
     * @param len       length of source segment to lex
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   199
     * @param stream    token stream to lex
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   200
     * @param scripting are we in scripting mode
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
   201
     * @param es6       are we in ECMAScript 6 mode
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   202
     * @param pauseOnFunctionBody if true, lexer will return from {@link #lexify()} when it encounters a
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   203
     * function body. This is used with the feature where the parser is skipping nested function bodies to
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   204
     * avoid reading ahead unnecessarily when we skip the function bodies.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   205
     */
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
   206
    public Lexer(final Source source, final int start, final int len, final TokenStream stream, final boolean scripting, final boolean es6, final boolean pauseOnFunctionBody) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   207
        super(source.getContent(), 1, start, len);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   208
        this.source      = source;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   209
        this.stream      = stream;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   210
        this.scripting   = scripting;
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
   211
        this.es6         = es6;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   212
        this.nested      = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   213
        this.pendingLine = 1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   214
        this.last        = EOL;
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   215
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   216
        this.pauseOnFunctionBody = pauseOnFunctionBody;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   217
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   218
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   219
    private Lexer(final Lexer lexer, final State state) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
        super(lexer, state);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   221
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   222
        source = lexer.source;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   223
        stream = lexer.stream;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   224
        scripting = lexer.scripting;
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
   225
        es6 = lexer.es6;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   226
        nested = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   227
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   228
        pendingLine = state.pendingLine;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   229
        linePosition = state.linePosition;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   230
        last = EOL;
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   231
        pauseOnFunctionBody = false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   232
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   233
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   234
    static class State extends Scanner.State {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   235
        /** Pending new line number and position. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   236
        public final int pendingLine;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   237
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   238
        /** Position of last EOL + 1. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   239
        public final int linePosition;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   240
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   241
        /** Type of last token added. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   242
        public final TokenType last;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   243
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   244
        /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   245
         * Constructor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   246
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   247
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   248
        State(final int position, final int limit, final int line, final int pendingLine, final int linePosition, final TokenType last) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   249
            super(position, limit, line);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   250
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   251
            this.pendingLine = pendingLine;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   252
            this.linePosition = linePosition;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   253
            this.last = last;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   254
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   255
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   256
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   257
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   258
     * Save the state of the scan.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   259
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   260
     * @return Captured state.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   261
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   262
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   263
    State saveState() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   264
        return new State(position, limit, line, pendingLine, linePosition, last);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   265
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   266
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   267
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   268
     * Restore the state of the scan.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   269
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   270
     * @param state
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   271
     *            Captured state.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   272
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   273
    void restoreState(final State state) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   274
        super.restoreState(state);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   275
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   276
        pendingLine = state.pendingLine;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   277
        linePosition = state.linePosition;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   278
        last = state.last;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   279
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   280
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   281
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   282
     * Add a new token to the stream.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   283
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   284
     * @param type
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   285
     *            Token type.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   286
     * @param start
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   287
     *            Start position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   288
     * @param end
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   289
     *            End position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   290
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   291
    protected void add(final TokenType type, final int start, final int end) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   292
        // Record last token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   293
        last = type;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   294
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   295
        // Only emit the last EOL in a cluster.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   296
        if (type == EOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   297
            pendingLine = end;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   298
            linePosition = start;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   299
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   300
            // Write any pending EOL to stream.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   301
            if (pendingLine != -1) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   302
                stream.put(Token.toDesc(EOL, linePosition, pendingLine));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   303
                pendingLine = -1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   304
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   305
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   306
            // Write token to stream.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   307
            stream.put(Token.toDesc(type, start, end - start));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   308
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   309
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   310
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   311
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   312
     * Add a new token to the stream.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   313
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   314
     * @param type
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   315
     *            Token type.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   316
     * @param start
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   317
     *            Start position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   318
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   319
    protected void add(final TokenType type, final int start) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   320
        add(type, start, position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   321
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   322
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   323
    /**
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   324
     * Return the String of valid whitespace characters for regular
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   325
     * expressions in JavaScript
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   326
     * @return regexp whitespace string
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   327
     */
16226
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16211
diff changeset
   328
    public static String getWhitespaceRegExp() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   329
        return JAVASCRIPT_WHITESPACE_IN_REGEXP;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   330
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   331
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   332
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   333
     * Skip end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   334
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   335
     * @param addEOL true if EOL token should be recorded.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   336
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   337
    private void skipEOL(final boolean addEOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   338
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   339
        if (ch0 == '\r') { // detect \r\n pattern
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   340
            skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   341
            if (ch0 == '\n') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   342
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   343
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   344
        } else { // all other space, ch0 is guaranteed to be EOL or \0
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   345
            skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   346
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   347
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   348
        // bump up line count
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   349
        line++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   350
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   351
        if (addEOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   352
            // Add an EOL token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   353
            add(EOL, position, line);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   354
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   355
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   356
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   357
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   358
     * Skip over rest of line including end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   359
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   360
     * @param addEOL true if EOL token should be recorded.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   361
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   362
    private void skipLine(final boolean addEOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   363
        // Ignore characters.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   364
        while (!isEOL(ch0) && !atEOF()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   365
            skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   366
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   367
        // Skip over end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   368
        skipEOL(addEOL);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   369
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   370
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   371
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   372
     * Test whether a char is valid JavaScript whitespace
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   373
     * @param ch a char
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   374
     * @return true if valid JavaScript whitespace
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   375
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   376
    public static boolean isJSWhitespace(final char ch) {
41982
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   377
        return ch == ' '                  // space
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   378
            || ch >= '\t' && ch <= '\r'   // 0x09..0x0d: tab, line feed, tabulation line, ff, carriage return
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   379
            || ch >= 160 && isOtherJSWhitespace(ch);
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   380
    }
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   381
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   382
    private static boolean isOtherJSWhitespace(final char ch) {
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   383
        return JAVASCRIPT_OTHER_WHITESPACE.indexOf(ch) != -1;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   384
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   385
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   386
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   387
     * Test whether a char is valid JavaScript end of line
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   388
     * @param ch a char
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   389
     * @return true if valid JavaScript end of line
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   390
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   391
    public static boolean isJSEOL(final char ch) {
41982
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   392
        return ch == '\n'      // line feed
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   393
            || ch == '\r'      // carriage return (ctrl-m)
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   394
            || ch == '\u2028'  // line separator
d7226731ac08 8168049: Fix Performance of Lexer.isJSWhitespace
hannesw
parents: 41422
diff changeset
   395
            || ch == '\u2029'; // paragraph separator
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   396
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   397
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   398
    /**
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   399
     * Test if char is a string delimiter, e.g. '\' or '"'.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   400
     * @param ch a char
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   401
     * @return true if string delimiter
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   402
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   403
    protected boolean isStringDelimiter(final char ch) {
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   404
        return ch == '\'' || ch == '"';
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   405
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   406
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   407
    /**
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   408
     * Test if char is a template literal delimiter ('`').
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   409
     */
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 39168
diff changeset
   410
    private static boolean isTemplateDelimiter(final char ch) {
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   411
        return ch == '`';
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   412
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   413
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   414
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
     * Test whether a char is valid JavaScript whitespace
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   416
     * @param ch a char
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   417
     * @return true if valid JavaScript whitespace
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   418
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
    protected boolean isWhitespace(final char ch) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   420
        return Lexer.isJSWhitespace(ch);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   421
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   422
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   423
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   424
     * Test whether a char is valid JavaScript end of line
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   425
     * @param ch a char
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
     * @return true if valid JavaScript end of line
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   427
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   428
    protected boolean isEOL(final char ch) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   429
        return Lexer.isJSEOL(ch);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   430
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   431
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   432
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   433
     * Skip over whitespace and detect end of line, adding EOL tokens if
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   434
     * encountered.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   435
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   436
     * @param addEOL true if EOL tokens should be recorded.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   437
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   438
    private void skipWhitespace(final boolean addEOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   439
        while (isWhitespace(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   440
            if (isEOL(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   441
                skipEOL(addEOL);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   442
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   443
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   444
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   445
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   446
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   447
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   448
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   449
     * Skip over comments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   450
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   451
     * @return True if a comment.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   452
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   453
    protected boolean skipComments() {
19089
51cfdcf21d35 8021130: Comments need to be tokens
jlaskey
parents: 19083
diff changeset
   454
        // Save the current position.
51cfdcf21d35 8021130: Comments need to be tokens
jlaskey
parents: 19083
diff changeset
   455
        final int start = position;
51cfdcf21d35 8021130: Comments need to be tokens
jlaskey
parents: 19083
diff changeset
   456
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   457
        if (ch0 == '/') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   458
            // Is it a // comment.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   459
            if (ch1 == '/') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   460
                // Skip over //.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   461
                skip(2);
22390
1d2d88e478ea 8032068: implement @sourceURL and #sourceURL directives
sundar
parents: 21437
diff changeset
   462
1d2d88e478ea 8032068: implement @sourceURL and #sourceURL directives
sundar
parents: 21437
diff changeset
   463
                boolean directiveComment = false;
1d2d88e478ea 8032068: implement @sourceURL and #sourceURL directives
sundar
parents: 21437
diff changeset
   464
                if ((ch0 == '#' || ch0 == '@') && (ch1 == ' ')) {
1d2d88e478ea 8032068: implement @sourceURL and #sourceURL directives
sundar
parents: 21437
diff changeset
   465
                    directiveComment = true;
1d2d88e478ea 8032068: implement @sourceURL and #sourceURL directives
sundar
parents: 21437
diff changeset
   466
                }
1d2d88e478ea 8032068: implement @sourceURL and #sourceURL directives
sundar
parents: 21437
diff changeset
   467
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   468
                // Scan for EOL.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   469
                while (!atEOF() && !isEOL(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   470
                    skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   471
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   472
                // Did detect a comment.
22390
1d2d88e478ea 8032068: implement @sourceURL and #sourceURL directives
sundar
parents: 21437
diff changeset
   473
                add(directiveComment? DIRECTIVE_COMMENT : COMMENT, start);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   474
                return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   475
            } else if (ch1 == '*') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   476
                // Skip over /*.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   477
                skip(2);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   478
                // Scan for */.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   479
                while (!atEOF() && !(ch0 == '*' && ch1 == '/')) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   480
                    // If end of line handle else skip character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   481
                    if (isEOL(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   482
                        skipEOL(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   483
                    } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   484
                        skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   485
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   486
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   487
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   488
                if (atEOF()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   489
                    // TODO - Report closing */ missing in parser.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   490
                    add(ERROR, start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   491
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   492
                    // Skip */.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   493
                    skip(2);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   494
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   495
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   496
                // Did detect a comment.
19089
51cfdcf21d35 8021130: Comments need to be tokens
jlaskey
parents: 19083
diff changeset
   497
                add(COMMENT, start);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   498
                return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   499
            }
19089
51cfdcf21d35 8021130: Comments need to be tokens
jlaskey
parents: 19083
diff changeset
   500
        } else if (ch0 == '#') {
51cfdcf21d35 8021130: Comments need to be tokens
jlaskey
parents: 19083
diff changeset
   501
            assert scripting;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   502
            // shell style comment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   503
            // Skip over #.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   504
            skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   505
            // Scan for EOL.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   506
            while (!atEOF() && !isEOL(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   507
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   508
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   509
            // Did detect a comment.
19089
51cfdcf21d35 8021130: Comments need to be tokens
jlaskey
parents: 19083
diff changeset
   510
            add(COMMENT, start);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   511
            return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   512
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   513
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   514
        // Not a comment.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   515
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   516
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   517
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   518
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   519
     * Convert a regex token to a token object.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   520
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   521
     * @param start  Position in source content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   522
     * @param length Length of regex token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   523
     * @return Regex token object.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   524
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   525
    public RegexToken valueOfPattern(final int start, final int length) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   526
        // Save the current position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   527
        final int savePosition = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   528
        // Reset to beginning of content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   529
        reset(start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   530
        // Buffer for recording characters.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   531
        final StringBuilder sb = new StringBuilder(length);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   532
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   533
        // Skip /.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   534
        skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   535
        boolean inBrackets = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   536
        // Scan for closing /, stopping at end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   537
        while (!atEOF() && ch0 != '/' && !isEOL(ch0) || inBrackets) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   538
            // Skip over escaped character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   539
            if (ch0 == '\\') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   540
                sb.append(ch0);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   541
                sb.append(ch1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   542
                skip(2);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   543
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   544
                if (ch0 == '[') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   545
                    inBrackets = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   546
                } else if (ch0 == ']') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   547
                    inBrackets = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   548
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   549
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   550
                // Skip literal character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   551
                sb.append(ch0);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   552
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   553
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   554
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   555
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   556
        // Get pattern as string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   557
        final String regex = sb.toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   558
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   559
        // Skip /.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   560
        skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   561
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   562
        // Options as string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   563
        final String options = source.getString(position, scanIdentifier());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   564
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   565
        reset(savePosition);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   566
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   567
        // Compile the pattern.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   568
        return new RegexToken(regex, options);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   569
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   570
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   571
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   572
     * Return true if the given token can be the beginning of a literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   573
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   574
     * @param token a token
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   575
     * @return true if token can start a literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   576
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   577
    public boolean canStartLiteral(final TokenType token) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   578
        return token.startsWith('/') || ((scripting || XML_LITERALS) && token.startsWith('<'));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   579
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   580
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   581
    /**
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   582
     * interface to receive line information for multi-line literals.
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   583
     */
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   584
    protected interface LineInfoReceiver {
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   585
        /**
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   586
         * Receives line information
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   587
         * @param line last line number
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   588
         * @param linePosition position of last line
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   589
         */
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   590
        public void lineInfo(int line, int linePosition);
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   591
    }
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   592
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   593
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   594
     * Check whether the given token represents the beginning of a literal. If so scan
49145
2854589fd853 8199236: Nashorn uses deprecated HTML tags in Javadoc
hannesw
parents: 47337
diff changeset
   595
     * the literal and return <code>true</code>, otherwise return false.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   596
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   597
     * @param token the token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   598
     * @param startTokenType the token type.
19089
51cfdcf21d35 8021130: Comments need to be tokens
jlaskey
parents: 19083
diff changeset
   599
     * @param lir LineInfoReceiver that receives line info for multi-line string literals.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
     * @return True if a literal beginning with startToken was found and scanned.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   601
     */
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
   602
    protected boolean scanLiteral(final long token, final TokenType startTokenType, final LineInfoReceiver lir) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   603
        // Check if it can be a literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   604
        if (!canStartLiteral(startTokenType)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   605
            return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   606
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   607
        // We break on ambiguous tokens so if we already moved on it can't be a literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   608
        if (stream.get(stream.last()) != token) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   609
            return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   610
        }
39168
e02c166da4dd 8073653: Secondary heredoc eating wrong lines.
hannesw
parents: 34732
diff changeset
   611
e02c166da4dd 8073653: Secondary heredoc eating wrong lines.
hannesw
parents: 34732
diff changeset
   612
        // Record current position in case multiple heredocs start on this line - see JDK-8073653
e02c166da4dd 8073653: Secondary heredoc eating wrong lines.
hannesw
parents: 34732
diff changeset
   613
        final State state = saveState();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   614
        // Rewind to token start position
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   615
        reset(Token.descPosition(token));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   616
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   617
        if (ch0 == '/') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   618
            return scanRegEx();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   619
        } else if (ch0 == '<') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   620
            if (ch1 == '<') {
39168
e02c166da4dd 8073653: Secondary heredoc eating wrong lines.
hannesw
parents: 34732
diff changeset
   621
                return scanHereString(lir, state);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   622
            } else if (Character.isJavaIdentifierStart(ch1)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   623
                return scanXMLLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   624
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   625
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   626
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   627
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   628
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   629
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   630
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   631
     * Scan over regex literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   632
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   633
     * @return True if a regex literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   634
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   635
    private boolean scanRegEx() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   636
        assert ch0 == '/';
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   637
        // Make sure it's not a comment.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   638
        if (ch1 != '/' && ch1 != '*') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   639
            // Record beginning of literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   640
            final int start = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   641
            // Skip /.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   642
            skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   643
            boolean inBrackets = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   644
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   645
            // Scan for closing /, stopping at end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   646
            while (!atEOF() && (ch0 != '/' || inBrackets) && !isEOL(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   647
                // Skip over escaped character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   648
                if (ch0 == '\\') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   649
                    skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   650
                    if (isEOL(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   651
                        reset(start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   652
                        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   653
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   654
                    skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   655
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   656
                    if (ch0 == '[') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   657
                        inBrackets = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   658
                    } else if (ch0 == ']') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   659
                        inBrackets = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   660
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   661
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   662
                    // Skip literal character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   663
                    skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   664
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   665
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   666
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   667
            // If regex literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   668
            if (ch0 == '/') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   669
                // Skip /.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   670
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   671
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   672
                // Skip over options.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   673
                while (!atEOF() && Character.isJavaIdentifierPart(ch0) || ch0 == '\\' && ch1 == 'u') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   674
                    skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   675
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   676
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   677
                // Add regex token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   678
                add(REGEX, start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   679
                // Regex literal detected.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   680
                return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   681
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   682
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   683
            // False start try again.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   684
            reset(start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   685
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   686
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   687
        // Regex literal not detected.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   688
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   689
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   690
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   691
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   692
     * Convert a digit to a integer.  Can't use Character.digit since we are
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   693
     * restricted to ASCII by the spec.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   694
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   695
     * @param ch   Character to convert.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   696
     * @param base Numeric base.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   697
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   698
     * @return The converted digit or -1 if invalid.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   699
     */
18317
2f5434c9c9fd 8015346: JSON parsing issues with escaped strings, octal, decimal numbers
sundar
parents: 17246
diff changeset
   700
    protected static int convertDigit(final char ch, final int base) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   701
        int digit;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   702
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   703
        if ('0' <= ch && ch <= '9') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   704
            digit = ch - '0';
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   705
        } else if ('A' <= ch && ch <= 'Z') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   706
            digit = ch - 'A' + 10;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   707
        } else if ('a' <= ch && ch <= 'z') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   708
            digit = ch - 'a' + 10;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   709
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   710
            return -1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   711
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   712
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   713
        return digit < base ? digit : -1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   714
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   715
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   716
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   717
    /**
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   718
     * Get the value of a hexadecimal numeric sequence.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   719
     *
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   720
     * @param length Number of digits.
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   721
     * @param type   Type of token to report against.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   722
     * @return Value of sequence or < 0 if no digits.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   723
     */
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   724
    private int hexSequence(final int length, final TokenType type) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   725
        int value = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   726
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   727
        for (int i = 0; i < length; i++) {
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   728
            final int digit = convertDigit(ch0, 16);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   729
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   730
            if (digit == -1) {
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   731
                error(Lexer.message("invalid.hex"), type, position, limit);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   732
                return i == 0 ? -1 : value;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   733
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   734
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   735
            value = digit | value << 4;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   736
            skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   737
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   738
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   739
        return value;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   740
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   741
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   742
    /**
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   743
     * Get the value of an octal numeric sequence. This parses up to 3 digits with a maximum value of 255.
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   744
     *
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   745
     * @return Value of sequence.
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   746
     */
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   747
    private int octalSequence() {
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   748
        int value = 0;
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   749
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   750
        for (int i = 0; i < 3; i++) {
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   751
            final int digit = convertDigit(ch0, 8);
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   752
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   753
            if (digit == -1) {
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   754
                break;
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   755
            }
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   756
            value = digit | value << 3;
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   757
            skip(1);
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   758
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   759
            if (i == 1 && value >= 32) {
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   760
                break;
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   761
            }
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   762
        }
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   763
        return value;
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   764
    }
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   765
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   766
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   767
     * Convert a string to a JavaScript identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   768
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   769
     * @param start  Position in source content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   770
     * @param length Length of token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   771
     * @return Ident string or null if an error.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   772
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   773
    private String valueOfIdent(final int start, final int length) throws RuntimeException {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   774
        // Save the current position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   775
        final int savePosition = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   776
        // End of scan.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   777
        final int end = start + length;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   778
        // Reset to beginning of content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   779
        reset(start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   780
        // Buffer for recording characters.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   781
        final StringBuilder sb = new StringBuilder(length);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   782
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   783
        // Scan until end of line or end of file.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   784
        while (!atEOF() && position < end && !isEOL(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   785
            // If escape character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   786
            if (ch0 == '\\' && ch1 == 'u') {
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   787
                skip(2);
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   788
                final int ch = hexSequence(4, TokenType.IDENT);
47337
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47216
diff changeset
   789
                assert ! isWhitespace((char)ch);
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47216
diff changeset
   790
                assert ch >= 0;
079a87f87518 8027302: Identifiers containing unicode escapes are not recognized as reserved words
hannesw
parents: 47216
diff changeset
   791
                sb.append((char)ch);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   792
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   793
                // Add regular character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   794
                sb.append(ch0);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   795
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   796
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   797
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   798
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   799
        // Restore position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   800
        reset(savePosition);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   801
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   802
        return sb.toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   803
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   804
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   805
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   806
     * Scan over and identifier or keyword. Handles identifiers containing
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   807
     * encoded Unicode chars.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   808
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   809
     * Example:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   810
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   811
     * var \u0042 = 44;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   812
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   813
    private void scanIdentifierOrKeyword() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   814
        // Record beginning of identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   815
        final int start = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   816
        // Scan identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   817
        final int length = scanIdentifier();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   818
        // Check to see if it is a keyword.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   819
        final TokenType type = TokenLookup.lookupKeyword(content, start, length);
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   820
        if (type == FUNCTION && pauseOnFunctionBody) {
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   821
            pauseOnNextLeftBrace = true;
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
   822
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   823
        // Add keyword or identifier token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   824
        add(type, start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   825
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   826
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   827
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   828
     * Convert a string to a JavaScript string object.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   829
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   830
     * @param start  Position in source content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   831
     * @param length Length of token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   832
     * @return JavaScript string object.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   833
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   834
    private String valueOfString(final int start, final int length, final boolean strict) throws RuntimeException {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   835
        // Save the current position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   836
        final int savePosition = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   837
        // Calculate the end position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   838
        final int end = start + length;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   839
        // Reset to beginning of string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   840
        reset(start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   841
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   842
        // Buffer for recording characters.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   843
        final StringBuilder sb = new StringBuilder(length);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   844
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   845
        // Scan until end of string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   846
        while (position < end) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   847
            // If escape character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   848
            if (ch0 == '\\') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   849
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   850
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   851
                final char next = ch0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   852
                final int afterSlash = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   853
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   854
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   855
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   856
                // Special characters.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   857
                switch (next) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   858
                case '0':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   859
                case '1':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   860
                case '2':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   861
                case '3':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   862
                case '4':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   863
                case '5':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   864
                case '6':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   865
                case '7': {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   866
                    if (strict) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   867
                        // "\0" itself is allowed in strict mode. Only other 'real'
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   868
                        // octal escape sequences are not allowed (eg. "\02", "\31").
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   869
                        // See section 7.8.4 String literals production EscapeSequence
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   870
                        if (next != '0' || (ch0 >= '0' && ch0 <= '9')) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   871
                            error(Lexer.message("strict.no.octal"), STRING, position, limit);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   872
                        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   873
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   874
                    reset(afterSlash);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   875
                    // Octal sequence.
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   876
                    final int ch = octalSequence();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   877
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   878
                    if (ch < 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   879
                        sb.append('\\');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   880
                        sb.append('x');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   881
                    } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   882
                        sb.append((char)ch);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   883
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   884
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   885
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   886
                case 'n':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   887
                    sb.append('\n');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   888
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   889
                case 't':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   890
                    sb.append('\t');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   891
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   892
                case 'b':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   893
                    sb.append('\b');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   894
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   895
                case 'f':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   896
                    sb.append('\f');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   897
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   898
                case 'r':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   899
                    sb.append('\r');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   900
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   901
                case '\'':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   902
                    sb.append('\'');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   903
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   904
                case '\"':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   905
                    sb.append('\"');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   906
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   907
                case '\\':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   908
                    sb.append('\\');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   909
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   910
                case '\r': // CR | CRLF
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   911
                    if (ch0 == '\n') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   912
                        skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   913
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   914
                    // fall through
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   915
                case '\n': // LF
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   916
                case '\u2028': // LS
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   917
                case '\u2029': // PS
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   918
                    // continue on the next line, slash-return continues string
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   919
                    // literal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   920
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   921
                case 'x': {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   922
                    // Hex sequence.
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   923
                    final int ch = hexSequence(2, STRING);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   924
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   925
                    if (ch < 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   926
                        sb.append('\\');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   927
                        sb.append('x');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   928
                    } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   929
                        sb.append((char)ch);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   930
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   931
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   932
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   933
                case 'u': {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   934
                    // Unicode sequence.
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
   935
                    final int ch = hexSequence(4, STRING);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   936
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   937
                    if (ch < 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   938
                        sb.append('\\');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   939
                        sb.append('u');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   940
                    } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   941
                        sb.append((char)ch);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   942
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   943
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   944
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   945
                case 'v':
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   946
                    sb.append('\u000B');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   947
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   948
                // All other characters.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   949
                default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   950
                    sb.append(next);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   951
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   952
                }
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   953
            } else if (ch0 == '\r') {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   954
                // Convert CR-LF or CR to LF line terminator.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   955
                sb.append('\n');
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   956
                skip(ch1 == '\n' ? 2 : 1);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   957
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   958
                // Add regular character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   959
                sb.append(ch0);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   960
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   961
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   962
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   963
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   964
        // Restore position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   965
        reset(savePosition);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   966
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   967
        return sb.toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   968
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   969
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   970
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   971
     * Scan over a string literal.
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
   972
     * @param add true if we are not just scanning but should actually modify the token stream
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   973
     */
18317
2f5434c9c9fd 8015346: JSON parsing issues with escaped strings, octal, decimal numbers
sundar
parents: 17246
diff changeset
   974
    protected void scanString(final boolean add) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   975
        // Type of string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   976
        TokenType type = STRING;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   977
        // Record starting quote.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   978
        final char quote = ch0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   979
        // Skip over quote.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   980
        skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   981
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   982
        // Record beginning of string content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   983
        final State stringState = saveState();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   984
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   985
        // Scan until close quote or end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   986
        while (!atEOF() && ch0 != quote && !isEOL(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   987
            // Skip over escaped character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   988
            if (ch0 == '\\') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   989
                type = ESCSTRING;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   990
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   991
                if (isEOL(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   992
                    // Multiline string literal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   993
                    skipEOL(false);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   994
                    continue;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   995
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   996
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   997
            // Skip literal character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   998
            skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   999
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1000
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1001
        // If close quote.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1002
        if (ch0 == quote) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1003
            // Skip close quote.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1004
            skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1005
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1006
            error(Lexer.message("missing.close.quote"), STRING, position, limit);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1007
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1008
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1009
        // If not just scanning.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1010
        if (add) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1011
            // Record end of string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1012
            stringState.setLimit(position - 1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1013
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1014
            if (scripting && !stringState.isEmpty()) {
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1015
                switch (quote) {
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1016
                case '`':
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1017
                    // Mark the beginning of an exec string.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1018
                    add(EXECSTRING, stringState.position, stringState.limit);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1019
                    // Frame edit string with left brace.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1020
                    add(LBRACE, stringState.position, stringState.position);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1021
                    // Process edit string.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1022
                    editString(type, stringState);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1023
                    // Frame edit string with right brace.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1024
                    add(RBRACE, stringState.limit, stringState.limit);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1025
                    break;
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1026
                case '"':
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1027
                    // Only edit double quoted strings.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1028
                    editString(type, stringState);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1029
                    break;
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1030
                case '\'':
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1031
                    // Add string token without editing.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1032
                    add(type, stringState.position, stringState.limit);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1033
                    break;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  1034
                default:
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  1035
                    break;
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1036
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1037
            } else {
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16151
diff changeset
  1038
                /// Add string token without editing.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1039
                add(type, stringState.position, stringState.limit);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1040
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1041
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1042
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1043
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1044
    /**
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1045
     * Scan over a template string literal.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1046
     */
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1047
    private void scanTemplate() {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1048
        assert ch0 == '`';
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1049
        TokenType type = TEMPLATE;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1050
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1051
        // Skip over quote and record beginning of string content.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1052
        skip(1);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1053
        State stringState = saveState();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1054
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1055
        // Scan until close quote
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1056
        while (!atEOF()) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1057
            // Skip over escaped character.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1058
            if (ch0 == '`') {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1059
                skip(1);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1060
                // Record end of string.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1061
                stringState.setLimit(position - 1);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1062
                add(type == TEMPLATE ? type : TEMPLATE_TAIL, stringState.position, stringState.limit);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1063
                return;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1064
            } else if (ch0 == '$' && ch1 == '{') {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1065
                skip(2);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1066
                stringState.setLimit(position - 2);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1067
                add(type == TEMPLATE ? TEMPLATE_HEAD : type, stringState.position, stringState.limit);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1068
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1069
                // scan to RBRACE
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 39168
diff changeset
  1070
                final Lexer expressionLexer = new Lexer(this, saveState());
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1071
                expressionLexer.templateExpressionOpenBraces = 1;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1072
                expressionLexer.lexify();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1073
                restoreState(expressionLexer.saveState());
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1074
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1075
                // scan next middle or tail of the template literal
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1076
                assert ch0 == '}';
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1077
                type = TEMPLATE_MIDDLE;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1078
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1079
                // Skip over rbrace and record beginning of string content.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1080
                skip(1);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1081
                stringState = saveState();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1082
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1083
                continue;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1084
            } else if (ch0 == '\\') {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1085
                skip(1);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1086
                // EscapeSequence
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1087
                if (isEOL(ch0)) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1088
                    // LineContinuation
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1089
                    skipEOL(false);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1090
                    continue;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1091
                }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1092
            }  else if (isEOL(ch0)) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1093
                // LineTerminatorSequence
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1094
                skipEOL(false);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1095
                continue;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1096
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1097
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1098
            // Skip literal character.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1099
            skip(1);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1100
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1101
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1102
        error(Lexer.message("missing.close.quote"), TEMPLATE, position, limit);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1103
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1104
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1105
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1106
     * Convert string to number.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1107
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1108
     * @param valueString  String to convert.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1109
     * @param radix        Numeric base.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1110
     * @return Converted number.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1111
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1112
    private static Number valueOf(final String valueString, final int radix) throws NumberFormatException {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1113
        try {
34732
6605efbe8447 8144020: Remove long as an internal numeric type
hannesw
parents: 33890
diff changeset
  1114
            return Integer.parseInt(valueString, radix);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1115
        } catch (final NumberFormatException e) {
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1116
            if (radix == 10) {
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1117
                return Double.valueOf(valueString);
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1118
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1119
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1120
            double value = 0.0;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1121
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1122
            for (int i = 0; i < valueString.length(); i++) {
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1123
                final char ch = valueString.charAt(i);
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1124
                // Preverified, should always be a valid digit.
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1125
                final int digit = convertDigit(ch, radix);
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1126
                value *= radix;
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1127
                value += digit;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1128
            }
17246
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1129
a1bcf4d2bff1 8013203: A collection of smaller speedups to compilation pipeline
attila
parents: 16256
diff changeset
  1130
            return value;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1131
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1132
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1133
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1134
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1135
     * Scan a number.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1136
     */
18317
2f5434c9c9fd 8015346: JSON parsing issues with escaped strings, octal, decimal numbers
sundar
parents: 17246
diff changeset
  1137
    protected void scanNumber() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1138
        // Record beginning of number.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1139
        final int start = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1140
        // Assume value is a decimal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1141
        TokenType type = DECIMAL;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1142
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1143
        // First digit of number.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1144
        int digit = convertDigit(ch0, 10);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1145
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1146
        // If number begins with 0x.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1147
        if (digit == 0 && (ch1 == 'x' || ch1 == 'X') && convertDigit(ch2, 16) != -1) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1148
            // Skip over 0xN.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1149
            skip(3);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1150
            // Skip over remaining digits.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1151
            while (convertDigit(ch0, 16) != -1) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1152
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1153
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1154
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1155
            type = HEXADECIMAL;
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1156
        } else if (digit == 0 && es6 && (ch1 == 'o' || ch1 == 'O') && convertDigit(ch2, 8) != -1) {
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1157
            // Skip over 0oN.
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1158
            skip(3);
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1159
            // Skip over remaining digits.
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1160
            while (convertDigit(ch0, 8) != -1) {
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1161
                skip(1);
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1162
            }
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1163
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1164
            type = OCTAL;
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1165
        } else if (digit == 0 && es6 && (ch1 == 'b' || ch1 == 'B') && convertDigit(ch2, 2) != -1) {
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1166
            // Skip over 0bN.
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1167
            skip(3);
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1168
            // Skip over remaining digits.
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1169
            while (convertDigit(ch0, 2) != -1) {
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1170
                skip(1);
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1171
            }
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1172
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1173
            type = BINARY_NUMBER;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1174
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1175
            // Check for possible octal constant.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1176
            boolean octal = digit == 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1177
            // Skip first digit if not leading '.'.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1178
            if (digit != -1) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1179
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1180
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1181
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1182
            // Skip remaining digits.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1183
            while ((digit = convertDigit(ch0, 10)) != -1) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1184
                // Check octal only digits.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1185
                octal = octal && digit < 8;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1186
                // Skip digit.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1187
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1188
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1189
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1190
            if (octal && position - start > 1) {
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1191
                type = OCTAL_LEGACY;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1192
            } else if (ch0 == '.' || ch0 == 'E' || ch0 == 'e') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1193
                // Must be a double.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1194
                if (ch0 == '.') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1195
                    // Skip period.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1196
                    skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1197
                    // Skip mantissa.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1198
                    while (convertDigit(ch0, 10) != -1) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1199
                        skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1200
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1201
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1202
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1203
                // Detect exponent.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1204
                if (ch0 == 'E' || ch0 == 'e') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1205
                    // Skip E.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1206
                    skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1207
                    // Detect and skip exponent sign.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1208
                    if (ch0 == '+' || ch0 == '-') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1209
                        skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1210
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1211
                    // Skip exponent.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1212
                    while (convertDigit(ch0, 10) != -1) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1213
                        skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1214
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1215
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1216
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1217
                type = FLOATING;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1218
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1219
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1220
18330
0d7d60a0eec6 8016522: Numeric literal must not be followed by IdentifierStart
hannesw
parents: 18329
diff changeset
  1221
        if (Character.isJavaIdentifierStart(ch0)) {
0d7d60a0eec6 8016522: Numeric literal must not be followed by IdentifierStart
hannesw
parents: 18329
diff changeset
  1222
            error(Lexer.message("missing.space.after.number"), type, position, 1);
0d7d60a0eec6 8016522: Numeric literal must not be followed by IdentifierStart
hannesw
parents: 18329
diff changeset
  1223
        }
0d7d60a0eec6 8016522: Numeric literal must not be followed by IdentifierStart
hannesw
parents: 18329
diff changeset
  1224
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1225
        // Add number token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1226
        add(type, start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1227
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1228
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1229
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1230
     * Convert a regex token to a token object.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1231
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1232
     * @param start  Position in source content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1233
     * @param length Length of regex token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1234
     * @return Regex token object.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1235
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1236
    XMLToken valueOfXML(final int start, final int length) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1237
        return new XMLToken(source.getString(start, length));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1238
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1239
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1240
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1241
     * Scan over a XML token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1242
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1243
     * @return TRUE if is an XML literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1244
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1245
    private boolean scanXMLLiteral() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1246
        assert ch0 == '<' && Character.isJavaIdentifierStart(ch1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1247
        if (XML_LITERALS) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1248
            // Record beginning of xml expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1249
            final int start = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1250
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1251
            int openCount = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1252
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1253
            do {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1254
                if (ch0 == '<') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1255
                    if (ch1 == '/' && Character.isJavaIdentifierStart(ch2)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1256
                        skip(3);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1257
                        openCount--;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1258
                    } else if (Character.isJavaIdentifierStart(ch1)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1259
                        skip(2);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1260
                        openCount++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1261
                    } else if (ch1 == '?') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1262
                        skip(2);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1263
                    } else if (ch1 == '!' && ch2 == '-' && ch3 == '-') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1264
                        skip(4);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1265
                    } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1266
                        reset(start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1267
                        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1268
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1269
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1270
                    while (!atEOF() && ch0 != '>') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1271
                        if (ch0 == '/' && ch1 == '>') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1272
                            openCount--;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1273
                            skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1274
                            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1275
                        } else if (ch0 == '\"' || ch0 == '\'') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1276
                            scanString(false);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1277
                        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1278
                            skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1279
                        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1280
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1281
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1282
                    if (ch0 != '>') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1283
                        reset(start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1284
                        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1285
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1286
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1287
                    skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1288
                } else if (atEOF()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1289
                    reset(start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1290
                    return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1291
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1292
                    skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1293
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1294
            } while (openCount > 0);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1295
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1296
            add(XML, start);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1297
            return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1298
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1299
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1300
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1301
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1302
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1303
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1304
     * Scan over identifier characters.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1305
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1306
     * @return Length of identifier or zero if none found.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1307
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1308
    private int scanIdentifier() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1309
        final int start = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1310
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1311
        // Make sure first character is valid start character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1312
        if (ch0 == '\\' && ch1 == 'u') {
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
  1313
            skip(2);
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
  1314
            final int ch = hexSequence(4, TokenType.IDENT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1315
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1316
            if (!Character.isJavaIdentifierStart(ch)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1317
                error(Lexer.message("illegal.identifier.character"), TokenType.IDENT, start, position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1318
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1319
        } else if (!Character.isJavaIdentifierStart(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1320
            // Not an identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1321
            return 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1322
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1323
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1324
        // Make sure remaining characters are valid part characters.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1325
        while (!atEOF()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1326
            if (ch0 == '\\' && ch1 == 'u') {
18329
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
  1327
                skip(2);
392aaae366d6 8016518: Parsing of octal string escapes is broken
hannesw
parents: 18317
diff changeset
  1328
                final int ch = hexSequence(4, TokenType.IDENT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1329
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1330
                if (!Character.isJavaIdentifierPart(ch)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1331
                    error(Lexer.message("illegal.identifier.character"), TokenType.IDENT, start, position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1332
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1333
            } else if (Character.isJavaIdentifierPart(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1334
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1335
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1336
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1337
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1338
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1339
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1340
        // Length of identifier sequence.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1341
        return position - start;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1342
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1343
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1344
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1345
     * Compare two identifiers (in content) for equality.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1346
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1347
     * @param aStart  Start of first identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1348
     * @param aLength Length of first identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1349
     * @param bStart  Start of second identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1350
     * @param bLength Length of second identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1351
     * @return True if equal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1352
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1353
    private boolean identifierEqual(final int aStart, final int aLength, final int bStart, final int bLength) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1354
        if (aLength == bLength) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1355
            for (int i = 0; i < aLength; i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1356
                if (content[aStart + i] != content[bStart + i]) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1357
                    return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1358
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1359
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1360
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1361
            return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1362
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1363
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1364
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1365
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1366
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1367
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1368
     * Detect if a line starts with a marker identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1369
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1370
     * @param identStart  Start of identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1371
     * @param identLength Length of identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1372
     * @return True if detected.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1373
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1374
    private boolean hasHereMarker(final int identStart, final int identLength) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1375
        // Skip any whitespace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1376
        skipWhitespace(false);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1377
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1378
        return identifierEqual(identStart, identLength, position, scanIdentifier());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1379
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1380
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1381
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1382
     * Lexer to service edit strings.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1383
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1384
    private static class EditStringLexer extends Lexer {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1385
        /** Type of string literals to emit. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1386
        final TokenType stringType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1387
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1388
        /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1389
         * Constructor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1390
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1391
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1392
        EditStringLexer(final Lexer lexer, final TokenType stringType, final State stringState) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1393
            super(lexer, stringState);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1394
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1395
            this.stringType = stringType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1396
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1397
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1398
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1399
         * Lexify the contents of the string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1400
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1401
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1402
        public void lexify() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1403
            // Record start of string position.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1404
            int stringStart = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1405
            // Indicate that the priming first string has not been emitted.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1406
            boolean primed = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1407
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1408
            while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1409
                // Detect end of content.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1410
                if (atEOF()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1411
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1412
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1413
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1414
                // Honour escapes (should be well formed.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1415
                if (ch0 == '\\' && stringType == ESCSTRING) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1416
                    skip(2);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1417
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1418
                    continue;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1419
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1420
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1421
                // If start of expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1422
                if (ch0 == '$' && ch1 == '{') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1423
                    if (!primed || stringStart != position) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1424
                        if (primed) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1425
                            add(ADD, stringStart, stringStart + 1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1426
                        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1427
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1428
                        add(stringType, stringStart, position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1429
                        primed = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1430
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1431
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1432
                    // Skip ${
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1433
                    skip(2);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1434
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1435
                    // Save expression state.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1436
                    final State expressionState = saveState();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1437
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1438
                    // Start with one open brace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1439
                    int braceCount = 1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1440
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1441
                    // Scan for the rest of the string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1442
                    while (!atEOF()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1443
                        // If closing brace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1444
                        if (ch0 == '}') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1445
                            // Break only only if matching brace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1446
                            if (--braceCount == 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1447
                                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1448
                            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1449
                        } else if (ch0 == '{') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1450
                            // Bump up the brace count.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1451
                            braceCount++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1452
                        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1453
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1454
                        // Skip to next character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1455
                        skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1456
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1457
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1458
                    // If braces don't match then report an error.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1459
                    if (braceCount != 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1460
                        error(Lexer.message("edit.string.missing.brace"), LBRACE, expressionState.position - 1, 1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1461
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1462
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1463
                    // Mark end of expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1464
                    expressionState.setLimit(position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1465
                    // Skip closing brace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1466
                    skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1467
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1468
                    // Start next string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1469
                    stringStart = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1470
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1471
                    // Concatenate expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1472
                    add(ADD, expressionState.position, expressionState.position + 1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1473
                    add(LPAREN, expressionState.position, expressionState.position + 1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1474
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1475
                    // Scan expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1476
                    final Lexer lexer = new Lexer(this, expressionState);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1477
                    lexer.lexify();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1478
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1479
                    // Close out expression parenthesis.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1480
                    add(RPAREN, position - 1, position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1481
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1482
                    continue;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1483
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1484
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1485
                // Next character in string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1486
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1487
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1488
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1489
            // If there is any unemitted string portion.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1490
            if (stringStart != limit) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1491
                // Concatenate remaining string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1492
                if (primed) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1493
                    add(ADD, stringStart, 1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1494
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1495
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1496
                add(stringType, stringStart, limit);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1497
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1498
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1499
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1500
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1501
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1502
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1503
     * Edit string for nested expressions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1504
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1505
     * @param stringType  Type of string literals to emit.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1506
     * @param stringState State of lexer at start of string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1507
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1508
    private void editString(final TokenType stringType, final State stringState) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1509
        // Use special lexer to scan string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1510
        final EditStringLexer lexer = new EditStringLexer(this, stringType, stringState);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1511
        lexer.lexify();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1512
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1513
        // Need to keep lexer informed.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1514
        last = stringType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1515
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1516
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1517
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1518
     * Scan over a here string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1519
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1520
     * @return TRUE if is a here string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1521
     */
39168
e02c166da4dd 8073653: Secondary heredoc eating wrong lines.
hannesw
parents: 34732
diff changeset
  1522
    private boolean scanHereString(final LineInfoReceiver lir, final State oldState) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1523
        assert ch0 == '<' && ch1 == '<';
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1524
        if (scripting) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1525
            // Record beginning of here string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1526
            final State saved = saveState();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1527
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1528
            // << or <<<
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1529
            final boolean excludeLastEOL = ch2 != '<';
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1530
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1531
            if (excludeLastEOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1532
                skip(2);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1533
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1534
                skip(3);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1535
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1536
32321
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1537
            // Scan identifier. It might be quoted, indicating that no string editing should take place.
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1538
            final char quoteChar = ch0;
32322
5e140163c89f 8134484: disallow backquotes as heredoc end marker delimiters
mhaupt
parents: 32321
diff changeset
  1539
            final boolean noStringEditing = quoteChar == '"' || quoteChar == '\'';
32321
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1540
            if (noStringEditing) {
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1541
                skip(1);
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1542
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1543
            final int identStart = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1544
            final int identLength = scanIdentifier();
32321
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1545
            if (noStringEditing) {
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1546
                if (ch0 != quoteChar) {
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1547
                    error(Lexer.message("here.non.matching.delimiter"), last, position, position);
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1548
                    restoreState(saved);
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1549
                    return false;
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1550
                }
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1551
                skip(1);
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1552
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1553
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1554
            // Check for identifier.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1555
            if (identLength == 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1556
                // Treat as shift.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1557
                restoreState(saved);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1558
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1559
                return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1560
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1561
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1562
            // Record rest of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1563
            final State restState = saveState();
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
  1564
            // keep line number updated
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
  1565
            int lastLine = line;
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
  1566
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1567
            skipLine(false);
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
  1568
            lastLine++;
19089
51cfdcf21d35 8021130: Comments need to be tokens
jlaskey
parents: 19083
diff changeset
  1569
            int lastLinePosition = position;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1570
            restState.setLimit(position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1571
39168
e02c166da4dd 8073653: Secondary heredoc eating wrong lines.
hannesw
parents: 34732
diff changeset
  1572
            if (oldState.position > position) {
e02c166da4dd 8073653: Secondary heredoc eating wrong lines.
hannesw
parents: 34732
diff changeset
  1573
                restoreState(oldState);
e02c166da4dd 8073653: Secondary heredoc eating wrong lines.
hannesw
parents: 34732
diff changeset
  1574
                skipLine(false);
e02c166da4dd 8073653: Secondary heredoc eating wrong lines.
hannesw
parents: 34732
diff changeset
  1575
            }
e02c166da4dd 8073653: Secondary heredoc eating wrong lines.
hannesw
parents: 34732
diff changeset
  1576
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1577
            // Record beginning of string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1578
            final State stringState = saveState();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1579
            int stringEnd = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1580
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1581
            // Hunt down marker.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1582
            while (!atEOF()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1583
                // Skip any whitespace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1584
                skipWhitespace(false);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1585
47039
c7bdfebc55a9 8073640: Nashorn scripting: here document with only whitespace gives error
sdama
parents: 41982
diff changeset
  1586
                //handle trailing blank lines
c7bdfebc55a9 8073640: Nashorn scripting: here document with only whitespace gives error
sdama
parents: 41982
diff changeset
  1587
                lastLinePosition = position;
c7bdfebc55a9 8073640: Nashorn scripting: here document with only whitespace gives error
sdama
parents: 41982
diff changeset
  1588
                stringEnd = position;
c7bdfebc55a9 8073640: Nashorn scripting: here document with only whitespace gives error
sdama
parents: 41982
diff changeset
  1589
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1590
                if (hasHereMarker(identStart, identLength)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1591
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1592
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1593
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1594
                skipLine(false);
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
  1595
                lastLine++;
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
  1596
                lastLinePosition = position;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1597
                stringEnd = position;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1598
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1599
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
  1600
            // notify last line information
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
  1601
            lir.lineInfo(lastLine, lastLinePosition);
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18333
diff changeset
  1602
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1603
            // Record end of string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1604
            stringState.setLimit(stringEnd);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1605
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1606
            // If marker is missing.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1607
            if (stringState.isEmpty() || atEOF()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1608
                error(Lexer.message("here.missing.end.marker", source.getString(identStart, identLength)), last, position, position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1609
                restoreState(saved);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1610
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1611
                return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1612
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1613
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1614
            // Remove last end of line if specified.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1615
            if (excludeLastEOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1616
                // Handles \n.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1617
                if (content[stringEnd - 1] == '\n') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1618
                    stringEnd--;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1619
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1620
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1621
                // Handles \r and \r\n.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1622
                if (content[stringEnd - 1] == '\r') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1623
                    stringEnd--;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1624
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1625
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1626
                // Update end of string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1627
                stringState.setLimit(stringEnd);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1628
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1629
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1630
            // Edit string if appropriate.
32321
b883916a29ff 8073613: Here documents: how to avoid string interpolation?
mhaupt
parents: 31549
diff changeset
  1631
            if (!noStringEditing && !stringState.isEmpty()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1632
                editString(STRING, stringState);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1633
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1634
                // Add here string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1635
                add(STRING, stringState.position, stringState.limit);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1636
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1637
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1638
            // Scan rest of original line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1639
            final Lexer restLexer = new Lexer(this, restState);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1640
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1641
            restLexer.lexify();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1642
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1643
            return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1644
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1645
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1646
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1647
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1648
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1649
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1650
     * Breaks source content down into lex units, adding tokens to the token
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1651
     * stream. The routine scans until the stream buffer is full. Can be called
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1652
     * repeatedly until EOF is detected.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1653
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1654
    public void lexify() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1655
        while (!stream.isFull() || nested) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1656
            // Skip over whitespace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1657
            skipWhitespace(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1658
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1659
            // Detect end of file.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1660
            if (atEOF()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1661
                if (!nested) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1662
                    // Add an EOF token at the end.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1663
                    add(EOF, position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1664
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1665
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1666
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1667
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1668
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1669
            // Check for comments. Note that we don't scan for regexp and other literals here as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1670
            // we may not have enough context to distinguish them from similar looking operators.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1671
            // Instead we break on ambiguous operators below and let the parser decide.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1672
            if (ch0 == '/' && skipComments()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1673
                continue;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1674
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1675
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1676
            if (scripting && ch0 == '#' && skipComments()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1677
                continue;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1678
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1679
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1680
            // TokenType for lookup of delimiter or operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1681
            TokenType type;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1682
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1683
            if (ch0 == '.' && convertDigit(ch1, 10) != -1) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1684
                // '.' followed by digit.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1685
                // Scan and add a number.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1686
                scanNumber();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1687
            } else if ((type = TokenLookup.lookupOperator(ch0, ch1, ch2, ch3)) != null) {
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1688
                if (templateExpressionOpenBraces > 0) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1689
                    if (type == LBRACE) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1690
                        templateExpressionOpenBraces++;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1691
                    } else if (type == RBRACE) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1692
                        if (--templateExpressionOpenBraces == 0) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1693
                            break;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1694
                        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1695
                    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1696
                }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1697
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1698
                // Get the number of characters in the token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1699
                final int typeLength = type.getLength();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1700
                // Skip that many characters.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1701
                skip(typeLength);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1702
                // Add operator token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1703
                add(type, position - typeLength);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1704
                // Some operator tokens also mark the beginning of regexp, XML, or here string literals.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1705
                // We break to let the parser decide what it is.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1706
                if (canStartLiteral(type)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1707
                    break;
26505
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
  1708
                } else if (type == LBRACE && pauseOnNextLeftBrace) {
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
  1709
                    pauseOnNextLeftBrace = false;
d29bf8787b43 8057931: Instead of not skipping small functions in parser, make lexer avoid them instead
attila
parents: 25865
diff changeset
  1710
                    break;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1711
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1712
            } else if (Character.isJavaIdentifierStart(ch0) || ch0 == '\\' && ch1 == 'u') {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1713
                // Scan and add identifier or keyword.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1714
                scanIdentifierOrKeyword();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1715
            } else if (isStringDelimiter(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1716
                // Scan and add a string.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1717
                scanString(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1718
            } else if (Character.isDigit(ch0)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1719
                // Scan and add a number.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1720
                scanNumber();
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1721
            } else if (isTemplateDelimiter(ch0) && es6) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1722
                // Scan and add template in ES6 mode.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1723
                scanTemplate();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1724
            } else if (isTemplateDelimiter(ch0) && scripting) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1725
                // Scan and add an exec string ('`') in scripting mode.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1726
                scanString(true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1727
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1728
                // Don't recognize this character.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1729
                skip(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1730
                add(ERROR, position - 1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1731
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1732
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1733
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1734
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1735
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1736
     * Return value of token given its token descriptor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1737
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1738
     * @param token  Token descriptor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1739
     * @return JavaScript value.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1740
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1741
    Object getValueOf(final long token, final boolean strict) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1742
        final int start = Token.descPosition(token);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1743
        final int len   = Token.descLength(token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1744
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1745
        switch (Token.descType(token)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1746
        case DECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1747
            return Lexer.valueOf(source.getString(start, len), 10); // number
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1748
        case HEXADECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1749
            return Lexer.valueOf(source.getString(start + 2, len - 2), 16); // number
32444
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1750
        case OCTAL_LEGACY:
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1751
            return Lexer.valueOf(source.getString(start, len), 8); // number
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1752
        case OCTAL:
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1753
            return Lexer.valueOf(source.getString(start + 2, len - 2), 8); // number
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1754
        case BINARY_NUMBER:
4c7a40aab132 8134873: Implement support for ES6 numeric literals
aw
parents: 32322
diff changeset
  1755
            return Lexer.valueOf(source.getString(start + 2, len - 2), 2); // number
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1756
        case FLOATING:
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1757
            final String str   = source.getString(start, len);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1758
            final double value = Double.valueOf(str);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1759
            if (str.indexOf('.') != -1) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1760
                return value; //number
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1761
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1762
            //anything without an explicit decimal point is still subject to a
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1763
            //"representable as int or long" check. Then the programmer does not
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1764
            //explicitly code something as a double. For example new Color(int, int, int)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1765
            //and new Color(float, float, float) will get ambiguous for cases like
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1766
            //new Color(1.0, 1.5, 1.5) if we don't respect the decimal point.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1767
            //yet we don't want e.g. 1e6 to be a double unnecessarily
31490
77f783445d40 8130234: Get rid of JSType.isNegativeZero
attila
parents: 28786
diff changeset
  1768
            if (JSType.isStrictlyRepresentableAsInt(value)) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1769
                return (int)value;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1770
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1771
            return value;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1772
        case STRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1773
            return source.getString(start, len); // String
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1774
        case ESCSTRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1775
            return valueOfString(start, len, strict); // String
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1776
        case IDENT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1777
            return valueOfIdent(start, len); // String
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1778
        case REGEX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1779
            return valueOfPattern(start, len); // RegexToken::LexerToken
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1780
        case TEMPLATE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1781
        case TEMPLATE_HEAD:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1782
        case TEMPLATE_MIDDLE:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1783
        case TEMPLATE_TAIL:
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1784
            return valueOfString(start, len, true); // String
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1785
        case XML:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1786
            return valueOfXML(start, len); // XMLToken::LexerToken
22390
1d2d88e478ea 8032068: implement @sourceURL and #sourceURL directives
sundar
parents: 21437
diff changeset
  1787
        case DIRECTIVE_COMMENT:
1d2d88e478ea 8032068: implement @sourceURL and #sourceURL directives
sundar
parents: 21437
diff changeset
  1788
            return source.getString(start, len);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1789
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1790
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1791
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1792
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1793
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1794
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1795
18333
2a89c3938a00 8016235: Use in catch block that may not have been executed in try block caused illegal byte code to be generated
lagergren
parents: 18330
diff changeset
  1796
    /**
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1797
     * Get the raw string value of a template literal string part.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1798
     *
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1799
     * @param token template string token
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1800
     * @return raw string
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1801
     */
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1802
    public String valueOfRawString(final long token) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1803
        final int start  = Token.descPosition(token);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1804
        final int length = Token.descLength(token);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1805
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1806
        // Save the current position.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1807
        final int savePosition = position;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1808
        // Calculate the end position.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1809
        final int end = start + length;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1810
        // Reset to beginning of string.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1811
        reset(start);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1812
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1813
        // Buffer for recording characters.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1814
        final StringBuilder sb = new StringBuilder(length);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1815
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1816
        // Scan until end of string.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1817
        while (position < end) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1818
            if (ch0 == '\r') {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1819
                // Convert CR-LF or CR to LF line terminator.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1820
                sb.append('\n');
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1821
                skip(ch1 == '\n' ? 2 : 1);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1822
            } else {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1823
                // Add regular character.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1824
                sb.append(ch0);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1825
                skip(1);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1826
            }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1827
        }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1828
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1829
        // Restore position.
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1830
        reset(savePosition);
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1831
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1832
        return sb.toString();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1833
    }
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1834
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 32444
diff changeset
  1835
    /**
18333
2a89c3938a00 8016235: Use in catch block that may not have been executed in try block caused illegal byte code to be generated
lagergren
parents: 18330
diff changeset
  1836
     * Get the correctly localized error message for a given message id format arguments
2a89c3938a00 8016235: Use in catch block that may not have been executed in try block caused illegal byte code to be generated
lagergren
parents: 18330
diff changeset
  1837
     * @param msgId message id
2a89c3938a00 8016235: Use in catch block that may not have been executed in try block caused illegal byte code to be generated
lagergren
parents: 18330
diff changeset
  1838
     * @param args  format arguments
2a89c3938a00 8016235: Use in catch block that may not have been executed in try block caused illegal byte code to be generated
lagergren
parents: 18330
diff changeset
  1839
     * @return message
2a89c3938a00 8016235: Use in catch block that may not have been executed in try block caused illegal byte code to be generated
lagergren
parents: 18330
diff changeset
  1840
     */
18317
2f5434c9c9fd 8015346: JSON parsing issues with escaped strings, octal, decimal numbers
sundar
parents: 17246
diff changeset
  1841
    protected static String message(final String msgId, final String... args) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1842
        return ECMAErrors.getMessage("lexer.error." + msgId, args);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1843
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1844
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1845
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1846
     * Generate a runtime exception
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1847
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1848
     * @param message       error message
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1849
     * @param type          token type
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1850
     * @param start         start position of lexed error
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1851
     * @param length        length of lexed error
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1852
     * @throws ParserException  unconditionally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1853
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1854
    protected void error(final String message, final TokenType type, final int start, final int length) throws ParserException {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1855
        final long token     = Token.toDesc(type, start, length);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1856
        final int  pos       = Token.descPosition(token);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1857
        final int  lineNum   = source.getLine(pos);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1858
        final int  columnNum = source.getColumn(pos);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1859
        final String formatted = ErrorManager.format(message, source, lineNum, columnNum, token);
16256
f2d9a0c49914 8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents: 16234
diff changeset
  1860
        throw new ParserException(JSErrorType.SYNTAX_ERROR, formatted, source, lineNum, columnNum, token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1861
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1862
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1863
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1864
     * Helper class for Lexer tokens, e.g XML or RegExp tokens.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1865
     * This is the abstract superclass
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1866
     */
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26505
diff changeset
  1867
    public static abstract class LexerToken implements Serializable {
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26505
diff changeset
  1868
        private static final long serialVersionUID = 1L;
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26505
diff changeset
  1869
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1870
        private final String expression;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1871
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1872
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1873
         * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1874
         * @param expression token expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1875
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1876
        protected LexerToken(final String expression) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1877
            this.expression = expression;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1878
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1879
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1880
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1881
         * Get the expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1882
         * @return expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1883
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1884
        public String getExpression() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1885
            return expression;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1886
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1887
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1888
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1889
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1890
     * Temporary container for regular expressions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1891
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1892
    public static class RegexToken extends LexerToken {
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26505
diff changeset
  1893
        private static final long serialVersionUID = 1L;
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26505
diff changeset
  1894
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1895
        /** Options. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1896
        private final String options;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1897
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1898
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1899
         * Constructor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1900
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1901
         * @param expression  regexp expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1902
         * @param options     regexp options
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1903
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1904
        public RegexToken(final String expression, final String options) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1905
            super(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1906
            this.options = options;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1907
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1908
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1909
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1910
         * Get regexp options
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1911
         * @return options
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1912
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1913
        public String getOptions() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1914
            return options;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1915
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1916
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1917
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1918
        public String toString() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1919
            return '/' + getExpression() + '/' + options;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1920
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1921
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1922
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1923
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1924
     * Temporary container for XML expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1925
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1926
    public static class XMLToken extends LexerToken {
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26505
diff changeset
  1927
        private static final long serialVersionUID = 1L;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1928
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1929
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1930
         * Constructor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1931
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1932
         * @param expression  XML expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1933
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1934
        public XMLToken(final String expression) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1935
            super(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1936
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1937
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1938
}