summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2014-02-14 20:33:22 +0100
committerClifford Wolf <clifford@clifford.at>2014-02-14 20:33:22 +0100
commite8af3def7fbefa1608e72609e1c534091fc7c88e (patch)
treefe733f25ccd610f439721186fdcd329912d2e84f
parent534c1a5dd009b41629d2d05acfde747ce6fbc19c (diff)
Added support for FOR loops in function calls in parameters
-rw-r--r--frontends/ast/ast.cc1
-rw-r--r--frontends/ast/ast.h1
-rw-r--r--frontends/ast/simplify.cc41
3 files changed, 43 insertions, 0 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 7e199cd5..56e9393b 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -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)
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index ec4f4f62..f42bc35f 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -116,6 +116,7 @@ namespace AST
AST_COND,
AST_DEFAULT,
AST_FOR,
+ AST_WHILE,
AST_GENVAR,
AST_GENFOR,
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 85dc1d3c..236843d5 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -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();