added parsing for constant variables

This commit is contained in:
Liana Husikyan 2015-03-03 12:58:01 +01:00
parent a16677dcfb
commit 67cd3a7180
7 changed files with 42 additions and 17 deletions

View File

@ -197,7 +197,7 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::getIn
} }
for (ASTPointer<VariableDeclaration> const& v: contract->getStateVariables()) for (ASTPointer<VariableDeclaration> const& v: contract->getStateVariables())
if (v->isPublic() && functionsSeen.count(v->getName()) == 0) if (v->isPublic() && functionsSeen.count(v->getName()) == 0 && !v->isConstant())
{ {
FunctionType ftype(*v); FunctionType ftype(*v);
functionsSeen.insert(v->getName()); functionsSeen.insert(v->getName());
@ -322,8 +322,8 @@ string FunctionDefinition::getCanonicalSignature() const
bool VariableDeclaration::isLValue() const bool VariableDeclaration::isLValue() const
{ {
// External function parameters are Read-Only // External function parameters and constant declared variables are Read-Only
return !isExternalFunctionParameter(); return !isExternalFunctionParameter() && !m_isConstant;
} }
void VariableDeclaration::checkTypeRequirements() void VariableDeclaration::checkTypeRequirements()

21
AST.h
View File

@ -440,13 +440,22 @@ private:
class VariableDeclaration: public Declaration class VariableDeclaration: public Declaration
{ {
public: public:
VariableDeclaration(SourceLocation const& _location, ASTPointer<TypeName> const& _type, VariableDeclaration(
ASTPointer<ASTString> const& _name, ASTPointer<Expression> _value, SourceLocation const& _location,
ASTPointer<TypeName> const& _type,
ASTPointer<ASTString> const& _name,
ASTPointer<Expression> _value,
Visibility _visibility, Visibility _visibility,
bool _isStateVar = false, bool _isIndexed = false): bool _isStateVar = false,
bool _isIndexed = false,
bool _isConstant = false):
Declaration(_location, _name, _visibility), Declaration(_location, _name, _visibility),
m_typeName(_type), m_value(_value), m_typeName(_type),
m_isStateVariable(_isStateVar), m_isIndexed(_isIndexed) {} m_value(_value),
m_isStateVariable(_isStateVar),
m_isIndexed(_isIndexed),
m_isConstant(_isConstant){}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
@ -465,6 +474,7 @@ public:
bool isExternalFunctionParameter() const; bool isExternalFunctionParameter() const;
bool isStateVariable() const { return m_isStateVariable; } bool isStateVariable() const { return m_isStateVariable; }
bool isIndexed() const { return m_isIndexed; } bool isIndexed() const { return m_isIndexed; }
bool isConstant() const { return m_isConstant; }
protected: protected:
Visibility getDefaultVisibility() const override { return Visibility::Internal; } Visibility getDefaultVisibility() const override { return Visibility::Internal; }
@ -474,6 +484,7 @@ private:
ASTPointer<Expression> m_value; ///< the assigned value, can be missing ASTPointer<Expression> m_value; ///< the assigned value, can be missing
bool m_isStateVariable; ///< Whether or not this is a contract state variable bool m_isStateVariable; ///< Whether or not this is a contract state variable
bool m_isIndexed; ///< Whether this is an indexed variable (used by events). bool m_isIndexed; ///< Whether this is an indexed variable (used by events).
bool m_isConstant; ///< Whether the variable is a compile-time constant.
std::shared_ptr<Type const> m_type; ///< derived type, initially empty std::shared_ptr<Type const> m_type; ///< derived type, initially empty
}; };

View File

@ -276,13 +276,14 @@ void Compiler::registerStateVariables(ContractDefinition const& _contract)
{ {
for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.getLinearizedBaseContracts())) for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.getLinearizedBaseContracts()))
for (ASTPointer<VariableDeclaration> const& variable: contract->getStateVariables()) for (ASTPointer<VariableDeclaration> const& variable: contract->getStateVariables())
if (!variable->isConstant())
m_context.addStateVariable(*variable); m_context.addStateVariable(*variable);
} }
void Compiler::initializeStateVariables(ContractDefinition const& _contract) void Compiler::initializeStateVariables(ContractDefinition const& _contract)
{ {
for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables()) for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
if (variable->getValue()) if (variable->getValue() && !variable->isConstant())
ExpressionCompiler(m_context, m_optimize).appendStateVariableInitialization(*variable); ExpressionCompiler(m_context, m_optimize).appendStateVariableInitialization(*variable);
} }

