From edd0afa3c35475990bacd8ffe64d15b3be40a036 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 2 May 2017 18:26:33 +0100 Subject: Support true/false literals in inline assembly --- libsolidity/inlineasm/AsmAnalysis.cpp | 2 +- libsolidity/inlineasm/AsmCodeGen.cpp | 9 ++++++++- libsolidity/inlineasm/AsmData.h | 3 ++- libsolidity/inlineasm/AsmParser.cpp | 23 ++++++++++++++++++++++- libsolidity/inlineasm/AsmPrinter.cpp | 10 +++++++++- 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 590f9ad6..e03eea2e 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -72,7 +72,7 @@ bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction) bool AsmAnalyzer::operator()(assembly::Literal const& _literal) { ++m_stackHeight; - if (!_literal.isNumber && _literal.value.size() > 32) + if (_literal.kind == assembly::LiteralKind::String && _literal.value.size() > 32) { m_errors.push_back(make_shared( Error::Type::TypeError, diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libsolidity/inlineasm/AsmCodeGen.cpp index 137a70f5..44e12b3e 100644 --- a/libsolidity/inlineasm/AsmCodeGen.cpp +++ b/libsolidity/inlineasm/AsmCodeGen.cpp @@ -118,8 +118,15 @@ public: void operator()(assembly::Literal const& _literal) { m_state.assembly.setSourceLocation(_literal.location); - if (_literal.isNumber) + if (_literal.kind == assembly::LiteralKind::Number) m_state.assembly.append(u256(_literal.value)); + else if (_literal.kind == assembly::LiteralKind::Boolean) + { + if (_literal.value == "true") + m_state.assembly.append(u256(1)); + else + m_state.assembly.append(u256(0)); + } else { solAssert(_literal.value.size() <= 32, ""); diff --git a/libsolidity/inlineasm/AsmData.h b/libsolidity/inlineasm/AsmData.h index 363873ab..8efe1f07 100644 --- a/libsolidity/inlineasm/AsmData.h +++ b/libsolidity/inlineasm/AsmData.h @@ -43,7 +43,8 @@ using TypedNameList = std::vector; /// Direct EVM instruction (except PUSHi and JUMPDEST) struct Instruction { SourceLocation location; solidity::Instruction instruction; }; /// Literal number or string (up to 32 bytes) -struct Literal { SourceLocation location; bool isNumber; std::string value; Type type; }; +enum class LiteralKind { Number, Boolean, String }; +struct Literal { SourceLocation location; LiteralKind kind; std::string value; Type type; }; /// External / internal identifier or label reference struct Identifier { SourceLocation location; std::string name; }; struct FunctionalInstruction; diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 7ecad5ea..079b9352 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -206,10 +206,29 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) } case Token::StringLiteral: case Token::Number: + case Token::TrueLiteral: + case Token::FalseLiteral: { + LiteralKind kind = LiteralKind::Number; + switch (m_scanner->currentToken()) + { + case Token::StringLiteral: + kind = LiteralKind::String; + break; + case Token::Number: + kind = LiteralKind::Number; + break; + case Token::TrueLiteral: + case Token::FalseLiteral: + kind = LiteralKind::Boolean; + break; + default: + break; + } + Literal literal{ location(), - m_scanner->currentToken() == Token::Number, + kind, m_scanner->currentLiteral(), "" }; @@ -220,6 +239,8 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) literal.location.end = endPosition(); literal.type = expectAsmIdentifier(); } + else if (kind == LiteralKind::Boolean) + fatalParserError("True and false are not valid literals."); ret = std::move(literal); break; } diff --git a/libsolidity/inlineasm/AsmPrinter.cpp b/libsolidity/inlineasm/AsmPrinter.cpp index f3b66aee..636e61b8 100644 --- a/libsolidity/inlineasm/AsmPrinter.cpp +++ b/libsolidity/inlineasm/AsmPrinter.cpp @@ -46,8 +46,16 @@ string AsmPrinter::operator()(assembly::Instruction const& _instruction) string AsmPrinter::operator()(assembly::Literal const& _literal) { - if (_literal.isNumber) + switch (_literal.kind) + { + case LiteralKind::Number: return _literal.value + appendTypeName(_literal.type); + case LiteralKind::Boolean: + return ((_literal.value == "true") ? "true" : "false") + appendTypeName(_literal.type); + case LiteralKind::String: + break; + } + string out; for (char c: _literal.value) if (c == '\\') -- cgit From 2ade4fcdd80cdb12ef12cf929021f64d20de53d2 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 17 May 2017 13:20:24 +0100 Subject: Add tests for bool literal --- test/libjulia/Parser.cpp | 6 ++++++ test/libsolidity/InlineAssembly.cpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/test/libjulia/Parser.cpp b/test/libjulia/Parser.cpp index c401f57b..d1081067 100644 --- a/test/libjulia/Parser.cpp +++ b/test/libjulia/Parser.cpp @@ -120,6 +120,12 @@ BOOST_AUTO_TEST_CASE(vardecl) BOOST_CHECK(successParse("{ let x:u256 := 7:u256 }")); } +BOOST_AUTO_TEST_CASE(vardecl_bool) +{ + BOOST_CHECK(successParse("{ let x:bool := true:bool }")); + BOOST_CHECK(successParse("{ let x:bool := false:bool }")); +} + BOOST_AUTO_TEST_CASE(assignment) { BOOST_CHECK(successParse("{ let x:u256 := 2:u256 let y:u256 := x }")); diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index b7046f80..0729c8db 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -161,6 +161,12 @@ BOOST_AUTO_TEST_CASE(vardecl) BOOST_CHECK(successParse("{ let x := 7 }")); } +BOOST_AUTO_TEST_CASE(vardecl_bool) +{ + CHECK_PARSE_ERROR("{ let x := true }", ParserError, "True and false are not valid literals."); + CHECK_PARSE_ERROR("{ let x := false }", ParserError, "True and false are not valid literals."); +} + BOOST_AUTO_TEST_CASE(assignment) { BOOST_CHECK(successParse("{ let x := 2 7 8 add =: x }")); -- cgit From ebcb27e5c14549d114c116889c730c3a8cd82a86 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 17 May 2017 13:33:05 +0100 Subject: Accept bool as a type in Julia mode --- libsolidity/inlineasm/AsmParser.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 079b9352..a96984f5 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -381,7 +381,15 @@ TypedName Parser::parseTypedName() string Parser::expectAsmIdentifier() { string name = m_scanner->currentLiteral(); - if (!m_julia && instructions().count(name)) + if (m_julia) + { + if (m_scanner->currentToken() == Token::Bool) + { + m_scanner->next(); + return name; + } + } + else if (instructions().count(name)) fatalParserError("Cannot use instruction names for identifier names."); expectToken(Token::Identifier); return name; -- cgit