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