9837563cd1
- Offsets on more stuff
- Status file for kernel
-> Testing with (before fasta)
```
python tools/test.py -mrelease -cdartk --no-tree-shake --no-dfe service
```
now shows everything as passing.
Reload stuff, and evaluation stuff (e.g.) has been disabled though.
- Lots of new service tests that tests what positions we stop at when
saying next.
As fasta has now landed debugging does not currently work, but this is still needed in order to both test better and allow for proper kernel debugging support.
R=hausner@google.com, kmillikin@google.com
Review-Url: https://codereview.chromium.org/2680303002 .
220 lines
6.6 KiB
C++
220 lines
6.6 KiB
C++
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
//
|
|
// Scanner class for the Dart language. The scanner reads source text
|
|
// and produces a stream of tokens which is used by the parser.
|
|
//
|
|
|
|
#ifndef RUNTIME_VM_SCANNER_H_
|
|
#define RUNTIME_VM_SCANNER_H_
|
|
|
|
#include "vm/growable_array.h"
|
|
#include "vm/token.h"
|
|
|
|
namespace dart {
|
|
|
|
// Forward declarations.
|
|
class Array;
|
|
class Library;
|
|
class RawString;
|
|
class ScanContext;
|
|
class String;
|
|
|
|
// A call to Scan() scans the source one token at at time.
|
|
// The scanned token is returned by current_token().
|
|
// GetStream() scans the entire source text and returns a stream of tokens.
|
|
class Scanner : ValueObject {
|
|
public:
|
|
typedef uint16_t (*CharAtFunc)(const String& str, intptr_t index);
|
|
|
|
// SourcePosition describes a text location in user friendly
|
|
// terms of line number and column.
|
|
struct SourcePosition {
|
|
int line;
|
|
int column;
|
|
};
|
|
|
|
// TokenDesc defines the kind of a token and its location in
|
|
// the source text.
|
|
struct TokenDescriptor {
|
|
Token::Kind kind;
|
|
int offset; // Offset in source string.
|
|
SourcePosition position; // Text position in source.
|
|
const String* literal; // Identifier, number or string literal.
|
|
};
|
|
|
|
class TokenCollector : public ValueObject {
|
|
public:
|
|
TokenCollector() {}
|
|
virtual ~TokenCollector() {}
|
|
virtual void AddToken(const TokenDescriptor& token) {}
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(TokenCollector);
|
|
};
|
|
|
|
// Initializes scanner to scan string source.
|
|
Scanner(const String& source, const String& private_key);
|
|
~Scanner();
|
|
|
|
// Scans one token at a time.
|
|
void Scan();
|
|
|
|
// Scans the entire source and collects tokens in the provided collector.
|
|
void ScanAll(TokenCollector* collector);
|
|
|
|
// Scans to specified token position.
|
|
// Use CurrentPosition() to extract line and column number.
|
|
void ScanTo(intptr_t token_index);
|
|
|
|
// Info about most recently recognized token.
|
|
const TokenDescriptor& current_token() const { return current_token_; }
|
|
|
|
// Was there a line break before the current token?
|
|
bool NewlineBeforeToken() const { return newline_seen_; }
|
|
|
|
// Source code line number and column of current token.
|
|
const SourcePosition& CurrentPosition() const {
|
|
return current_token_.position;
|
|
}
|
|
|
|
static void InitOnce();
|
|
|
|
// Return true if str is an identifier.
|
|
bool IsIdent(const String& str);
|
|
|
|
// Does the token stream contain a valid integer literal.
|
|
static bool IsValidInteger(const String& str,
|
|
bool* is_positive,
|
|
const String** value);
|
|
|
|
static bool IsIdentStartChar(int32_t c);
|
|
static bool IsIdentChar(int32_t c);
|
|
|
|
private:
|
|
friend class ScanContext;
|
|
|
|
static const int kNumLowercaseChars = 26;
|
|
|
|
struct KeywordTable {
|
|
Token::Kind kind;
|
|
const char* keyword_chars;
|
|
int keyword_len;
|
|
const String* keyword_symbol;
|
|
};
|
|
|
|
// Rewind scanner position to token 0.
|
|
void Reset();
|
|
|
|
// Reads next lookahead character.
|
|
void ReadChar();
|
|
|
|
// Read and discard characters up to end of line.
|
|
void SkipLine();
|
|
|
|
// Recognizes token 'kind' and reads next character in input.
|
|
void Recognize(Token::Kind kind) {
|
|
ReadChar();
|
|
current_token_.kind = kind;
|
|
}
|
|
|
|
int32_t LookaheadChar(int how_many);
|
|
|
|
void ErrorMsg(const char* msg);
|
|
|
|
// These functions return true if the given character is a letter,
|
|
// a decimal digit, a hexadecimal digit, etc.
|
|
static bool IsLetter(int32_t c);
|
|
static bool IsDecimalDigit(int32_t c);
|
|
static bool IsNumberStart(int32_t);
|
|
static bool IsHexDigit(int32_t c);
|
|
|
|
// Skips up to next non-whitespace character.
|
|
void ConsumeWhiteSpace();
|
|
|
|
// Skips characters up to end of line.
|
|
void ConsumeLineComment();
|
|
|
|
// Skips characters up to matching '*/'.
|
|
void ConsumeBlockComment();
|
|
|
|
// Is this scanner currently scanning a string literal.
|
|
bool IsScanningString() const { return string_delimiter_ != '\0'; }
|
|
void BeginStringLiteral(const char delimiter);
|
|
void EndStringLiteral();
|
|
|
|
// Is this scanner currently scanning a string interpolation expression.
|
|
bool IsNestedContext() const { return saved_context_ != NULL; }
|
|
void PushContext();
|
|
void PopContext();
|
|
|
|
// Starts reading a string literal.
|
|
void ScanLiteralString(bool is_raw);
|
|
|
|
// Read the characters of a string literal. Remove whitespace up to
|
|
// and including the first newline character if remove_whitespace
|
|
// is true.
|
|
void ScanLiteralStringChars(bool is_raw, bool remove_whitespace);
|
|
|
|
// Reads a fixed number of hexadecimal digits.
|
|
bool ScanHexDigits(int digits, int32_t* value);
|
|
|
|
// Reads a variable number of hexadecimal digits.
|
|
bool ScanHexDigits(int min_digits, int max_digits, int32_t* value);
|
|
|
|
// Reads an escaped code point from within a string literal.
|
|
void ScanEscapedCodePoint(int32_t* escaped_char);
|
|
|
|
// Reads identifier.
|
|
void ScanIdentChars(bool allow_dollar);
|
|
void ScanIdent() { ScanIdentChars(true); }
|
|
void ScanIdentNoDollar() { ScanIdentChars(false); }
|
|
|
|
// Reads a number literal.
|
|
void ScanNumber(bool dec_point_seen);
|
|
|
|
void ScanScriptTag();
|
|
|
|
CharAtFunc CallCharAt() const { return char_at_func_; }
|
|
|
|
Thread* thread() const { return thread_; }
|
|
Zone* zone() const { return zone_; }
|
|
|
|
TokenDescriptor current_token_; // Current token.
|
|
TokenDescriptor newline_token_; // Newline token.
|
|
TokenDescriptor empty_string_token_; // Token for "".
|
|
const String& source_; // The source text being tokenized.
|
|
intptr_t source_length_; // The length of the source text.
|
|
intptr_t lookahead_pos_; // Position of lookahead character
|
|
// within source_.
|
|
intptr_t token_start_; // Begin of current token in src_.
|
|
int32_t c0_; // Lookahead character.
|
|
bool newline_seen_; // Newline before current token.
|
|
intptr_t prev_token_line_; // Line number of the previous token.
|
|
|
|
// The following fields keep track whether we are scanning a string literal
|
|
// and its interpolated expressions.
|
|
ScanContext* saved_context_;
|
|
int32_t string_delimiter_;
|
|
bool string_is_multiline_;
|
|
int brace_level_;
|
|
|
|
const String& private_key_;
|
|
|
|
SourcePosition c0_pos_; // Source position of lookahead character c0_.
|
|
|
|
const CharAtFunc char_at_func_;
|
|
|
|
Thread* thread_;
|
|
Zone* zone_;
|
|
|
|
static KeywordTable keywords_[Token::kNumKeywords];
|
|
static int keywords_char_offset_[kNumLowercaseChars];
|
|
};
|
|
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_SCANNER_H_
|