Internals: Add AstSFormatF

This commit is contained in:
Wilson Snyder 2010-01-17 15:53:12 -05:00
parent 788f69a8c9
commit 0d1de96dbc
12 changed files with 66 additions and 65 deletions

View File

@ -61,12 +61,12 @@ private:
}
void replaceDisplay(AstDisplay* nodep, const string& prefix) {
nodep->displayType(AstDisplayType::WRITE);
nodep->text(assertDisplayMessage(nodep, prefix, nodep->text()));
AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack();
nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text()));
AstNode* timesp = nodep->fmtp()->exprsp(); if (timesp) timesp->unlinkFrBack();
timesp = timesp->addNext(new AstTime(nodep->fileline()));
nodep->exprsp(timesp);
if (!nodep->scopeNamep() && nodep->formatScopeTracking()) {
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
nodep->fmtp()->exprsp(timesp);
if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) {
nodep->fmtp()->scopeNamep(new AstScopeName(nodep->fileline()));
}
}

View File

@ -1194,26 +1194,6 @@ public:
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
};
class AstNodeDisplay : public AstNodeStmt {
// AstDisplay, AstSFormat or anything else with a format that might have %m
string m_text;
public:
AstNodeDisplay(FileLine* fl, const string& text, AstNode* exprsp)
: AstNodeStmt(fl), m_text(text) {
addNOp1p(exprsp); addNOp2p(NULL); }
ASTNODE_BASE_FUNCS(NodeDisplay)
virtual string name() const { return m_text; }
virtual int instrCount() const { return instrCountPli(); }
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
string text() const { return m_text; } // * = Text to display
void text(const string& text) { m_text=text; }
AstScopeName* scopeNamep() const { return op2p()->castScopeName(); }
void scopeNamep(AstNode* nodep) { setNOp2p(nodep); }
bool formatScopeTracking() const { // Track scopeNamep(); Ok if over-eager
return (name().find("%m") != string::npos || name().find("%M") != string::npos); }
};
struct AstNodeText : public AstNode {
private:
string m_text;

View File

@ -1506,14 +1506,38 @@ public:
void ignoreOverlap(bool flag) { m_ignoreOverlap = flag; }
};
struct AstDisplay : public AstNodeDisplay {
class AstSFormatF : public AstNode {
// Convert format to string, generally under a AstDisplay or AstSFormat
string m_text;
public:
AstSFormatF(FileLine* fl, const string& text, AstNode* exprsp)
: AstNode(fl), m_text(text) {
addNOp1p(exprsp); addNOp2p(NULL); }
ASTNODE_NODE_FUNCS(SFormatF, SFORMATF)
virtual string name() const { return m_text; }
virtual int instrCount() const { return instrCountPli(); }
virtual V3Hash sameHash() const { return V3Hash(text()); }
virtual bool same(AstNode* samep) const { return text()==samep->castSFormatF()->text(); }
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
string text() const { return m_text; } // * = Text to display
void text(const string& text) { m_text=text; }
AstScopeName* scopeNamep() const { return op2p()->castScopeName(); }
void scopeNamep(AstNode* nodep) { setNOp2p(nodep); }
bool formatScopeTracking() const { // Track scopeNamep(); Ok if false positive
return (name().find("%m") != string::npos || name().find("%M") != string::npos); }
};
struct AstDisplay : public AstNode {
// Parents: stmtlist
// Children: file which must be a varref, MATH to print
// Children: file which must be a varref
// Children: SFORMATF to generate print string
private:
AstDisplayType m_displayType;
public:
AstDisplay(FileLine* fileline, AstDisplayType dispType, const string& text, AstNode* filep, AstNode* exprsp)
: AstNodeDisplay (fileline, text, exprsp) {
: AstNode (fileline) {
setNOp1p(new AstSFormatF(fileline,text,exprsp));
setNOp3p(filep);
m_displayType = dispType;
}
@ -1526,24 +1550,25 @@ public:
virtual bool isSplittable() const { return false; } // SPECIAL: $display has 'visual' ordering
virtual bool isOutputter() const { return true; } // SPECIAL: $display makes output
virtual bool isUnlikely() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(text()); }
virtual bool same(AstNode* samep) const {
return displayType()==samep->castDisplay()->displayType()
&& text()==samep->castDisplay()->text(); }
// op1,op2 used by AstNodeDisplay
virtual V3Hash sameHash() const { return V3Hash(displayType()); }
virtual bool same(AstNode* samep) const { return displayType()==samep->castDisplay()->displayType(); }
virtual int instrCount() const { return instrCountPli(); }
AstDisplayType displayType() const { return m_displayType; }
void displayType(AstDisplayType type) { m_displayType = type; }
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter
AstSFormatF* fmtp() const { return op1p()->castSFormatF(); }
AstNode* filep() const { return op3p(); }
void filep(AstNodeVarRef* nodep) { setNOp3p(nodep); }
};
struct AstSFormat : public AstNodeDisplay {
struct AstSFormat : public AstNode {
// Parents: statement container
// Children: string to load
// Children: varrefs to print
// Children: SFORMATF to generate print string
AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp)
: AstNodeDisplay (fileline, text, exprsp) {
: AstNode (fileline) {
setOp1p(new AstSFormatF(fileline,text,exprsp));
setOp3p(lhsp);
}
ASTNODE_NODE_FUNCS(SFormat, SFORMAT)
@ -1555,10 +1580,11 @@ struct AstSFormat : public AstNodeDisplay {
virtual bool isSplittable() const { return true; }
virtual bool isOutputter() const { return false; }
virtual bool cleanOut() { return false; }
virtual V3Hash sameHash() const { return V3Hash(text()); }
virtual bool same(AstNode* samep) const {
return text()==samep->castSFormat()->text(); }
// op1,op2 used by AstNodeDisplay
virtual int instrCount() const { return instrCountPli(); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter
AstSFormatF* fmtp() const { return op1p()->castSFormatF(); }
AstNode* lhsp() const { return op3p(); }
void lhsp(AstNode* nodep) { setOp3p(nodep); }
};

View File

@ -240,7 +240,7 @@ private:
nodep->iterateChildren(*this);
insureClean(nodep->condp());
}
virtual void visit(AstNodeDisplay* nodep, AstNUser*) {
virtual void visit(AstSFormatF* nodep, AstNUser*) {
nodep->iterateChildren(*this);
insureCleanAndNext (nodep->exprsp());
}

View File

@ -1404,7 +1404,7 @@ private:
}
}
virtual void visit(AstNodeDisplay* nodep, AstNUser*) {
virtual void visit(AstSFormatF* nodep, AstNUser*) {
// Substitute constants into displays. The main point of this is to
// simplify assertion methodologies which call functions with display's.
// This eliminates a pile of wide temps, and makes the C a whole lot more readable.

View File

@ -63,7 +63,8 @@ public:
&& v3Global.opt.outputSplit() < splitSize()); }
// METHODS
void displayNode(AstNode* nodep, const string& vformat, AstNode* exprsp, bool isScan);
void displayNode(AstNode* nodep, AstScopeName* scopenamep,
const string& vformat, AstNode* exprsp, bool isScan);
void displayEmit(AstNode* nodep, bool isScan);
void displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
string vfmt, char fmtLetter);
@ -203,9 +204,9 @@ public:
puts(");\n");
}
virtual void visit(AstDisplay* nodep, AstNUser*) {
string text = nodep->text();
string text = nodep->fmtp()->text();
if (nodep->addNewline()) text += "\n";
displayNode(nodep, text, nodep->exprsp(), false);
displayNode(nodep, nodep->fmtp()->scopeNamep(), text, nodep->fmtp()->exprsp(), false);
}
virtual void visit(AstScopeName* nodep, AstNUser*) {
// For use under AstCCalls for dpiImports. ScopeNames under displays are handled in AstDisplay
@ -214,13 +215,13 @@ public:
}
}
virtual void visit(AstSFormat* nodep, AstNUser*) {
displayNode(nodep, nodep->text(), nodep->exprsp(), false);
displayNode(nodep, nodep->fmtp()->scopeNamep(), nodep->fmtp()->text(), nodep->fmtp()->exprsp(), false);
}
virtual void visit(AstFScanF* nodep, AstNUser*) {
displayNode(nodep, nodep->text(), nodep->exprsp(), true);
displayNode(nodep, NULL, nodep->text(), nodep->exprsp(), true);
}
virtual void visit(AstSScanF* nodep, AstNUser*) {
displayNode(nodep, nodep->text(), nodep->exprsp(), true);
displayNode(nodep, NULL, nodep->text(), nodep->exprsp(), true);
}
virtual void visit(AstValuePlusArgs* nodep, AstNUser*) {
string prefix;
@ -1150,7 +1151,8 @@ void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
*elistp = (*elistp)->nextp();
}
void EmitCStmts::displayNode(AstNode* nodep, const string& vformat, AstNode* exprsp,
void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
const string& vformat, AstNode* exprsp,
bool isScan) {
AstNode* elistp = exprsp;
@ -1193,8 +1195,6 @@ void EmitCStmts::displayNode(AstNode* nodep, const string& vformat, AstNode* exp
case 'm': {
emitDispState.pushFormat("%S");
emitDispState.pushArg(NULL, "vlSymsp->name()");
if (!nodep->castNodeDisplay()) nodep->v3fatalSrc("Non-Display with %m");
AstScopeName* scopenamep = nodep->castNodeDisplay()->scopeNamep();
if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
emitDispState.pushFormat(scopenamep->scopePrettyName());
break;

View File

@ -196,7 +196,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
puts(");\n");
}
virtual void visit(AstDisplay* nodep, AstNUser*) {
visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp());
visitNodeDisplay(nodep, nodep->filep(), nodep->fmtp()->text(), nodep->fmtp()->exprsp());
}
virtual void visit(AstFScanF* nodep, AstNUser*) {
visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp());
@ -205,7 +205,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
visitNodeDisplay(nodep, nodep->fromp(), nodep->text(), nodep->exprsp());
}
virtual void visit(AstSFormat* nodep, AstNUser*) {
visitNodeDisplay(nodep, nodep->lhsp(), nodep->text(), nodep->exprsp());
visitNodeDisplay(nodep, nodep->lhsp(), nodep->fmtp()->text(), nodep->fmtp()->exprsp());
}
virtual void visit(AstValuePlusArgs* nodep, AstNUser*) {
visitNodeDisplay(nodep, NULL, nodep->text(), nodep->exprsp());

View File

@ -180,7 +180,7 @@ private:
m_setRefLvalue = true;
nodep->lhsp()->iterateAndNext(*this);
m_setRefLvalue = false;
nodep->exprsp()->iterateAndNext(*this);
nodep->fmtp()->iterateAndNext(*this);
}
m_setRefLvalue = last_setRefLvalue;
}

