Rework $display/$write to go via new VL_WRITE function instead of

converting to pure C printf call.  This makes the resulting code smaller,
and allows sharing code with future $sprintf support.
This commit is contained in:
Wilson Snyder
2008-06-30 14:31:58 -04:00
parent 20aa21d4b6
commit 1a8c8bec0d
9 changed files with 289 additions and 217 deletions
+37
View File
@@ -312,10 +312,46 @@ private:
}
}
void expectFormat(AstNode* nodep, const string& format, AstNode* argp) {
// Check display arguments
bool inPct = false;
for (const char* inp = format.c_str(); *inp; inp++) {
char ch = *inp; // Breaks with iterators...
if (!inPct && ch=='%') {
inPct = true;
} else if (inPct) {
inPct = false;
switch (tolower(ch)) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
inPct = true;
break;
case '%': break; // %% - just output a %
case 'm': break; // %m - auto insert "name"
default: // Most operators, just move to next argument
if (!V3Number::displayedFmtLegal(ch)) {
nodep->v3error("Unknown $display format code: %"<<ch);
} else {
if (!argp) {
nodep->v3error("Missing arguments for $display format");
} else {
argp = argp->nextp();
}
}
break;
} // switch
}
}
if (argp) {
argp->v3error("Extra arguments for $display format\n");
}
}
void expectDescriptor(AstNode* nodep, AstNodeVarRef* filep) {
if (!filep) nodep->v3error("Unsupported: $fopen/$fclose/$f* descriptor must be a simple variable");
if (filep && filep->varp()) filep->varp()->attrFileDescr(true);
}
virtual void visit(AstFOpen* nodep, AstNUser*) {
nodep->iterateChildren(*this);
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
@@ -343,6 +379,7 @@ private:
virtual void visit(AstDisplay* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
expectFormat(nodep, nodep->name(), nodep->exprsp());
if (!m_assertp
&& (nodep->displayType() == AstDisplayType::INFO
|| nodep->displayType() == AstDisplayType::WARNING