mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #953 from LefterisJP/sol_ethSubDenominations
Solidity ether subdenominations
This commit is contained in:
commit
59a3909376
11
AST.cpp
11
AST.cpp
@ -594,6 +594,17 @@ void ElementaryTypeNameExpression::checkTypeRequirements()
|
|||||||
m_type = make_shared<TypeType>(Type::fromElementaryTypeName(m_typeToken));
|
m_type = make_shared<TypeType>(Type::fromElementaryTypeName(m_typeToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Literal::Literal(Location const& _location, Token::Value _token,
|
||||||
|
ASTPointer<ASTString> const& _value,
|
||||||
|
Token::Value _sub):
|
||||||
|
PrimaryExpression(_location), m_token(_token), m_value(_value)
|
||||||
|
{
|
||||||
|
if (Token::isEtherSubdenomination(_sub))
|
||||||
|
m_subDenomination = static_cast<Literal::SubDenomination>(_sub);
|
||||||
|
else
|
||||||
|
m_subDenomination = Literal::SubDenomination::None;
|
||||||
|
}
|
||||||
|
|
||||||
void Literal::checkTypeRequirements()
|
void Literal::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
m_type = Type::forLiteral(*this);
|
m_type = Type::forLiteral(*this);
|
||||||
|
18
AST.h
18
AST.h
@ -1112,13 +1112,22 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A literal string or number. @see Type::literalToBigEndian is used to actually parse its value.
|
* A literal string or number. @see ExpressionCompiler::endVisit() is used to actually parse its value.
|
||||||
*/
|
*/
|
||||||
class Literal: public PrimaryExpression
|
class Literal: public PrimaryExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Literal(Location const& _location, Token::Value _token, ASTPointer<ASTString> const& _value):
|
enum class SubDenomination
|
||||||
PrimaryExpression(_location), m_token(_token), m_value(_value) {}
|
{
|
||||||
|
None = Token::ILLEGAL,
|
||||||
|
Wei = Token::SubWei,
|
||||||
|
Szabo = Token::SubSzabo,
|
||||||
|
Finney = Token::SubFinney,
|
||||||
|
Ether = Token::SubEther
|
||||||
|
};
|
||||||
|
Literal(Location const& _location, Token::Value _token,
|
||||||
|
ASTPointer<ASTString> const& _value,
|
||||||
|
Token::Value _sub = Token::ILLEGAL);
|
||||||
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;
|
||||||
virtual void checkTypeRequirements() override;
|
virtual void checkTypeRequirements() override;
|
||||||
@ -1127,9 +1136,12 @@ public:
|
|||||||
/// @returns the non-parsed value of the literal
|
/// @returns the non-parsed value of the literal
|
||||||
ASTString const& getValue() const { return *m_value; }
|
ASTString const& getValue() const { return *m_value; }
|
||||||
|
|
||||||
|
SubDenomination getSubDenomination() const { return m_subDenomination; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value m_token;
|
Token::Value m_token;
|
||||||
ASTPointer<ASTString> m_value;
|
ASTPointer<ASTString> m_value;
|
||||||
|
SubDenomination m_subDenomination;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -180,7 +180,7 @@ ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()
|
|||||||
|
|
||||||
Declaration::Visibility Parser::parseVisibilitySpecifier(Token::Value _token)
|
Declaration::Visibility Parser::parseVisibilitySpecifier(Token::Value _token)
|
||||||
{
|
{
|
||||||
Declaration::Visibility visibility;
|
Declaration::Visibility visibility = Declaration::Visibility::DEFAULT;
|
||||||
if (_token == Token::PUBLIC)
|
if (_token == Token::PUBLIC)
|
||||||
visibility = Declaration::Visibility::PUBLIC;
|
visibility = Declaration::Visibility::PUBLIC;
|
||||||
else if (_token == Token::PROTECTED)
|
else if (_token == Token::PROTECTED)
|
||||||
@ -684,6 +684,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
Token::Value token = m_scanner->getCurrentToken();
|
Token::Value token = m_scanner->getCurrentToken();
|
||||||
ASTPointer<Expression> expression;
|
ASTPointer<Expression> expression;
|
||||||
|
Token::Value nextToken = Token::ILLEGAL;
|
||||||
switch (token)
|
switch (token)
|
||||||
{
|
{
|
||||||
case Token::TRUE_LITERAL:
|
case Token::TRUE_LITERAL:
|
||||||
@ -691,9 +692,12 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
|
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
|
||||||
break;
|
break;
|
||||||
case Token::NUMBER:
|
case Token::NUMBER:
|
||||||
|
nextToken = m_scanner->peekNextToken();
|
||||||
case Token::STRING_LITERAL:
|
case Token::STRING_LITERAL:
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
|
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance(), nextToken);
|
||||||
|
if (Token::isEtherSubdenomination(nextToken))
|
||||||
|
m_scanner->next();
|
||||||
break;
|
break;
|
||||||
case Token::IDENTIFIER:
|
case Token::IDENTIFIER:
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
|
6
Token.h
6
Token.h
@ -174,6 +174,11 @@ namespace solidity
|
|||||||
K(WHILE, "while", 0) \
|
K(WHILE, "while", 0) \
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
|
/* Ether subdenominations */ \
|
||||||
|
K(SubWei, "wei", 0) \
|
||||||
|
K(SubSzabo, "szabo", 0) \
|
||||||
|
K(SubFinney, "finney", 0) \
|
||||||
|
K(SubEther, "ether", 0) \
|
||||||
/* type keywords, keep them in this order, keep int as first keyword
|
/* type keywords, keep them in this order, keep int as first keyword
|
||||||
* the implementation in Types.cpp has to be synced to this here
|
* the implementation in Types.cpp has to be synced to this here
|
||||||
* TODO more to be added */ \
|
* TODO more to be added */ \
|
||||||
@ -378,6 +383,7 @@ public:
|
|||||||
static bool isCountOp(Value op) { return op == INC || op == DEC; }
|
static bool isCountOp(Value op) { return op == INC || op == DEC; }
|
||||||
static bool isShiftOp(Value op) { return (SHL <= op) && (op <= SHR); }
|
static bool isShiftOp(Value op) { return (SHL <= op) && (op <= SHR); }
|
||||||
static bool isVisibilitySpecifier(Value op) { return op == PUBLIC || op == PRIVATE || op == PROTECTED; }
|
static bool isVisibilitySpecifier(Value op) { return op == PUBLIC || op == PRIVATE || op == PROTECTED; }
|
||||||
|
static bool isEtherSubdenomination(Value op) { return op == SubWei || op == SubSzabo || op == SubFinney || op == Token::SubEther; }
|
||||||
|
|
||||||
// Returns a string corresponding to the JS token string
|
// Returns a string corresponding to the JS token string
|
||||||
// (.e., "<" for the token LT) or NULL if the token doesn't
|
// (.e., "<" for the token LT) or NULL if the token doesn't
|
||||||
|
30
Types.cpp
30
Types.cpp
@ -326,15 +326,39 @@ string IntegerConstantType::toString() const
|
|||||||
return "int_const " + m_value.str();
|
return "int_const " + m_value.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
u256 IntegerConstantType::literalValue(Literal const*) const
|
u256 IntegerConstantType::literalValue(Literal const* _literal) const
|
||||||
{
|
{
|
||||||
|
u256 value;
|
||||||
// we ignore the literal and hope that the type was correctly determined
|
// we ignore the literal and hope that the type was correctly determined
|
||||||
solAssert(m_value <= u256(-1), "Integer constant too large.");
|
solAssert(m_value <= u256(-1), "Integer constant too large.");
|
||||||
solAssert(m_value >= -(bigint(1) << 255), "Integer constant too small.");
|
solAssert(m_value >= -(bigint(1) << 255), "Integer constant too small.");
|
||||||
|
|
||||||
if (m_value >= 0)
|
if (m_value >= 0)
|
||||||
return u256(m_value);
|
value = u256(m_value);
|
||||||
else
|
else
|
||||||
return s2u(s256(m_value));
|
value = s2u(s256(m_value));
|
||||||
|
|
||||||
|
if (_literal)
|
||||||
|
{
|
||||||
|
Literal::SubDenomination sub =_literal->getSubDenomination();
|
||||||
|
switch(sub)
|
||||||
|
{
|
||||||
|
case Literal::SubDenomination::Wei:
|
||||||
|
case Literal::SubDenomination::None:
|
||||||
|
break;
|
||||||
|
case Literal::SubDenomination::Szabo:
|
||||||
|
value *= u256(1000000000000);
|
||||||
|
break;
|
||||||
|
case Literal::SubDenomination::Finney:
|
||||||
|
value *= u256(1000000000000000);
|
||||||
|
break;
|
||||||
|
case Literal::SubDenomination::Ether:
|
||||||
|
value *= u256(1000000000000000000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<IntegerType const> IntegerConstantType::getIntegerType() const
|
shared_ptr<IntegerType const> IntegerConstantType::getIntegerType() const
|
||||||
|
Loading…
Reference in New Issue
Block a user