View File

@ -311,22 +311,16 @@ private:
nodep->iterateChildren(*this);
expectFormat(nodep, nodep->text(), nodep->exprsp(), true);
}
void expectNodeDisplay(AstNodeDisplay* nodep) {
// AstSFormat also handled here
virtual void visit(AstSFormatF* nodep, AstNUser*) {
nodep->iterateChildren(*this);
expectFormat(nodep, nodep->text(), nodep->exprsp(), false);
if ((nodep->castDisplay() && nodep->castDisplay()->displayType().needScopeTracking())
if ((nodep->backp()->castDisplay() && nodep->backp()->castDisplay()->displayType().needScopeTracking())
|| nodep->formatScopeTracking()) {
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
}
}
virtual void visit(AstNodeDisplay* nodep, AstNUser*) {
nodep->iterateChildren(*this);
expectNodeDisplay(nodep);
}
virtual void visit(AstDisplay* nodep, AstNUser* vup) {
nodep->iterateChildren(*this);
expectNodeDisplay(nodep);
if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
if (!m_assertp
&& (nodep->displayType() == AstDisplayType::INFO

View File

@ -195,7 +195,7 @@ private:
}
// VISITORS - Special
virtual void visit(AstNodeDisplay* nodep, AstNUser*) {
virtual void visit(AstSFormatF* nodep, AstNUser*) {
nodep->iterateChildren(*this);
//
UINFO(9," Display in "<<nodep->text()<<endl);

View File

@ -738,7 +738,7 @@ private:
widthCheck(nodep,"Assign RHS",nodep->rhsp(),awidth,awidth);
//if (debug()) nodep->dumpTree(cout," AssignOut: ");
}
virtual void visit(AstNodeDisplay* nodep, AstNUser*) {
virtual void visit(AstSFormatF* nodep, AstNUser*) {
// Excludes NodeDisplay, see below
// TOP LEVEL NODE
// Just let all arguments seek their natural sizes

View File

@ -2064,6 +2064,7 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
| yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); }
| yD_RANDOM '(' expr ')' { $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")"); }
| yD_RANDOM parenE { $$ = new AstRand($1); }
//| yD_SFORMATF '(' str commaEListE ')' { $$ = new AstSFormatF($1,*$3,$4); } // Have AST, just need testing and debug
| yD_SIGNED '(' expr ')' { $$ = new AstSigned($1,$3); }
| yD_STIME parenE { $$ = new AstSel($1,new AstTime($1),0,32); }
| yD_TIME parenE { $$ = new AstTime($1); }