mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
If statement for Iulia / inline assembly.
This commit is contained in:
@@ -72,6 +72,11 @@ public:
|
||||
for (auto const& arg: _funCall.arguments)
|
||||
boost::apply_visitor(*this, arg);
|
||||
}
|
||||
void operator()(assembly::If const& _if)
|
||||
{
|
||||
boost::apply_visitor(*this, *_if.condition);
|
||||
(*this)(_if.body);
|
||||
}
|
||||
void operator()(assembly::Switch const& _switch)
|
||||
{
|
||||
boost::apply_visitor(*this, *_switch.expression);
|
||||
|
||||
@@ -286,6 +286,22 @@ bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(If const& _if)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
if (!expectExpression(*_if.condition))
|
||||
success = false;
|
||||
m_stackHeight--;
|
||||
|
||||
if (!(*this)(_if.body))
|
||||
success = false;
|
||||
|
||||
m_info.stackHeightInfo[&_if] = m_stackHeight;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(Switch const& _switch)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
@@ -70,6 +70,7 @@ public:
|
||||
bool operator()(assembly::VariableDeclaration const& _variableDeclaration);
|
||||
bool operator()(assembly::FunctionDefinition const& _functionDefinition);
|
||||
bool operator()(assembly::FunctionCall const& _functionCall);
|
||||
bool operator()(assembly::If const& _if);
|
||||
bool operator()(assembly::Switch const& _switch);
|
||||
bool operator()(assembly::ForLoop const& _forLoop);
|
||||
bool operator()(assembly::Block const& _block);
|
||||
|
||||
@@ -68,6 +68,8 @@ struct VariableDeclaration { SourceLocation location; TypedNameList variables; s
|
||||
struct Block { SourceLocation location; std::vector<Statement> statements; };
|
||||
/// Function definition ("function f(a, b) -> (d, e) { ... }")
|
||||
struct FunctionDefinition { SourceLocation location; std::string name; TypedNameList arguments; TypedNameList returns; Block body; };
|
||||
/// Conditional execution without "else" part.
|
||||
struct If { SourceLocation location; std::shared_ptr<Statement> condition; Block body; };
|
||||
/// Switch case or default case
|
||||
struct Case { SourceLocation location; std::shared_ptr<Literal> value; Block body; };
|
||||
/// Switch statement
|
||||
|
||||
@@ -41,11 +41,12 @@ struct VariableDeclaration;
|
||||
struct FunctionalInstruction;
|
||||
struct FunctionDefinition;
|
||||
struct FunctionCall;
|
||||
struct If;
|
||||
struct Switch;
|
||||
struct ForLoop;
|
||||
struct Block;
|
||||
|
||||
using Statement = boost::variant<Instruction, Literal, Label, StackAssignment, Identifier, Assignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Switch, ForLoop, Block>;
|
||||
using Statement = boost::variant<Instruction, Literal, Label, StackAssignment, Identifier, Assignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, If, Switch, ForLoop, Block>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,13 +73,23 @@ assembly::Statement Parser::parseStatement()
|
||||
return parseFunctionDefinition();
|
||||
case Token::LBrace:
|
||||
return parseBlock();
|
||||
case Token::If:
|
||||
{
|
||||
assembly::If _if = createWithLocation<assembly::If>();
|
||||
m_scanner->next();
|
||||
_if.condition = make_shared<Statement>(parseExpression());
|
||||
if (_if.condition->type() == typeid(assembly::Instruction))
|
||||
fatalParserError("Instructions are not supported as conditions for if - try to append \"()\".");
|
||||
_if.body = parseBlock();
|
||||
return _if;
|
||||
}
|
||||
case Token::Switch:
|
||||
{
|
||||
assembly::Switch _switch = createWithLocation<assembly::Switch>();
|
||||
m_scanner->next();
|
||||
_switch.expression = make_shared<Statement>(parseExpression());
|
||||
if (_switch.expression->type() == typeid(assembly::Instruction))
|
||||
fatalParserError("Instructions are not supported as expressions for switch.");
|
||||
fatalParserError("Instructions are not supported as expressions for switch - try to append \"()\".");
|
||||
while (m_scanner->currentToken() == Token::Case)
|
||||
_switch.cases.emplace_back(parseCase());
|
||||
if (m_scanner->currentToken() == Token::Default)
|
||||
|
||||
@@ -174,6 +174,11 @@ string AsmPrinter::operator()(assembly::FunctionCall const& _functionCall)
|
||||
")";
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(If const& _if)
|
||||
{
|
||||
return "if " + boost::apply_visitor(*this, *_if.condition) + "\n" + (*this)(_if.body);
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(Switch const& _switch)
|
||||
{
|
||||
string out = "switch " + boost::apply_visitor(*this, *_switch.expression);
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
std::string operator()(assembly::VariableDeclaration const& _variableDeclaration);
|
||||
std::string operator()(assembly::FunctionDefinition const& _functionDefinition);
|
||||
std::string operator()(assembly::FunctionCall const& _functionCall);
|
||||
std::string operator()(assembly::If const& _if);
|
||||
std::string operator()(assembly::Switch const& _switch);
|
||||
std::string operator()(assembly::ForLoop const& _forLoop);
|
||||
std::string operator()(assembly::Block const& _block);
|
||||
|
||||
@@ -104,6 +104,11 @@ bool ScopeFiller::operator()(assembly::FunctionDefinition const& _funDef)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ScopeFiller::operator()(If const& _if)
|
||||
{
|
||||
return (*this)(_if.body);
|
||||
}
|
||||
|
||||
bool ScopeFiller::operator()(Switch const& _switch)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
bool operator()(assembly::VariableDeclaration const& _variableDeclaration);
|
||||
bool operator()(assembly::FunctionDefinition const& _functionDefinition);
|
||||
bool operator()(assembly::FunctionCall const&) { return true; }
|
||||
bool operator()(assembly::If const& _if);
|
||||
bool operator()(assembly::Switch const& _switch);
|
||||
bool operator()(assembly::ForLoop const& _forLoop);
|
||||
bool operator()(assembly::Block const& _block);
|
||||
|
||||
Reference in New Issue
Block a user