View File

@ -855,8 +855,11 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
} }
else if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration)) else if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))
m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag(); m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag();
else if (dynamic_cast<VariableDeclaration const*>(declaration)) else if (auto variable = dynamic_cast<VariableDeclaration const*>(declaration))
{
if (!variable->isConstant())
setLValueFromDeclaration(*declaration, _identifier); setLValueFromDeclaration(*declaration, _identifier);
}
else if (dynamic_cast<ContractDefinition const*>(declaration)) else if (dynamic_cast<ContractDefinition const*>(declaration))
{ {
// no-op // no-op

View File

@ -135,6 +135,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
} }
while (m_scanner->getCurrentToken() == Token::Comma); while (m_scanner->getCurrentToken() == Token::Comma);
expectToken(Token::LBrace); expectToken(Token::LBrace);
bool isDeclaredConst = false;
while (true) while (true)
{ {
Token::Value currentToken = m_scanner->getCurrentToken(); Token::Value currentToken = m_scanner->getCurrentToken();
@ -152,13 +153,21 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
VarDeclParserOptions options; VarDeclParserOptions options;
options.isStateVariable = true; options.isStateVariable = true;
options.allowInitialValue = true; options.allowInitialValue = true;
options.isDeclaredConst = isDeclaredConst;
stateVariables.push_back(parseVariableDeclaration(options)); stateVariables.push_back(parseVariableDeclaration(options));
isDeclaredConst = false;
expectToken(Token::Semicolon); expectToken(Token::Semicolon);
} }
else if (currentToken == Token::Modifier) else if (currentToken == Token::Modifier)
modifiers.push_back(parseModifierDefinition()); modifiers.push_back(parseModifierDefinition());
else if (currentToken == Token::Event) else if (currentToken == Token::Event)
events.push_back(parseEventDefinition()); events.push_back(parseEventDefinition());
else if (currentToken == Token::Const)
{
solAssert(Token::isElementaryTypeName(m_scanner->peekNextToken()), "");
isDeclaredConst = true;
m_scanner->next();
}
else else
BOOST_THROW_EXCEPTION(createParserError("Function, variable, struct or modifier declaration expected.")); BOOST_THROW_EXCEPTION(createParserError("Function, variable, struct or modifier declaration expected."));
} }
@ -348,7 +357,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
} }
return nodeFactory.createNode<VariableDeclaration>(type, identifier, value, return nodeFactory.createNode<VariableDeclaration>(type, identifier, value,
visibility, _options.isStateVariable, visibility, _options.isStateVariable,
isIndexed); isIndexed, _options.isDeclaredConst);
} }
ASTPointer<ModifierDefinition> Parser::parseModifierDefinition() ASTPointer<ModifierDefinition> Parser::parseModifierDefinition()

View File

@ -54,6 +54,7 @@ private:
bool allowIndexed = false; bool allowIndexed = false;
bool allowEmptyName = false; bool allowEmptyName = false;
bool allowInitialValue = false; bool allowInitialValue = false;
bool isDeclaredConst = false;
}; };
///@{ ///@{

View File

@ -516,7 +516,7 @@ private:
std::vector<std::string> m_parameterNames; std::vector<std::string> m_parameterNames;
std::vector<std::string> m_returnParameterNames; std::vector<std::string> m_returnParameterNames;
Location const m_location; Location const m_location;
/// true iff the function takes an arbitrary number of arguments of arbitrary types /// true if the function takes an arbitrary number of arguments of arbitrary types
bool const m_arbitraryParameters = false; bool const m_arbitraryParameters = false;
bool const m_gasSet = false; ///< true iff the gas value to be used is on the stack bool const m_gasSet = false; ///< true iff the gas value to be used is on the stack
bool const m_valueSet = false; ///< true iff the value to be sent is on the stack bool const m_valueSet = false; ///< true iff the value to be sent is on the stack