Commit 6c2c17cd authored by nikolaos's avatar nikolaos Committed by Commit bot

[parser] Apply an adaptation of the CRTP

This patch applies an adaptation of the Curiously Recurring Template
Pattern to the parser objects.  The result is roughly:

    // Common denominator, needed to avoid cyclic dependency.
    // Instances of this template will end up with very minimal
    // definitions, ideally containing just typedefs.
    template <typename Impl>
    class ParserBaseTraits;

    // The parser base object, which should just implement pure
    // parser behavior.  The Impl parameter is the actual derived
    // class (according to CRTP), which implements impure parser
    // behavior.
    template <typename Impl>
    class ParserBase : public ParserBaseTraits<Impl> { ... };

    // And then, for each parser variant:
    class Parser;

    template <>
    class ParserBaseTraits<Parser> { ... };

    class Parser : public ParserBase<Parser> { ... };

Using the CRTP, we will ultimately achieve two goals:
(1) clean up the traits objects, but most importantly
(2) clearly separate pure/impure parser implementation and facilitate
experimentation with different parser variants.

R=adamk@chromium.org, marja@chromium.org
BUG=
LOG=N

Review-Url: https://codereview.chromium.org/2267663002
Cr-Commit-Position: refs/heads/master@{#38819}
parent 1776fd09
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -41,24 +41,21 @@ namespace internal { ...@@ -41,24 +41,21 @@ namespace internal {
#define DUMMY ) // to make indentation work #define DUMMY ) // to make indentation work
#undef DUMMY #undef DUMMY
void PreParserTraits::ReportMessageAt(Scanner::Location source_location, void ParserBaseTraits<PreParser>::ReportMessageAt(
MessageTemplate::Template message, Scanner::Location source_location, MessageTemplate::Template message,
const char* arg, const char* arg, ParseErrorType error_type) {
ParseErrorType error_type) { delegate()->log_->LogMessage(source_location.beg_pos, source_location.end_pos,
pre_parser_->log_->LogMessage(source_location.beg_pos, message, arg, error_type);
source_location.end_pos, message, arg,
error_type);
} }
void PreParserTraits::ReportMessageAt(Scanner::Location source_location, void ParserBaseTraits<PreParser>::ReportMessageAt(
MessageTemplate::Template message, Scanner::Location source_location, MessageTemplate::Template message,
const AstRawString* arg, const AstRawString* arg, ParseErrorType error_type) {
ParseErrorType error_type) {
UNREACHABLE(); UNREACHABLE();
} }
PreParserIdentifier ParserBaseTraits<PreParser>::GetSymbol(
PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) const { Scanner* scanner) const {
switch (scanner->current_token()) { switch (scanner->current_token()) {
case Token::ENUM: case Token::ENUM:
return PreParserIdentifier::Enum(); return PreParserIdentifier::Enum();
...@@ -89,8 +86,7 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) const { ...@@ -89,8 +86,7 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) const {
} }
} }
PreParserExpression ParserBaseTraits<PreParser>::ExpressionFromString(
PreParserExpression PreParserTraits::ExpressionFromString(
int pos, Scanner* scanner, PreParserFactory* factory) const { int pos, Scanner* scanner, PreParserFactory* factory) const {
if (scanner->UnescapedLiteralMatches("use strict", 10)) { if (scanner->UnescapedLiteralMatches("use strict", 10)) {
return PreParserExpression::UseStrictStringLiteral(); return PreParserExpression::UseStrictStringLiteral();
...@@ -98,18 +94,16 @@ PreParserExpression PreParserTraits::ExpressionFromString( ...@@ -98,18 +94,16 @@ PreParserExpression PreParserTraits::ExpressionFromString(
return PreParserExpression::StringLiteral(); return PreParserExpression::StringLiteral();
} }
PreParserExpression ParserBaseTraits<PreParser>::ParseV8Intrinsic(bool* ok) {
PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) { return delegate()->ParseV8Intrinsic(ok);
return pre_parser_->ParseV8Intrinsic(ok);
} }
PreParserExpression ParserBaseTraits<PreParser>::ParseFunctionLiteral(
PreParserExpression PreParserTraits::ParseFunctionLiteral(
PreParserIdentifier name, Scanner::Location function_name_location, PreParserIdentifier name, Scanner::Location function_name_location,
FunctionNameValidity function_name_validity, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type, int function_token_position, FunctionLiteral::FunctionType type,
LanguageMode language_mode, bool* ok) { LanguageMode language_mode, bool* ok) {
return pre_parser_->ParseFunctionLiteral( return delegate()->ParseFunctionLiteral(
name, function_name_location, function_name_validity, kind, name, function_name_location, function_name_validity, kind,
function_token_position, type, language_mode, ok); function_token_position, type, language_mode, ok);
} }
...@@ -154,12 +148,12 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction( ...@@ -154,12 +148,12 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
return kPreParseSuccess; return kPreParseSuccess;
} }
PreParserExpression PreParserTraits::ParseClassLiteral( PreParserExpression ParserBaseTraits<PreParser>::ParseClassLiteral(
Type::ExpressionClassifier* classifier, PreParserIdentifier name, Type::ExpressionClassifier* classifier, PreParserIdentifier name,
Scanner::Location class_name_location, bool name_is_strict_reserved, Scanner::Location class_name_location, bool name_is_strict_reserved,
int pos, bool* ok) { int pos, bool* ok) {
return pre_parser_->ParseClassLiteral(classifier, name, class_name_location, return delegate()->ParseClassLiteral(classifier, name, class_name_location,
name_is_strict_reserved, pos, ok); name_is_strict_reserved, pos, ok);
} }
...@@ -1280,13 +1274,13 @@ PreParserExpression PreParser::ParseDoExpression(bool* ok) { ...@@ -1280,13 +1274,13 @@ PreParserExpression PreParser::ParseDoExpression(bool* ok) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
void PreParserTraits::ParseAsyncArrowSingleExpressionBody( void ParserBaseTraits<PreParser>::ParseAsyncArrowSingleExpressionBody(
PreParserStatementList body, bool accept_IN, PreParserStatementList body, bool accept_IN,
Type::ExpressionClassifier* classifier, int pos, bool* ok) { Type::ExpressionClassifier* classifier, int pos, bool* ok) {
Scope* scope = pre_parser_->scope(); Scope* scope = delegate()->scope();
scope->ForceContextAllocation(); scope->ForceContextAllocation();
PreParserExpression return_value = pre_parser_->ParseAssignmentExpression( PreParserExpression return_value = delegate()->ParseAssignmentExpression(
accept_IN, classifier, CHECK_OK_CUSTOM(Void)); accept_IN, classifier, CHECK_OK_CUSTOM(Void));
body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); body->Add(PreParserStatement::ExpressionStatement(return_value), zone());
......
...@@ -585,13 +585,12 @@ struct PreParserFormalParameters : FormalParametersBase { ...@@ -585,13 +585,12 @@ struct PreParserFormalParameters : FormalParametersBase {
class PreParser; class PreParser;
class PreParserTraits { template <>
class ParserBaseTraits<PreParser> {
public: public:
struct Type { typedef ParserBaseTraits<PreParser> PreParserTraits;
// TODO(marja): To be removed. The Traits object should contain all the data
// it needs.
typedef PreParser* Parser;
struct Type {
// PreParser doesn't need to store generator variables. // PreParser doesn't need to store generator variables.
typedef void GeneratorVariable; typedef void GeneratorVariable;
...@@ -618,7 +617,12 @@ class PreParserTraits { ...@@ -618,7 +617,12 @@ class PreParserTraits {
typedef PreParserFactory Factory; typedef PreParserFactory Factory;
}; };
explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} // TODO(nikolaos): The traits methods should not need to call methods
// of the implementation object.
PreParser* delegate() { return reinterpret_cast<PreParser*>(this); }
const PreParser* delegate() const {
return reinterpret_cast<const PreParser*>(this);
}
// Helper functions for recursive descent. // Helper functions for recursive descent.
bool IsEval(PreParserIdentifier identifier) const { bool IsEval(PreParserIdentifier identifier) const {
...@@ -989,9 +993,6 @@ class PreParserTraits { ...@@ -989,9 +993,6 @@ class PreParserTraits {
inline PreParserExpression RewriteYieldStar(PreParserExpression generator, inline PreParserExpression RewriteYieldStar(PreParserExpression generator,
PreParserExpression expression, PreParserExpression expression,
int pos); int pos);
private:
PreParser* pre_parser_;
}; };
...@@ -1007,7 +1008,11 @@ class PreParserTraits { ...@@ -1007,7 +1008,11 @@ class PreParserTraits {
// rather it is to speed up properly written and correct programs. // rather it is to speed up properly written and correct programs.
// That means that contextual checks (like a label being declared where // That means that contextual checks (like a label being declared where
// it is used) are generally omitted. // it is used) are generally omitted.
class PreParser : public ParserBase<PreParserTraits> { class PreParser : public ParserBase<PreParser> {
// TODO(nikolaos): This should not be necessary. It will be removed
// when the traits object stops delegating to the implementation object.
friend class ParserBaseTraits<PreParser>;
public: public:
typedef PreParserIdentifier Identifier; typedef PreParserIdentifier Identifier;
typedef PreParserExpression Expression; typedef PreParserExpression Expression;
...@@ -1020,8 +1025,8 @@ class PreParser : public ParserBase<PreParserTraits> { ...@@ -1020,8 +1025,8 @@ class PreParser : public ParserBase<PreParserTraits> {
PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory, PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
ParserRecorder* log, uintptr_t stack_limit) ParserRecorder* log, uintptr_t stack_limit)
: ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL, : ParserBase<PreParser>(zone, scanner, stack_limit, NULL,
ast_value_factory, log, this), ast_value_factory, log),
use_counts_(nullptr) {} use_counts_(nullptr) {}
// Pre-parse the program from the character stream; returns true on // Pre-parse the program from the character stream; returns true on
...@@ -1075,8 +1080,6 @@ class PreParser : public ParserBase<PreParserTraits> { ...@@ -1075,8 +1080,6 @@ class PreParser : public ParserBase<PreParserTraits> {
int* use_counts); int* use_counts);
private: private:
friend class PreParserTraits;
static const int kLazyParseTrialLimit = 200; static const int kLazyParseTrialLimit = 200;
// These types form an algebra over syntactic categories that is just // These types form an algebra over syntactic categories that is just
...@@ -1153,27 +1156,24 @@ class PreParser : public ParserBase<PreParserTraits> { ...@@ -1153,27 +1156,24 @@ class PreParser : public ParserBase<PreParserTraits> {
int* use_counts_; int* use_counts_;
}; };
void ParserBaseTraits<PreParser>::MaterializeUnspreadArgumentsLiterals(
void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) { int count) {
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
pre_parser_->function_state_->NextMaterializedLiteralIndex(); delegate()->function_state_->NextMaterializedLiteralIndex();
} }
} }
PreParserExpression ParserBaseTraits<PreParser>::SpreadCall(
PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function, PreParserExpression function, PreParserExpressionList args, int pos) {
PreParserExpressionList args, return delegate()->factory()->NewCall(function, args, pos);
int pos) {
return pre_parser_->factory()->NewCall(function, args, pos);
} }
PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, PreParserExpression ParserBaseTraits<PreParser>::SpreadCallNew(
PreParserExpressionList args, PreParserExpression function, PreParserExpressionList args, int pos) {
int pos) { return delegate()->factory()->NewCallNew(function, args, pos);
return pre_parser_->factory()->NewCallNew(function, args, pos);
} }
void PreParserTraits::ParseArrowFunctionFormalParameterList( void ParserBaseTraits<PreParser>::ParseArrowFunctionFormalParameterList(
PreParserFormalParameters* parameters, PreParserExpression params, PreParserFormalParameters* parameters, PreParserExpression params,
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
const Scope::Snapshot& scope_snapshot, bool* ok) { const Scope::Snapshot& scope_snapshot, bool* ok) {
...@@ -1181,42 +1181,41 @@ void PreParserTraits::ParseArrowFunctionFormalParameterList( ...@@ -1181,42 +1181,41 @@ void PreParserTraits::ParseArrowFunctionFormalParameterList(
// lists that are too long. // lists that are too long.
} }
PreParserExpression PreParserTraits::ParseAsyncFunctionExpression(bool* ok) { PreParserExpression ParserBaseTraits<PreParser>::ParseAsyncFunctionExpression(
return pre_parser_->ParseAsyncFunctionExpression(ok); bool* ok) {
return delegate()->ParseAsyncFunctionExpression(ok);
} }
PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) { PreParserExpression ParserBaseTraits<PreParser>::ParseDoExpression(bool* ok) {
return pre_parser_->ParseDoExpression(ok); return delegate()->ParseDoExpression(ok);
} }
void ParserBaseTraits<PreParser>::RewriteNonPattern(
void PreParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, Type::ExpressionClassifier* classifier, bool* ok) {
bool* ok) { delegate()->ValidateExpression(classifier, ok);
pre_parser_->ValidateExpression(classifier, ok);
} }
PreParserExpression PreParserTraits::RewriteAwaitExpression( PreParserExpression ParserBaseTraits<PreParser>::RewriteAwaitExpression(
PreParserExpression value, int pos) { PreParserExpression value, int pos) {
return value; return value;
} }
ZoneList<PreParserExpression>* PreParserTraits::GetNonPatternList() const { ZoneList<PreParserExpression>* ParserBaseTraits<PreParser>::GetNonPatternList()
return pre_parser_->function_state_->non_patterns_to_rewrite(); const {
return delegate()->function_state_->non_patterns_to_rewrite();
} }
ZoneList<
ZoneList<typename PreParserTraits::Type::ExpressionClassifier::Error>* typename ParserBaseTraits<PreParser>::Type::ExpressionClassifier::Error>*
PreParserTraits::GetReportedErrorList() const { ParserBaseTraits<PreParser>::GetReportedErrorList() const {
return pre_parser_->function_state_->GetReportedErrorList(); return delegate()->function_state_->GetReportedErrorList();
} }
Zone* ParserBaseTraits<PreParser>::zone() const {
Zone* PreParserTraits::zone() const { return delegate()->function_state_->scope()->zone();
return pre_parser_->function_state_->scope()->zone();
} }
PreParserExpression ParserBaseTraits<PreParser>::RewriteYieldStar(
PreParserExpression PreParserTraits::RewriteYieldStar(
PreParserExpression generator, PreParserExpression expression, int pos) { PreParserExpression generator, PreParserExpression expression, int pos) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
...@@ -1240,22 +1239,21 @@ PreParserStatementList PreParser::ParseEagerFunctionBody( ...@@ -1240,22 +1239,21 @@ PreParserStatementList PreParser::ParseEagerFunctionBody(
return PreParserStatementList(); return PreParserStatementList();
} }
PreParserStatementList ParserBaseTraits<PreParser>::ParseEagerFunctionBody(
PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
PreParserIdentifier function_name, int pos, PreParserIdentifier function_name, int pos,
const PreParserFormalParameters& parameters, FunctionKind kind, const PreParserFormalParameters& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, bool* ok) { FunctionLiteral::FunctionType function_type, bool* ok) {
return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters, return delegate()->ParseEagerFunctionBody(function_name, pos, parameters,
kind, function_type, ok); kind, function_type, ok);
} }
PreParserExpression PreParserTraits::CloseTemplateLiteral( PreParserExpression ParserBaseTraits<PreParser>::CloseTemplateLiteral(
TemplateLiteralState* state, int start, PreParserExpression tag) { TemplateLiteralState* state, int start, PreParserExpression tag) {
if (IsTaggedTemplate(tag)) { if (IsTaggedTemplate(tag)) {
// Emulate generation of array literals for tag callsite // Emulate generation of array literals for tag callsite
// 1st is array of cooked strings, second is array of raw strings // 1st is array of cooked strings, second is array of raw strings
pre_parser_->function_state_->NextMaterializedLiteralIndex(); delegate()->function_state_->NextMaterializedLiteralIndex();
pre_parser_->function_state_->NextMaterializedLiteralIndex(); delegate()->function_state_->NextMaterializedLiteralIndex();
} }
return EmptyExpression(); return EmptyExpression();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment