diff options
-rw-r--r-- | AST.cpp | 16 | ||||
-rw-r--r-- | AST.h | 38 | ||||
-rw-r--r-- | ASTForward.h | 2 | ||||
-rw-r--r-- | ASTPrinter.cpp | 22 | ||||
-rw-r--r-- | ASTPrinter.h | 4 | ||||
-rw-r--r-- | ASTVisitor.h | 4 | ||||
-rw-r--r-- | AST_accept.h | 12 | ||||
-rw-r--r-- | Parser.cpp | 41 | ||||
-rw-r--r-- | Parser.h | 3 |
9 files changed, 141 insertions, 1 deletions
@@ -255,6 +255,22 @@ void StructDefinition::checkRecursion() const } } +void EnumDefinition::checkValidityOfMembers() const +{ +#if 0 // LTODO: Make this work for the Declarations + vector<ASTPointer<ASTString>> members = getMembers(); + sort(begin(members), end(members)); + for (size_t i = 0; i < members.size(); ++i) + if (members[i] == members[i + 1]) + BOOST_THROW_EXCEPTION(createTypeError("Duplicate member detected in Enum")); +#endif +} + +TypePointer EnumDefinition::getType(ContractDefinition const*) const +{ + return make_shared<TypeType>(make_shared<EnumType>(*this)); +} + TypePointer FunctionDefinition::getType(ContractDefinition const*) const { return make_shared<FunctionType>(*this); @@ -166,6 +166,18 @@ private: }; /** + * Declaration of an Enum Value + */ +class EnumDeclaration : public Declaration +{ + EnumDeclaration(Location const& _location, + ASTPointer<ASTString> const& _name): + Declaration(_location, _name) {} + + TypePointer getType(ContractDefinition const*) const; +}; + +/** * Abstract class that is added to each AST node that can store local variables. */ class VariableScope @@ -209,6 +221,7 @@ public: ASTPointer<ASTString> const& _documentation, std::vector<ASTPointer<InheritanceSpecifier>> const& _baseContracts, std::vector<ASTPointer<StructDefinition>> const& _definedStructs, + std::vector<ASTPointer<EnumDefinition>> const& _definedEnums, std::vector<ASTPointer<VariableDeclaration>> const& _stateVariables, std::vector<ASTPointer<FunctionDefinition>> const& _definedFunctions, std::vector<ASTPointer<ModifierDefinition>> const& _functionModifiers, @@ -216,6 +229,7 @@ public: Declaration(_location, _name), Documented(_documentation), m_baseContracts(_baseContracts), m_definedStructs(_definedStructs), + m_definedEnums(_definedEnums), m_stateVariables(_stateVariables), m_definedFunctions(_definedFunctions), m_functionModifiers(_functionModifiers), @@ -227,6 +241,7 @@ public: std::vector<ASTPointer<InheritanceSpecifier>> const& getBaseContracts() const { return m_baseContracts; } std::vector<ASTPointer<StructDefinition>> const& getDefinedStructs() const { return m_definedStructs; } + std::vector<ASTPointer<EnumDefinition>> const& getDefinedEnums() const { return m_definedEnums; } std::vector<ASTPointer<VariableDeclaration>> const& getStateVariables() const { return m_stateVariables; } std::vector<ASTPointer<ModifierDefinition>> const& getFunctionModifiers() const { return m_functionModifiers; } std::vector<ASTPointer<FunctionDefinition>> const& getDefinedFunctions() const { return m_definedFunctions; } @@ -260,6 +275,7 @@ private: std::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts; std::vector<ASTPointer<StructDefinition>> m_definedStructs; + std::vector<ASTPointer<EnumDefinition>> m_definedEnums; std::vector<ASTPointer<VariableDeclaration>> m_stateVariables; std::vector<ASTPointer<FunctionDefinition>> m_definedFunctions; std::vector<ASTPointer<ModifierDefinition>> m_functionModifiers; @@ -315,6 +331,28 @@ private: std::vector<ASTPointer<VariableDeclaration>> m_members; }; +class EnumDefinition: public Declaration +{ +public: + EnumDefinition(Location const& _location, + ASTPointer<ASTString> const& _name, + std::vector<ASTPointer<EnumDeclaration>> const& _members): + Declaration(_location, _name), m_members(_members) {} + virtual void accept(ASTVisitor& _visitor) override; + virtual void accept(ASTConstVisitor& _visitor) const override; + + std::vector<ASTPointer<EnumDeclaration>> const& getMembers() const { return m_members; } + + virtual TypePointer getType(ContractDefinition const*) const override; + + /// Checks that the members do not include any duplicate names + void checkValidityOfMembers() const; + +private: + + std::vector<ASTPointer<EnumDeclaration>> m_members; +}; + /** * Parameter list, used as function parameter list and return list. * None of the parameters is allowed to contain mappings (not even recursively diff --git a/ASTForward.h b/ASTForward.h index 22015f26..a0a6f683 100644 --- a/ASTForward.h +++ b/ASTForward.h @@ -40,6 +40,8 @@ class Declaration; class ContractDefinition; class InheritanceSpecifier; class StructDefinition; +class EnumDefinition; +class EnumDeclaration; class ParameterList; class FunctionDefinition; class VariableDeclaration; diff --git a/ASTPrinter.cpp b/ASTPrinter.cpp index 949740e8..34cd12a9 100644 --- a/ASTPrinter.cpp +++ b/ASTPrinter.cpp @@ -71,6 +71,18 @@ bool ASTPrinter::visit(StructDefinition const& _node) return goDeeper(); } +bool ASTPrinter::visit(EnumDefinition const& _node) +{ + writeLine("EnumDefinition \"" + _node.getName() + "\""); + return goDeeper(); +} + +bool ASTPrinter::visit(EnuumDeclaration const& _node) +{ + writeLine("EnumValue \"" + _node.getName() + "\""); + return goDeeper(); +} + bool ASTPrinter::visit(ParameterList const& _node) { writeLine("ParameterList"); @@ -347,6 +359,16 @@ void ASTPrinter::endVisit(StructDefinition const&) m_indentation--; } +void ASTPrinter::endVisit(EnumDefinition const&) +{ + m_indentation--; +} + +void ASTPrinter::endVisit(EnumDeclaration const&) +{ + m_indentation--; +} + void ASTPrinter::endVisit(ParameterList const&) { m_indentation--; diff --git a/ASTPrinter.h b/ASTPrinter.h index ebc163e3..a306e90b 100644 --- a/ASTPrinter.h +++ b/ASTPrinter.h @@ -46,6 +46,8 @@ public: bool visit(ContractDefinition const& _node) override; bool visit(InheritanceSpecifier const& _node) override; bool visit(StructDefinition const& _node) override; + bool visit(EnumDefinition const& _node) override; + bool visit(EnumDeclaration const& _node) override; bool visit(ParameterList const& _node) override; bool visit(FunctionDefinition const& _node) override; bool visit(VariableDeclaration const& _node) override; @@ -85,6 +87,8 @@ public: void endVisit(ContractDefinition const&) override; void endVisit(InheritanceSpecifier const&) override; void endVisit(StructDefinition const&) override; + void endVisit(EnumDefinition const&) override; + void endVisit(EnumDeclaration const&) override; void endVisit(ParameterList const&) override; void endVisit(FunctionDefinition const&) override; void endVisit(VariableDeclaration const&) override; diff --git a/ASTVisitor.h b/ASTVisitor.h index 29490277..b05ec658 100644 --- a/ASTVisitor.h +++ b/ASTVisitor.h @@ -47,6 +47,7 @@ public: virtual bool visit(ContractDefinition&) { return true; } virtual bool visit(InheritanceSpecifier&) { return true; } virtual bool visit(StructDefinition&) { return true; } + virtual bool visit(EnumDefinition&) { return true; } virtual bool visit(ParameterList&) { return true; } virtual bool visit(FunctionDefinition&) { return true; } virtual bool visit(VariableDeclaration&) { return true; } @@ -88,6 +89,7 @@ public: virtual void endVisit(ContractDefinition&) { } virtual void endVisit(InheritanceSpecifier&) { } virtual void endVisit(StructDefinition&) { } + virtual void endVisit(EnumDefinition&) { } virtual void endVisit(ParameterList&) { } virtual void endVisit(FunctionDefinition&) { } virtual void endVisit(VariableDeclaration&) { } @@ -133,6 +135,7 @@ public: virtual bool visit(ContractDefinition const&) { return true; } virtual bool visit(InheritanceSpecifier const&) { return true; } virtual bool visit(StructDefinition const&) { return true; } + virtual bool visit(EnumDefinition const&) { return true; } virtual bool visit(ParameterList const&) { return true; } virtual bool visit(FunctionDefinition const&) { return true; } virtual bool visit(VariableDeclaration const&) { return true; } @@ -174,6 +177,7 @@ public: virtual void endVisit(ContractDefinition const&) { } virtual void endVisit(InheritanceSpecifier const&) { } virtual void endVisit(StructDefinition const&) { } + virtual void endVisit(EnumDefinition const&) { } virtual void endVisit(ParameterList const&) { } virtual void endVisit(FunctionDefinition const&) { } virtual void endVisit(VariableDeclaration const&) { } diff --git a/AST_accept.h b/AST_accept.h index 38108cd7..15f6b7ee 100644 --- a/AST_accept.h +++ b/AST_accept.h @@ -112,6 +112,18 @@ void StructDefinition::accept(ASTVisitor& _visitor) _visitor.endVisit(*this); } +void EnumDefinition::accept(ASTVisitor& _visitor) +{ + _visitor.visit(*this) + _visitor.endVisit(*this); +} + +void EnumDefinition::accept(ASTConstVisitor& _visitor) const +{ + _visitor.visit(*this) + _visitor.endVisit(*this); +} + void StructDefinition::accept(ASTConstVisitor& _visitor) const { if (_visitor.visit(*this)) @@ -119,6 +119,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition() ASTPointer<ASTString> name = expectIdentifierToken(); vector<ASTPointer<InheritanceSpecifier>> baseContracts; vector<ASTPointer<StructDefinition>> structs; + vector<ASTPointer<EnumDefinition>> enums; vector<ASTPointer<VariableDeclaration>> stateVariables; vector<ASTPointer<FunctionDefinition>> functions; vector<ASTPointer<ModifierDefinition>> modifiers; @@ -140,6 +141,8 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition() functions.push_back(parseFunctionDefinition(name.get())); else if (currentToken == Token::Struct) structs.push_back(parseStructDefinition()); + else if (currentToken == Token::Enum) + enums.push_back(parseEnumDefinition()); else if (currentToken == Token::Identifier || currentToken == Token::Mapping || Token::isElementaryTypeName(currentToken)) { @@ -157,7 +160,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition() } nodeFactory.markEndPosition(); expectToken(Token::RBrace); - return nodeFactory.createNode<ContractDefinition>(name, docString, baseContracts, structs, + return nodeFactory.createNode<ContractDefinition>(name, docString, baseContracts, structs, enums, stateVariables, functions, modifiers, events); } @@ -263,6 +266,35 @@ ASTPointer<StructDefinition> Parser::parseStructDefinition() return nodeFactory.createNode<StructDefinition>(name, members); } +ASTPointer<EnumDeclaration> Parser::parseEnumDeclaration() +{ + ASTNodeFactory nodeFactory(*this); + ASTPointer<ASTString> name = expectIdentifierToken(); + nodeFactory.markEndPosition(); + return nodeFactory.createNode<EnumDeclaration>(name); +} + +ASTPointer<EnumDefinition> Parser::parseEnumDefinition() +{ + ASTNodeFactory nodeFactory(*this); + expectToken(Token::Enum); + ASTPointer<ASTString> name = expectIdentifierToken(); + vector<ASTPointer<Declaration>> members; + expectToken(Token::LBrace); + + while (m_scanner->getCurrentToken() == Token::Identifier) + { + members.push_back(parseEnumDeclaration()); + if (m_scanner->getCurrentToken() == Token::RBrace) + break; + expectToken(Token::Comma); + } + + nodeFactory.markEndPosition(); + expectToken(Token::RBrace); + return nodeFactory.createNode<EnumDefinition>(name, members); +} + ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(VarDeclParserOptions const& _options) { ASTNodeFactory nodeFactory(*this); @@ -823,6 +855,13 @@ ASTPointer<ASTString> Parser::expectIdentifierToken() return getLiteralAndAdvance(); } +ASTPointer<ASTString> Parser::peekIdentifierToken() +{ + if (m_scanner->getCurrentToken() != Token::Identifier) + return nullptr; + return getLiteralAndAdvance(); +} + ASTPointer<ASTString> Parser::getLiteralAndAdvance() { ASTPointer<ASTString> identifier = make_shared<ASTString>(m_scanner->getCurrentLiteral()); @@ -61,6 +61,8 @@ private: Declaration::Visibility parseVisibilitySpecifier(Token::Value _token); ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName); ASTPointer<StructDefinition> parseStructDefinition(); + ASTPointer<EnumDefinition> parseEnumDefinition(); + ASTPointer<EnumDeclaration> parseEnumDeclaration(); ASTPointer<VariableDeclaration> parseVariableDeclaration(VarDeclParserOptions const& _options = VarDeclParserOptions()); ASTPointer<ModifierDefinition> parseModifierDefinition(); ASTPointer<EventDefinition> parseEventDefinition(); @@ -96,6 +98,7 @@ private: void expectToken(Token::Value _value); Token::Value expectAssignmentOperator(); ASTPointer<ASTString> expectIdentifierToken(); + ASTPointer<ASTString> peekIdentifierToken(); ASTPointer<ASTString> getLiteralAndAdvance(); ///@} |