namespace solidity { #define T(name, string, precedence) #name, char const* const Token::m_name[NUM_TOKENS] = { TOKEN_LIST(T, T) }; #undef T #define T(name, string, precedence) string, char const* const Token::m_string[NUM_TOKENS] = { TOKEN_LIST(T, T) }; #undef T #define T(name, string, precedence) precedence, int8_t const Token::m_precedence[NUM_TOKENS] = { TOKEN_LIST(T, T) }; #undef T #define KT(a, b, c) 'T', #define KK(a, b, c) 'K', char const Token::m_tokenType[] = { TOKEN_LIST(KT, KK) }; Token::Value Token::fromIdentifierOrKeyword(const std::string& _name) { // The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored // and keywords to be put inside the keywords variable. #define KEYWORD(name, string, precedence) {string, Token::name}, #define TOKEN(name, string, precedence) static const map<string, Token::Value> keywords({TOKEN_LIST(TOKEN, KEYWORD)}); #undef KEYWORD #undef TOKEN auto it = keywords.find(_name); return it == keywords.end() ? Token::Identifier : it->second; } #undef KT #undef KK }
Token::Value Token::fromIdentifierOrKeyword(const std::string& _name) { // The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored // and keywords to be put inside the keywords variable. #define KEYWORD(name, string, precedence) {string, Token::name}, #define TOKEN(name, string, precedence) static const map<string, Token::Value> keywords({TOKEN_LIST(TOKEN, KEYWORD)}); #undef KEYWORD #undef TOKEN auto it = keywords.find(_name); return it == keywords.end() ? Token::Identifier : it->second; }
namespace solidity { #define T(name, string, precedence) #name, char const* const Token::m_name[NUM_TOKENS] = { TOKEN_LIST(T, T) }; #undef T #define T(name, string, precedence) string, char const* const Token::m_string[NUM_TOKENS] = { TOKEN_LIST(T, T) }; #undef T #define T(name, string, precedence) precedence, int8_t const Token::m_precedence[NUM_TOKENS] = { TOKEN_LIST(T, T) }; #undef T #define KT(a, b, c) 'T', #define KK(a, b, c) 'K', char const Token::m_tokenType[] = { TOKEN_LIST(KT, KK) }; #undef KT #undef KK }
namespace solidity { void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned const& _first, unsigned const& _second) { solAssert(Token::isElementaryTypeName(_baseType), ""); if (_baseType == Token::BytesM) { solAssert(_second == 0, "There should not be a second size argument to type bytesM."); solAssert(_first <= 32, "No elementary type bytes" + to_string(_first) + "."); } else if (_baseType == Token::UIntM || _baseType == Token::IntM) { solAssert(_second == 0, "There should not be a second size argument to type " + string(Token::toString(_baseType)) + "."); solAssert( _first <= 256 && _first % 8 == 0, "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; } #define T(name, string, precedence) #name, char const* const Token::m_name[NUM_TOKENS] = { TOKEN_LIST(T, T) }; #undef T #define T(name, string, precedence) string, char const* const Token::m_string[NUM_TOKENS] = { TOKEN_LIST(T, T) }; #undef T #define T(name, string, precedence) precedence, int8_t const Token::m_precedence[NUM_TOKENS] = { TOKEN_LIST(T, T) }; #undef T #define KT(a, b, c) 'T', #define KK(a, b, c) 'K', char const Token::m_tokenType[] = { TOKEN_LIST(KT, KK) }; int Token::parseSize(string::const_iterator _begin, string::const_iterator _end) { try { unsigned int m = boost::lexical_cast<int>(boost::make_iterator_range(_begin, _end)); return m; } catch(boost::bad_lexical_cast const&) { return -1; } } 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); int m = parseSize(positionM, positionX); Token::Value keyword = keywordByName(baseType); if (keyword == Token::Bytes) { if (0 < m && m <= 32 && positionX == _literal.end()) return make_tuple(Token::BytesM, m, 0); } else if (keyword == Token::UInt || keyword == Token::Int) { if (0 < m && m <= 256 && m % 8 == 0 && positionX == _literal.end()) { if (keyword == Token::UInt) return make_tuple(Token::UIntM, m, 0); else 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 && 8 <= n && n <= 256 && m + n > 0 && m + n <= 256 && m % 8 == 0 && n % 8 == 0 ) { if (keyword == Token::UFixed) return make_tuple(Token::UFixedMxN, m, n); else return make_tuple(Token::FixedMxN, m, n); } } } return make_tuple(Token::Identifier, 0, 0); } return make_tuple(keywordByName(_literal), 0, 0); } Token::Value Token::keywordByName(string const& _name) { // The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored // and keywords to be put inside the keywords variable. #define KEYWORD(name, string, precedence) {string, Token::name}, #define TOKEN(name, string, precedence) static const map<string, Token::Value> keywords({TOKEN_LIST(TOKEN, KEYWORD)}); #undef KEYWORD #undef TOKEN auto it = keywords.find(_name); return it == keywords.end() ? Token::Identifier : it->second; } #undef KT #undef KK }
void CAstNode::Expose(void) { py::class_<CAstScope>("AstScope", py::no_init) .add_property("isEval", &CAstScope::IsEval) .add_property("isFunc", &CAstScope::IsFunction) .add_property("isGlobal", &CAstScope::IsGlobal) .add_property("callsEval", &CAstScope::CallsEval) .add_property("outerScopeCallsEval", &CAstScope::OuterScopeCallsEval) .add_property("insideWith", &CAstScope::InsideWith) .add_property("containsWith", &CAstScope::ContainsWith) .add_property("outer", &CAstScope::GetOuter) .add_property("declarations", &CAstScope::GetDeclarations) .add_property("num_parameters", &CAstScope::GetParametersNumer) .def("parameter", &CAstScope::GetParameter, (py::args("index"))) ; py::enum_<v8i::VariableMode>("AstVariableMode") .value("var", v8i::VAR) .value("const", v8i::CONST) .value("let", v8i::LET) .value("dynamic", v8i::DYNAMIC) .value("global", v8i::DYNAMIC_GLOBAL) .value("local", v8i::DYNAMIC_LOCAL) .value("internal", v8i::INTERNAL) .value("temporary", v8i::TEMPORARY) ; py::enum_<v8i::Variable::Location>("AstVariableLocation") .value("UNALLOCATED", v8i::Variable::UNALLOCATED) .value("PARAMETER", v8i::Variable::PARAMETER) .value("LOCAL", v8i::Variable::LOCAL) .value("CONTEXT", v8i::Variable::CONTEXT) .value("LOOKUP", v8i::Variable::LOOKUP) ; py::class_<CAstVariable>("AstVariable", py::no_init) .add_property("scope", &CAstVariable::scope) .add_property("name", &CAstVariable::name) .add_property("mode", &CAstVariable::mode) .add_property("isValidLeftHandSide", &CAstVariable::IsValidLeftHandSide) .add_property("isThis", &CAstVariable::is_this) .add_property("isArguments", &CAstVariable::is_arguments) .add_property("isPossiblyEval", &CAstVariable::is_possibly_eval) .add_property("location", &CAstVariable::location) .add_property("index", &CAstVariable::index) ; py::class_<CAstLabel>("AstLabel", py::no_init) .add_property("pos", &CAstLabel::GetPosition) .add_property("bound", &CAstLabel::IsBound) .add_property("unused", &CAstLabel::IsUnused) .add_property("linked", &CAstLabel::IsLinked) ; #define DECLARE_TYPE_ENUM(type) .value(#type, v8i::AstNode::k##type) py::enum_<v8i::AstNode::NodeType>("AstNodeType") AST_NODE_LIST(DECLARE_TYPE_ENUM) .value("Invalid", v8i::AstNode::kInvalid) ; py::class_<CAstNode, boost::noncopyable>("AstNode", py::no_init) .add_property("type", &CAstNode::GetType) .add_property("pos", &CAstStatement::GetPosition) .def("visit", &CAstNode::Visit, (py::arg("handler"))) .def("__str__", &CAstNode::ToString) ; py::class_<CAstStatement, py::bases<CAstNode> >("AstStatement", py::no_init) .def("__nonzero__", &CAstStatement::operator bool) ; py::class_<CAstExpression, py::bases<CAstNode> >("AstExpression", py::no_init) .add_property("isPropertyName", &CAstExpression::IsPropertyName) .add_property("isSmi", &CAstExpression::IsSmiLiteral) .add_property("isString", &CAstExpression::IsStringLiteral) .add_property("isNull", &CAstExpression::IsNullLiteral) ; py::class_<CAstBreakableStatement, py::bases<CAstStatement> >("AstBreakableStatement", py::no_init) .add_property("anonymous", &CAstBreakableStatement::IsTargetForAnonymous) .add_property("breakTarget", &CAstBreakableStatement::GetBreakTarget) ; py::class_<CAstBlock, py::bases<CAstBreakableStatement> >("AstBlock", py::no_init) .add_property("statements", &CAstBlock::GetStatements) .add_property("initializerBlock", &CAstBlock::IsInitializerBlock) .def("addStatement", &CAstBlock::AddStatement) ; py::class_<CAstDeclaration, py::bases<CAstNode> >("AstDeclaration", py::no_init) .add_property("proxy", &CAstDeclaration::GetProxy) .add_property("mode", &CAstDeclaration::GetMode) .add_property("scope", &CAstDeclaration::GetScope) ; py::class_<CAstVariableDeclaration, py::bases<CAstDeclaration> >("AstVariableDeclaration", py::no_init) ; py::class_<CAstFunctionDeclaration, py::bases<CAstDeclaration> >("AstFunctionDeclaration", py::no_init) .add_property("function", &CAstFunctionDeclaration::GetFunction) ; py::class_<CAstModule, py::bases<CAstNode> >("AstModule", py::no_init) ; py::class_<CAstModuleDeclaration, py::bases<CAstDeclaration> >("AstModuleDeclaration", py::no_init) .add_property("module", &CAstModuleDeclaration::GetModule) ; py::class_<CAstImportDeclaration, py::bases<CAstDeclaration> >("AstImportDeclaration", py::no_init) .add_property("module", &CAstImportDeclaration::GetModule) ; py::class_<CAstExportDeclaration, py::bases<CAstDeclaration> >("AstExportDeclaration", py::no_init) ; py::class_<CAstModuleLiteral, py::bases<CAstModule> >("AstModuleLiteral", py::no_init) .add_property("body", &CAstModuleLiteral::GetBody) ; py::class_<CAstModuleVariable, py::bases<CAstModule> >("AstModuleVariable", py::no_init) .add_property("proxy", &CAstModuleVariable::GetProxy) ; py::class_<CAstModulePath, py::bases<CAstModule> >("AstModulePath", py::no_init) .add_property("module", &CAstModulePath::GetModule) .add_property("name", &CAstModulePath::GetName) ; py::class_<CAstIterationStatement, py::bases<CAstBreakableStatement> >("AstIterationStatement", py::no_init) .add_property("body", &CAstIterationStatement::GetBody) .add_property("continueTarget", &CAstIterationStatement::GetContinueTarget) ; py::class_<CAstDoWhileStatement, py::bases<CAstIterationStatement> >("AstDoWhileStatement", py::no_init) .add_property("condition", &CAstDoWhileStatement::GetCondition) ; py::class_<CAstWhileStatement, py::bases<CAstIterationStatement> >("AstWhileStatement", py::no_init) .add_property("condition", &CAstWhileStatement::GetCondition) ; py::class_<CAstForStatement, py::bases<CAstIterationStatement> >("AstForStatement", py::no_init) .add_property("init", &CAstForStatement::GetInit) .add_property("condition", &CAstForStatement::GetCondition) .add_property("nextStmt", &CAstForStatement::GetNext) .add_property("fastLoop", &CAstForStatement::IsFastLoop) ; py::class_<CAstForEachStatement, py::bases<CAstIterationStatement> >("AstForEachStatement", py::no_init) .add_property("each", &CAstForEachStatement::GetEach) .add_property("subject", &CAstForEachStatement::GetSubject) ; py::class_<CAstForInStatement, py::bases<CAstForEachStatement> >("AstForInStatement", py::no_init) .add_property("enumerable", &CAstForInStatement::GetEnumerable) ; py::class_<CAstForOfStatement, py::bases<CAstForEachStatement> >("AstForOfStatement", py::no_init) .add_property("iterable", &CAstForOfStatement::GetIterable) .add_property("assignIterator", &CAstForOfStatement::AssignIterator) .add_property("next", &CAstForOfStatement::NextResult) .add_property("done", &CAstForOfStatement::ResultDone) .add_property("assignEach", &CAstForOfStatement::AssignEach) ; py::class_<CAstExpressionStatement, py::bases<CAstStatement> >("AstExpressionStatement", py::no_init) .add_property("expression", &CAstExpressionStatement::GetExpression) ; py::class_<CAstContinueStatement, py::bases<CAstStatement> >("AstContinueStatement", py::no_init) .add_property("target", &CAstContinueStatement::GetTarget) ; py::class_<CAstBreakStatement, py::bases<CAstStatement> >("AstBreakStatement", py::no_init) .add_property("target", &CAstBreakStatement::GetTarget) ; py::class_<CAstReturnStatement, py::bases<CAstStatement> >("AstReturnStatement", py::no_init) .add_property("expression", &CAstReturnStatement::expression) ; py::class_<CAstWithStatement, py::bases<CAstStatement> >("AstWithStatement", py::no_init) .add_property("expression", &CAstWithStatement::expression) .add_property("statement", &CAstWithStatement::statement) ; py::class_<CAstCaseClause, py::bases<CAstNode> >("AstCaseClause", py::no_init) .add_property("isDefault", &CAstCaseClause::is_default) .add_property("label", &CAstCaseClause::label) .add_property("bodyTarget", &CAstCaseClause::body_target) .add_property("statements", &CAstCaseClause::statements) ; py::class_<CAstSwitchStatement, py::bases<CAstBreakableStatement> >("AstSwitchStatement", py::no_init) .add_property("tag", &CAstSwitchStatement::tag) .add_property("cases", &CAstSwitchStatement::cases) ; py::class_<CAstIfStatement, py::bases<CAstStatement> >("AstIfStatement", py::no_init) .add_property("hasThenStatement", &CAstIfStatement::HasThenStatement) .add_property("hasElseStatement", &CAstIfStatement::HasElseStatement) .add_property("condition", &CAstIfStatement::GetCondition) .add_property("thenStatement", &CAstIfStatement::GetThenStatement) .add_property("elseStatement", &CAstIfStatement::GetElseStatement) ; py::class_<CAstTargetCollector, py::bases<CAstNode> >("AstTargetCollector", py::no_init) .add_property("targets", &CAstTargetCollector::GetTargets) ; py::class_<CAstTryStatement, py::bases<CAstStatement> >("AstTryStatement", py::no_init) .add_property("tryBlock", &CAstTryStatement::GetTryBlock) .add_property("targets", &CAstTryStatement::GetEscapingTargets) ; py::class_<CAstTryCatchStatement, py::bases<CAstTryStatement> >("AstTryCatchStatement", py::no_init) .add_property("scope", &CAstTryCatchStatement::GetScope) .add_property("variable", &CAstTryCatchStatement::GetVariable) .add_property("catchBlock", &CAstTryCatchStatement::GetCatchBlock) ; py::class_<CAstTryFinallyStatement, py::bases<CAstTryStatement> >("AstTryFinallyStatement", py::no_init) .add_property("finallyBlock", &CAstTryFinallyStatement::GetFinallyBlock) ; py::class_<CAstDebuggerStatement, py::bases<CAstStatement> >("AstDebuggerStatement", py::no_init) ; py::class_<CAstEmptyStatement, py::bases<CAstStatement> >("AstEmptyStatement", py::no_init) ; py::class_<CAstLiteral, py::bases<CAstExpression> >("AstLiteral", py::no_init) .add_property("isNull", &CAstLiteral::IsNull) .add_property("isTrue", &CAstLiteral::IsTrue) .add_property("isFalse", &CAstLiteral::IsFalse) .add_property("asPropertyName", &CAstLiteral::AsPropertyName) ; py::class_<CAstMaterializedLiteral, py::bases<CAstExpression> >("AstMaterializedLiteral", py::no_init) .add_property("index", &CAstMaterializedLiteral::GetIndex) ; py::enum_<v8i::ObjectLiteral::Property::Kind>("AstPropertyKind") .value("constant", v8i::ObjectLiteral::Property::CONSTANT) .value("computed", v8i::ObjectLiteral::Property::COMPUTED) .value("materialized", v8i::ObjectLiteral::Property::MATERIALIZED_LITERAL) .value("getter", v8i::ObjectLiteral::Property::GETTER) .value("setter", v8i::ObjectLiteral::Property::SETTER) .value("prototype", v8i::ObjectLiteral::Property::PROTOTYPE) ; py::class_<CAstObjectProperty>("AstObjectProperty", py::no_init) .add_property("key", &CAstObjectProperty::GetKey) .add_property("value", &CAstObjectProperty::GetValue) .add_property("kind", &CAstObjectProperty::GetKind) .add_property("isCompileTimeValue", &CAstObjectProperty::IsCompileTimeValue) ; py::class_<CAstObjectLiteral, py::bases<CAstMaterializedLiteral> >("AstObjectLiteral", py::no_init) .add_property("properties", &CAstObjectLiteral::GetProperties) ; py::class_<CAstRegExpLiteral, py::bases<CAstMaterializedLiteral> >("AstRegExpLiteral", py::no_init) .add_property("pattern", &CAstRegExpLiteral::GetPattern) .add_property("flags", &CAstRegExpLiteral::GetFlags) ; py::class_<CAstArrayLiteral, py::bases<CAstMaterializedLiteral> >("AstArrayLiteral", py::no_init) .add_property("values", &CAstArrayLiteral::GetValues) ; py::class_<CAstVariableProxy, py::bases<CAstExpression> >("AstVariableProxy", py::no_init) .add_property("isValidLeftHandSide", &CAstVariableProxy::IsValidLeftHandSide) .add_property("isArguments", &CAstVariableProxy::IsArguments) .add_property("name", &CAstVariableProxy::name) .add_property("var", &CAstVariableProxy::var) .add_property("isThis", &CAstVariableProxy::is_this) ; py::class_<CAstProperty, py::bases<CAstExpression> >("AstProperty", py::no_init) ; py::class_<CAstCall, py::bases<CAstExpression> >("AstCall", py::no_init) .add_property("expression", &CAstCall::GetExpression) .add_property("args", &CAstCall::GetArguments) ; py::class_<CAstCallNew, py::bases<CAstExpression> >("AstCallNew", py::no_init) .add_property("expression", &CAstCallNew::GetExpression) .add_property("args", &CAstCallNew::GetArguments) ; py::class_<CAstCallRuntime, py::bases<CAstExpression> >("AstCallRuntime", py::no_init) .add_property("name", &CAstCallRuntime::GetName) .add_property("args", &CAstCallRuntime::GetArguments) .add_property("isJsRuntime", &CAstCallRuntime::IsJSRuntime) ; py::enum_<v8i::Token::Value>("AstOperation") #define T(name, string, precedence) .value(#name, v8i::Token::name) TOKEN_LIST(T, IGNORE_TOKEN) #undef T ; py::class_<CAstUnaryOperation, py::bases<CAstExpression> >("AstUnaryOperation", py::no_init) .add_property("op", &CAstUnaryOperation::op) .add_property("expression", &CAstUnaryOperation::expression) ; py::class_<CAstBinaryOperation, py::bases<CAstExpression> >("AstBinaryOperation", py::no_init) .add_property("op", &CAstBinaryOperation::op) .add_property("left", &CAstBinaryOperation::left) .add_property("right", &CAstBinaryOperation::right) ; py::class_<CAstCountOperation, py::bases<CAstExpression> >("AstCountOperation", py::no_init) .add_property("prefix", &CAstCountOperation::is_prefix) .add_property("postfix", &CAstCountOperation::is_postfix) .add_property("op", &CAstCountOperation::op) .add_property("binop", &CAstCountOperation::binary_op) .add_property("expression", &CAstCountOperation::expression) ; py::class_<CAstCompareOperation, py::bases<CAstExpression> >("AstCompareOperation", py::no_init) .add_property("op", &CAstCompareOperation::op) .add_property("left", &CAstCompareOperation::left) .add_property("right", &CAstCompareOperation::right) ; py::class_<CAstConditional, py::bases<CAstExpression> >("AstConditional", py::no_init) .add_property("condition", &CAstConditional::condition) .add_property("thenExpr", &CAstConditional::then_expression) .add_property("elseExpr", &CAstConditional::else_expression) ; py::class_<CAstAssignment, py::bases<CAstExpression> >("AstAssignment", py::no_init) .add_property("op", &CAstAssignment::op) .add_property("binop", &CAstAssignment::binary_op) .add_property("target", &CAstAssignment::target) .add_property("value", &CAstAssignment::value) .add_property("binOperation", &CAstAssignment::binary_operation) .add_property("compound", &CAstAssignment::is_compound) ; py::enum_<v8i::Yield::Kind>("AstYieldKind") .value("initial", v8i::Yield::INITIAL) .value("suspend", v8i::Yield::SUSPEND) .value("delegating", v8i::Yield::DELEGATING) .value("final", v8i::Yield::FINAL) ; py::class_<CAstYield, py::bases<CAstExpression> >("AstYield", py::no_init) .add_property("expression", &CAstYield::expression) .add_property("kind", &CAstYield::yield_kind) ; py::class_<CAstThrow, py::bases<CAstExpression> >("AstThrow", py::no_init) .add_property("exception", &CAstThrow::GetException) ; py::class_<CAstFunctionLiteral, py::bases<CAstExpression> >("AstFunctionLiteral", py::no_init) .add_property("name", &CAstFunctionLiteral::GetName) .add_property("scope", &CAstFunctionLiteral::GetScope) .add_property("body", &CAstFunctionLiteral::GetBody) .add_property("startPos", &CAstFunctionLiteral::GetStartPosition) .add_property("endPos", &CAstFunctionLiteral::GetEndPosition) .add_property("isExpression", &CAstFunctionLiteral::IsExpression) .def("toAST", &CAstFunctionLiteral::ToAST) .def("toJSON", &CAstFunctionLiteral::ToJSON) ; py::class_<CAstNativeFunctionLiteral, py::bases<CAstExpression> >("AstNativeFunctionLiteral", py::no_init) ; py::class_<CAstThisFunction, py::bases<CAstExpression> >("AstThisFunction", py::no_init) ; }