aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-03-12 00:53:33 +0800
committerchriseth <c@ethdev.com>2016-03-12 00:53:33 +0800
commit1f9578cea3f7ea1982ba2288cd3238bfe791b348 (patch)
tree9cc3e20fde1c8c89afd3ca33a6c4b067c448e4bc /libsolidity
parent60a21c6487743578af6fd4e1540a36a2b80fcac7 (diff)
parent1bf87c6c2b90406d8a59aa928a9fe43a169e157a (diff)
downloaddexon-solidity-1f9578cea3f7ea1982ba2288cd3238bfe791b348.tar
dexon-solidity-1f9578cea3f7ea1982ba2288cd3238bfe791b348.tar.gz
dexon-solidity-1f9578cea3f7ea1982ba2288cd3238bfe791b348.tar.bz2
dexon-solidity-1f9578cea3f7ea1982ba2288cd3238bfe791b348.tar.lz
dexon-solidity-1f9578cea3f7ea1982ba2288cd3238bfe791b348.tar.xz
dexon-solidity-1f9578cea3f7ea1982ba2288cd3238bfe791b348.tar.zst
dexon-solidity-1f9578cea3f7ea1982ba2288cd3238bfe791b348.zip
Merge pull request #429 from chriseth/keywords
Breaking changes for version 0.3.0
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/ast/Types.cpp47
-rw-r--r--libsolidity/ast/Types.h6
-rw-r--r--libsolidity/codegen/Compiler.cpp10
-rw-r--r--libsolidity/codegen/Compiler.h2
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp29
-rw-r--r--libsolidity/formal/Why3Translator.h2
-rw-r--r--libsolidity/interface/CompilerStack.h10
-rw-r--r--libsolidity/interface/InterfaceHandler.h2
-rw-r--r--libsolidity/parsing/Parser.h4
-rw-r--r--libsolidity/parsing/Scanner.h6
-rw-r--r--libsolidity/parsing/Token.cpp43
-rw-r--r--libsolidity/parsing/Token.h22
12 files changed, 112 insertions, 71 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index bca83d59..4dc1eb13 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -333,6 +333,7 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons
{"balance", make_shared<IntegerType >(256)},
{"call", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Location::Bare, true)},
{"callcode", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Location::BareCallCode, true)},
+ {"delegatecall", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Location::BareDelegateCall, true)},
{"send", make_shared<FunctionType>(strings{"uint"}, strings{"bool"}, FunctionType::Location::Send)}
};
else
@@ -1561,9 +1562,9 @@ unsigned FunctionType::sizeOnStack() const
}
unsigned size = 0;
- if (location == Location::External || location == Location::CallCode)
+ if (location == Location::External || location == Location::CallCode || location == Location::DelegateCall)
size = 2;
- else if (location == Location::Bare || location == Location::BareCallCode)
+ else if (location == Location::Bare || location == Location::BareCallCode || location == Location::BareDelegateCall)
size = 1;
else if (location == Location::Internal)
size = 1;
@@ -1619,9 +1620,11 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con
case Location::RIPEMD160:
case Location::Bare:
case Location::BareCallCode:
+ case Location::BareDelegateCall:
{
- MemberList::MemberMap members{
- {
+ MemberList::MemberMap members;
+ if (m_location != Location::BareDelegateCall && m_location != Location::DelegateCall)
+ members.push_back(MemberList::Member(
"value",
make_shared<FunctionType>(
parseElementaryTypeVector({"uint"}),
@@ -1634,25 +1637,22 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con
m_gasSet,
m_valueSet
)
- }
- };
+ ));
if (m_location != Location::Creation)
- members.push_back(
- MemberList::Member(
- "gas",
- make_shared<FunctionType>(
- parseElementaryTypeVector({"uint"}),
- TypePointers{copyAndSetGasOrValue(true, false)},
- strings(),
- strings(),
- Location::SetGas,
- false,
- nullptr,
- m_gasSet,
- m_valueSet
- )
+ members.push_back(MemberList::Member(
+ "gas",
+ make_shared<FunctionType>(
+ parseElementaryTypeVector({"uint"}),
+ TypePointers{copyAndSetGasOrValue(true, false)},
+ strings(),
+ strings(),
+ Location::SetGas,
+ false,
+ nullptr,
+ m_gasSet,
+ m_valueSet
)
- );
+ ));
return members;
}
default:
@@ -1700,6 +1700,7 @@ bool FunctionType::isBareCall() const
{
case Location::Bare:
case Location::BareCallCode:
+ case Location::BareDelegateCall:
case Location::ECRecover:
case Location::SHA256:
case Location::RIPEMD160:
@@ -1785,7 +1786,7 @@ FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary, bool _bound)
returnParameterTypes,
m_parameterNames,
returnParameterNames,
- _inLibrary ? Location::CallCode : m_location,
+ _inLibrary ? Location::DelegateCall : m_location,
m_arbitraryParameters,
m_declaration,
m_gasSet,
@@ -1884,7 +1885,7 @@ MemberList::MemberMap TypeType::nativeMembers(ContractDefinition const* _current
for (auto const& it: contract.interfaceFunctions())
members.push_back(MemberList::Member(
it.second->declaration().name(),
- it.second->asMemberFunction(true), // use callcode
+ it.second->asMemberFunction(true),
&it.second->declaration()
));
if (isBase)
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index b4a2d573..1d65aeb6 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -732,8 +732,10 @@ public:
Internal, ///< stack-call using plain JUMP
External, ///< external call using CALL
CallCode, ///< extercnal call using CALLCODE, i.e. not exchanging the storage
+ DelegateCall, ///< extercnal call using DELEGATECALL, i.e. not exchanging the storage
Bare, ///< CALL without function hash
BareCallCode, ///< CALLCODE without function hash
+ BareDelegateCall, ///< DELEGATECALL without function hash
Creation, ///< external call using CREATE
Send, ///< CALL, but without data and gas
SHA3, ///< SHA3
@@ -824,7 +826,7 @@ public:
/// @returns TypePointer of a new FunctionType object. All input/return parameters are an
/// appropriate external types (i.e. the interfaceType()s) of input/return parameters of
/// current function.
- /// Returns an empty shared pointer if one of the input/return parameters does not have an
+ /// @returns an empty shared pointer if one of the input/return parameters does not have an
/// external type.
FunctionTypePointer interfaceFunctionType() const;
@@ -869,7 +871,7 @@ public:
/// removed and the location of reference types is changed from CallData to Memory.
/// This is needed if external functions are called on other contracts, as they cannot return
/// dynamic values.
- /// @param _inLibrary if true, uses CallCode as location.
+ /// @param _inLibrary if true, uses DelegateCall as location.
/// @param _bound if true, the argumenst are placed as `arg1.functionName(arg2, ..., argn)`.
FunctionTypePointer asMemberFunction(bool _inLibrary, bool _bound = false) const;
diff --git a/libsolidity/codegen/Compiler.cpp b/libsolidity/codegen/Compiler.cpp
index 18803b71..c7eb71a8 100644
--- a/libsolidity/codegen/Compiler.cpp
+++ b/libsolidity/codegen/Compiler.cpp
@@ -773,15 +773,13 @@ eth::Assembly Compiler::cloneRuntime()
a << u256(0) << eth::Instruction::DUP1 << eth::Instruction::CALLDATACOPY;
//@todo adjust for larger return values, make this dynamic.
a << u256(0x20) << u256(0) << eth::Instruction::CALLDATASIZE;
- // unfortunately, we have to send the value again, so that CALLVALUE returns the correct value
- // in the callcoded contract.
- a << u256(0) << eth::Instruction::CALLVALUE;
+ a << u256(0);
// this is the address which has to be substituted by the linker.
//@todo implement as special "marker" AssemblyItem.
a << u256("0xcafecafecafecafecafecafecafecafecafecafe");
- a << u256(schedule.callGas + schedule.callValueTransferGas + 10) << eth::Instruction::GAS << eth::Instruction::SUB;
- a << eth::Instruction::CALLCODE;
- //Propagate error condition (if CALLCODE pushes 0 on stack).
+ a << u256(schedule.callGas + 10) << eth::Instruction::GAS << eth::Instruction::SUB;
+ a << eth::Instruction::DELEGATECALL;
+ //Propagate error condition (if DELEGATECALL pushes 0 on stack).
a << eth::Instruction::ISZERO;
a.appendJumpI(a.errorTag());
//@todo adjust for larger return values, make this dynamic.
diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h
index 9d069f7c..fa33bd30 100644
--- a/libsolidity/codegen/Compiler.h
+++ b/libsolidity/codegen/Compiler.h
@@ -44,7 +44,7 @@ public:
ContractDefinition const& _contract,
std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts
);
- /// Compiles a contract that uses CALLCODE to call into a pre-deployed version of the given
+ /// Compiles a contract that uses DELEGATECALL to call into a pre-deployed version of the given
/// contract at runtime, but contains the full creation-time code.
void compileClone(
ContractDefinition const& _contract,
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 58db07b1..e0b2b5f6 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -465,8 +465,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
{
FunctionType const& function = *functionType;
if (function.bound())
- // Only callcode functions can be bound, this might be lifted later.
- solAssert(function.location() == Location::CallCode, "");
+ // Only delegatecall functions can be bound, this might be lifted later.
+ solAssert(function.location() == Location::DelegateCall, "");
switch (function.location())
{
case Location::Internal:
@@ -492,8 +492,10 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
}
case Location::External:
case Location::CallCode:
+ case Location::DelegateCall:
case Location::Bare:
case Location::BareCallCode:
+ case Location::BareDelegateCall:
_functionCall.expression().accept(*this);
appendExternalFunctionCall(function, arguments);
break;
@@ -875,7 +877,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
);
m_context << eth::Instruction::BALANCE;
}
- else if ((set<string>{"send", "call", "callcode"}).count(member))
+ else if ((set<string>{"send", "call", "callcode", "delegatecall"}).count(member))
utils().convertType(
*_memberAccess.expression().annotation().type,
IntegerType(0, IntegerType::Modifier::Address),
@@ -1356,6 +1358,7 @@ void ExpressionCompiler::appendExternalFunctionCall(
FunctionKind funKind = _functionType.location();
bool returnSuccessCondition = funKind == FunctionKind::Bare || funKind == FunctionKind::BareCallCode;
bool isCallCode = funKind == FunctionKind::BareCallCode || funKind == FunctionKind::CallCode;
+ bool isDelegateCall = funKind == FunctionKind::BareDelegateCall || funKind == FunctionKind::DelegateCall;
unsigned retSize = 0;
if (returnSuccessCondition)
@@ -1371,13 +1374,13 @@ void ExpressionCompiler::appendExternalFunctionCall(
TypePointers argumentTypes;
TypePointers parameterTypes = _functionType.parameterTypes();
bool manualFunctionId =
- (funKind == FunctionKind::Bare || funKind == FunctionKind::BareCallCode) &&
+ (funKind == FunctionKind::Bare || funKind == FunctionKind::BareCallCode || funKind == FunctionKind::BareDelegateCall) &&
!_arguments.empty() &&
_arguments.front()->annotation().type->mobileType()->calldataEncodedSize(false) ==
CompilerUtils::dataStartOffset;
if (manualFunctionId)
{
- // If we have a BareCall or BareCallCode and the first type has exactly 4 bytes, use it as
+ // If we have a Bare* and the first type has exactly 4 bytes, use it as
// function identifier.
_arguments.front()->accept(*this);
utils().convertType(
@@ -1416,7 +1419,7 @@ void ExpressionCompiler::appendExternalFunctionCall(
parameterTypes,
_functionType.padArguments(),
_functionType.takesArbitraryParameters(),
- isCallCode
+ isCallCode || isDelegateCall
);
// Stack now:
@@ -1435,8 +1438,10 @@ void ExpressionCompiler::appendExternalFunctionCall(
m_context << eth::Instruction::DUP2;
// CALL arguments: outSize, outOff, inSize, inOff (already present up to here)
- // value, addr, gas (stack top)
- if (_functionType.valueSet())
+ // [value,] addr, gas (stack top)
+ if (isDelegateCall)
+ solAssert(!_functionType.valueSet(), "Value set for delegatecall");
+ else if (_functionType.valueSet())
m_context << eth::dupInstruction(m_context.baseToCurrentStackOffset(valueStackPos));
else
m_context << u256(0);
@@ -1446,20 +1451,22 @@ void ExpressionCompiler::appendExternalFunctionCall(
m_context << eth::dupInstruction(m_context.baseToCurrentStackOffset(gasStackPos));
else
{
- eth::EVMSchedule schedule;// TODO: Make relevant to current suppose context.
+ eth::EVMSchedule schedule;
// send all gas except the amount needed to execute "SUB" and "CALL"
// @todo this retains too much gas for now, needs to be fine-tuned.
u256 gasNeededByCaller = schedule.callGas + 10;
if (_functionType.valueSet())
gasNeededByCaller += schedule.callValueTransferGas;
- if (!isCallCode)
+ if (!isCallCode && !isDelegateCall)
gasNeededByCaller += schedule.callNewAccountGas; // we never know
m_context <<
gasNeededByCaller <<
eth::Instruction::GAS <<
eth::Instruction::SUB;
}
- if (isCallCode)
+ if (isDelegateCall)
+ m_context << eth::Instruction::DELEGATECALL;
+ else if (isCallCode)
m_context << eth::Instruction::CALLCODE;
else
m_context << eth::Instruction::CALL;
diff --git a/libsolidity/formal/Why3Translator.h b/libsolidity/formal/Why3Translator.h
index f4315a7a..588b6d80 100644
--- a/libsolidity/formal/Why3Translator.h
+++ b/libsolidity/formal/Why3Translator.h
@@ -52,7 +52,7 @@ public:
std::string translation() const;
private:
- /// Returns an error.
+ /// Creates an error and adds it to errors list.
void error(ASTNode const& _node, std::string const& _description);
/// Reports a fatal error and throws.
void fatalError(ASTNode const& _node, std::string const& _description);
diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h
index 517d0055..c7f98184 100644
--- a/libsolidity/interface/CompilerStack.h
+++ b/libsolidity/interface/CompilerStack.h
@@ -101,7 +101,7 @@ public:
/// Sets the given source code as the only source unit apart from standard sources and parses it.
/// @returns false on error.
bool parse(std::string const& _sourceCode);
- /// Returns a list of the contract names in the sources.
+ /// @returns a list of the contract names in the sources.
std::vector<std::string> contractNames() const;
std::string defaultContractName() const;
@@ -124,7 +124,7 @@ public:
eth::LinkerObject const& object(std::string const& _contractName = "") const;
/// @returns the runtime object for the contract.
eth::LinkerObject const& runtimeObject(std::string const& _contractName = "") const;
- /// @returns the bytecode of a contract that uses an already deployed contract via CALLCODE.
+ /// @returns the bytecode of a contract that uses an already deployed contract via DELEGATECALL.
/// The returned bytes will contain a sequence of 20 bytes of the format "XXX...XXX" which have to
/// substituted by the actual address. Note that this sequence starts end ends in three X
/// characters but can contain anything in between.
@@ -144,13 +144,13 @@ public:
/// Prerequisite: Successful compilation.
Json::Value streamAssembly(std::ostream& _outStream, std::string const& _contractName = "", StringMap _sourceCodes = StringMap(), bool _inJsonFormat = false) const;
- /// Returns a string representing the contract interface in JSON.
+ /// @returns a string representing the contract interface in JSON.
/// Prerequisite: Successful call to parse or compile.
std::string const& interface(std::string const& _contractName = "") const;
- /// Returns a string representing the contract interface in Solidity.
+ /// @returns a string representing the contract interface in Solidity.
/// Prerequisite: Successful call to parse or compile.
std::string const& solidityInterface(std::string const& _contractName = "") const;
- /// Returns a string representing the contract's documentation in JSON.
+ /// @returns a string representing the contract's documentation in JSON.
/// Prerequisite: Successful call to parse or compile.
/// @param type The type of the documentation to get.
/// Can be one of 4 types defined at @c DocumentationType
diff --git a/libsolidity/interface/InterfaceHandler.h b/libsolidity/interface/InterfaceHandler.h
index 30b8f520..3e0a1660 100644
--- a/libsolidity/interface/InterfaceHandler.h
+++ b/libsolidity/interface/InterfaceHandler.h
@@ -85,7 +85,7 @@ public:
static std::string devDocumentation(ContractDefinition const& _contractDef);
private:
- /// Returns concatenation of all content under the given tag name.
+ /// @returns concatenation of all content under the given tag name.
static std::string extractDoc(std::multimap<std::string, DocTag> const& _tags, std::string const& _name);
};
diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h
index 9db3b3c4..a093cc5b 100644
--- a/libsolidity/parsing/Parser.h
+++ b/libsolidity/parsing/Parser.h
@@ -124,12 +124,12 @@ private:
/// For source code of the form "a[][8]" ("IndexAccessStructure"), this is not possible to
/// decide with constant look-ahead.
LookAheadInfo peekStatementType() const;
- /// Returns a typename parsed in look-ahead fashion from something like "a.b[8][2**70]".
+ /// @returns a typename parsed in look-ahead fashion from something like "a.b[8][2**70]".
ASTPointer<TypeName> typeNameIndexAccessStructure(
std::vector<ASTPointer<PrimaryExpression>> const& _path,
std::vector<std::pair<ASTPointer<Expression>, SourceLocation>> const& _indices
);
- /// Returns an expression parsed in look-ahead fashion from something like "a.b[8][2**70]".
+ /// @returns an expression parsed in look-ahead fashion from something like "a.b[8][2**70]".
ASTPointer<Expression> expressionFromIndexAccessStructure(
std::vector<ASTPointer<PrimaryExpression>> const& _path,
std::vector<std::pair<ASTPointer<Expression>, SourceLocation>> const& _indices
diff --git a/libsolidity/parsing/Scanner.h b/libsolidity/parsing/Scanner.h
index 8dde922d..cffcec8e 100644
--- a/libsolidity/parsing/Scanner.h
+++ b/libsolidity/parsing/Scanner.h
@@ -108,13 +108,13 @@ public:
/// Resets scanner to the start of input.
void reset();
- /// Returns the next token and advances input
+ /// @returns the next token and advances input
Token::Value next();
///@{
///@name Information about the current token
- /// Returns the current token
+ /// @returns the current token
Token::Value currentToken()
{
return m_currentToken.token;
@@ -138,7 +138,7 @@ public:
///@{
///@name Information about the next token
- /// Returns the next token without advancing input.
+ /// @returns the next token without advancing input.
Token::Value peekNextToken() const { return m_nextToken.token; }
SourceLocation peekLocation() const { return m_nextToken.location; }
std::string const& peekLiteral() const { return m_nextToken.literal; }
diff --git a/libsolidity/parsing/Token.cpp b/libsolidity/parsing/Token.cpp
index 78a90559..3812a83f 100644
--- a/libsolidity/parsing/Token.cpp
+++ b/libsolidity/parsing/Token.cpp
@@ -42,6 +42,7 @@
#include <map>
#include <libsolidity/parsing/Token.h>
+#include <boost/range/iterator_range.hpp>
using namespace std;
@@ -66,6 +67,13 @@ void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned con
"No elementary type " + string(Token::toString(_baseType)) + to_string(_first) + "."
);
}
+ else if (_baseType == Token::UFixedMxN || _baseType == Token::FixedMxN)
+ {
+ solAssert(
+ _first + _second <= 256 && _first % 8 == 0 && _second % 8 == 0,
+ "No elementary type " + string(Token::toString(_baseType)) + to_string(_first) + "x" + to_string(_second) + "."
+ );
+ }
m_token = _baseType;
m_firstNumber = _first;
m_secondNumber = _second;
@@ -101,26 +109,26 @@ char const Token::m_tokenType[] =
{
TOKEN_LIST(KT, KK)
};
-unsigned Token::extractM(string const& _literal)
+int Token::parseSize(string::const_iterator _begin, string::const_iterator _end)
{
try
{
- unsigned short m = stoi(_literal);
+ unsigned int m = boost::lexical_cast<int>(boost::make_iterator_range(_begin, _end));
return m;
}
- catch(out_of_range& e)
+ catch(boost::bad_lexical_cast const&)
{
- return 0;
+ return -1;
}
}
-tuple<Token::Value, unsigned short, unsigned short> Token::fromIdentifierOrKeyword(string const& _literal)
+tuple<Token::Value, unsigned int, unsigned int> Token::fromIdentifierOrKeyword(string const& _literal)
{
auto positionM = find_if(_literal.begin(), _literal.end(), ::isdigit);
if (positionM != _literal.end())
{
string baseType(_literal.begin(), positionM);
auto positionX = find_if_not(positionM, _literal.end(), ::isdigit);
- unsigned short m = extractM(string(positionM, positionX));
+ int m = parseSize(positionM, positionX);
Token::Value keyword = keywordByName(baseType);
if (keyword == Token::Bytes)
{
@@ -137,6 +145,29 @@ tuple<Token::Value, unsigned short, unsigned short> Token::fromIdentifierOrKeywo
return make_tuple(Token::IntM, m, 0);
}
}
+ else if (keyword == Token::UFixed || keyword == Token::Fixed)
+ {
+ if (
+ positionM < positionX &&
+ positionX < _literal.end() &&
+ *positionX == 'x' &&
+ all_of(positionX + 1, _literal.end(), ::isdigit)
+ ) {
+ int n = parseSize(positionX + 1, _literal.end());
+ if (
+ 0 < m && m < 256 &&
+ 0 < n && n < 256 &&
+ m + n <= 256 &&
+ m % 8 == 0 &&
+ n % 8 == 0
+ ) {
+ if (keyword == Token::UFixed)
+ return make_tuple(Token::UFixed, m, n);
+ else
+ return make_tuple(Token::Fixed, m, n);
+ }
+ }
+ }
return make_tuple(Token::Identifier, 0, 0);
}
return make_tuple(keywordByName(_literal), 0, 0);
diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h
index a64eded5..31646f8d 100644
--- a/libsolidity/parsing/Token.h
+++ b/libsolidity/parsing/Token.h
@@ -143,6 +143,7 @@ namespace solidity
\
/* Keywords */ \
K(Anonymous, "anonymous", 0) \
+ K(Assembly, "assembly", 0) \
K(Break, "break", 0) \
K(Const, "constant", 0) \
K(Continue, "continue", 0) \
@@ -198,8 +199,10 @@ namespace solidity
K(String, "string", 0) \
K(Address, "address", 0) \
K(Bool, "bool", 0) \
- K(Real, "real", 0) \
- K(UReal, "ureal", 0) \
+ K(Fixed, "fixed", 0) \
+ T(FixedMxN, "fixedMxN", 0) \
+ K(UFixed, "ufixed", 0) \
+ T(UFixedMxN, "ufixedMxN", 0) \
T(TypesEnd, NULL, 0) /* used as type enum end marker */ \
\
/* Literals */ \
@@ -218,6 +221,7 @@ namespace solidity
K(Case, "case", 0) \
K(Catch, "catch", 0) \
K(Final, "final", 0) \
+ K(Inline, "inline", 0) \
K(Let, "let", 0) \
K(Match, "match", 0) \
K(Of, "of", 0) \
@@ -249,7 +253,7 @@ public:
};
#undef T
- // Returns a string corresponding to the C++ token name
+ // @returns a string corresponding to the C++ token name
// (e.g. "LT" for the token LT).
static char const* name(Value tok)
{
@@ -283,7 +287,7 @@ public:
static bool isEtherSubdenomination(Value op) { return op == SubWei || op == SubSzabo || op == SubFinney || op == SubEther; }
static bool isTimeSubdenomination(Value op) { return op == SubSecond || op == SubMinute || op == SubHour || op == SubDay || op == SubWeek || op == SubYear; }
- // 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
// have a (unique) string (e.g. an IDENTIFIER).
static char const* toString(Value tok)
@@ -292,7 +296,7 @@ public:
return m_string[tok];
}
- // Returns the precedence > 0 for binary and compare
+ // @returns the precedence > 0 for binary and compare
// operators; returns 0 otherwise.
static int precedence(Value tok)
{
@@ -300,13 +304,11 @@ public:
return m_precedence[tok];
}
- static std::tuple<Token::Value, unsigned short, unsigned short> fromIdentifierOrKeyword(std::string const& _literal);
+ static std::tuple<Token::Value, unsigned int, unsigned int> fromIdentifierOrKeyword(std::string const& _literal);
private:
- // extractM provides a safe way to extract numbers,
- // if out_of_range error is thrown, they returns 0s, therefore securing
- // the variable's identity as an identifier.
- static unsigned extractM(std::string const& _literal);
+ // @returns -1 on error (invalid digit or number too large)
+ static int parseSize(std::string::const_iterator _begin, std::string::const_iterator _end);
// @returns the keyword with name @a _name or Token::Identifier of no such keyword exists.
static Token::Value keywordByName(std::string const& _name);
static char const* const m_name[NUM_TOKENS];