aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLefteris Karapetsas <lefteris@refu.co>2015-02-10 01:08:56 +0800
committerLefteris Karapetsas <lefteris@refu.co>2015-02-14 06:16:14 +0800
commita295417f3476428c286f96433a42a96bfe29fee3 (patch)
treee5f9b374407dfcdc4f11943d91df69e4ec559b0a
parent54ed8877aa673fd6765c1238bcef598331ae41ae (diff)
downloaddexon-solidity-a295417f3476428c286f96433a42a96bfe29fee3.tar.gz
dexon-solidity-a295417f3476428c286f96433a42a96bfe29fee3.tar.zst
dexon-solidity-a295417f3476428c286f96433a42a96bfe29fee3.zip
Parsing enums for Solidity - WIP
-rw-r--r--AST.cpp16
-rw-r--r--AST.h38
-rw-r--r--ASTForward.h2
-rw-r--r--ASTPrinter.cpp22
-rw-r--r--ASTPrinter.h4
-rw-r--r--ASTVisitor.h4
-rw-r--r--AST_accept.h12
-rw-r--r--Parser.cpp41
-rw-r--r--Parser.h3
9 files changed, 141 insertions, 1 deletions
diff --git a/AST.cpp b/AST.cpp
index 3c6b6007..0c34cea3 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -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);
diff --git a/AST.h b/AST.h
index 4e79026e..d3a7853a 100644
--- a/AST.h
+++ b/AST.h
@@ -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))
diff --git a/Parser.cpp b/Parser.cpp
index f076df87..2f0796d6 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -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());
diff --git a/Parser.h b/Parser.h
index 5816fec4..734bdd57 100644
--- a/Parser.h
+++ b/Parser.h
@@ -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();
///@}