Added support for FOR loops in function calls in parameters

This commit is contained in:
Clifford Wolf 2014-02-14 20:33:22 +01:00
parent 534c1a5dd0
commit e8af3def7f
3 changed files with 43 additions and 0 deletions

View File

@ -136,6 +136,7 @@ std::string AST::type2str(AstNodeType type)
X(AST_COND)
X(AST_DEFAULT)
X(AST_FOR)
X(AST_WHILE)
X(AST_GENVAR)
X(AST_GENFOR)
X(AST_GENIF)

View File

@ -116,6 +116,7 @@ namespace AST
AST_COND,
AST_DEFAULT,
AST_FOR,
AST_WHILE,
AST_GENVAR,
AST_GENFOR,

View File

@ -1891,10 +1891,51 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)
variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size());
delete block->children.front();
block->children.erase(block->children.begin());
continue;
}
if (stmt->type == AST_FOR)
{
block->children.insert(block->children.begin(), stmt->children.at(0));
stmt->children.at(3)->children.push_back(stmt->children.at(2));
stmt->children.erase(stmt->children.begin() + 2);
stmt->children.erase(stmt->children.begin());
stmt->type = AST_WHILE;
continue;
}
if (stmt->type == AST_WHILE)
{
AstNode *cond = stmt->children.at(0)->clone();
cond->replace_variables(variables, fcall);
while (cond->simplify(true, false, false, 1, -1, false, true)) { }
if (cond->type != AST_CONSTANT)
log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n",
stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
if (cond->asBool()) {
block->children.insert(block->children.begin(), stmt->children.at(1)->clone());
} else {
delete block->children.front();
block->children.erase(block->children.begin());
}
delete cond;
continue;
}
if (stmt->type == AST_BLOCK)
{
block->children.erase(block->children.begin());
block->children.insert(block->children.begin(), stmt->children.begin(), stmt->children.end());
stmt->children.clear();
delete stmt;
continue;
}
log_error("Unsupported language construct in constant function at %s:%d (called from %s:%d).\n",
stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
log_abort();