mirror of
https://github.com/verilator/verilator.git
synced 2025-04-30 04:26:55 +00:00
Internals: Add AstSFormatF
This commit is contained in:
parent
788f69a8c9
commit
0d1de96dbc
@ -61,12 +61,12 @@ private:
|
|||||||
}
|
}
|
||||||
void replaceDisplay(AstDisplay* nodep, const string& prefix) {
|
void replaceDisplay(AstDisplay* nodep, const string& prefix) {
|
||||||
nodep->displayType(AstDisplayType::WRITE);
|
nodep->displayType(AstDisplayType::WRITE);
|
||||||
nodep->text(assertDisplayMessage(nodep, prefix, nodep->text()));
|
nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text()));
|
||||||
AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack();
|
AstNode* timesp = nodep->fmtp()->exprsp(); if (timesp) timesp->unlinkFrBack();
|
||||||
timesp = timesp->addNext(new AstTime(nodep->fileline()));
|
timesp = timesp->addNext(new AstTime(nodep->fileline()));
|
||||||
nodep->exprsp(timesp);
|
nodep->fmtp()->exprsp(timesp);
|
||||||
if (!nodep->scopeNamep() && nodep->formatScopeTracking()) {
|
if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) {
|
||||||
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
nodep->fmtp()->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
src/V3Ast.h
20
src/V3Ast.h
@ -1194,26 +1194,6 @@ public:
|
|||||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
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 {
|
struct AstNodeText : public AstNode {
|
||||||
private:
|
private:
|
||||||
string m_text;
|
string m_text;
|
||||||
|
@ -1506,14 +1506,38 @@ public:
|
|||||||
void ignoreOverlap(bool flag) { m_ignoreOverlap = flag; }
|
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
|
// 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:
|
private:
|
||||||
AstDisplayType m_displayType;
|
AstDisplayType m_displayType;
|
||||||
public:
|
public:
|
||||||
AstDisplay(FileLine* fileline, AstDisplayType dispType, const string& text, AstNode* filep, AstNode* exprsp)
|
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);
|
setNOp3p(filep);
|
||||||
m_displayType = dispType;
|
m_displayType = dispType;
|
||||||
}
|
}
|
||||||
@ -1526,24 +1550,25 @@ public:
|
|||||||
virtual bool isSplittable() const { return false; } // SPECIAL: $display has 'visual' ordering
|
virtual bool isSplittable() const { return false; } // SPECIAL: $display has 'visual' ordering
|
||||||
virtual bool isOutputter() const { return true; } // SPECIAL: $display makes output
|
virtual bool isOutputter() const { return true; } // SPECIAL: $display makes output
|
||||||
virtual bool isUnlikely() const { return true; }
|
virtual bool isUnlikely() const { return true; }
|
||||||
virtual V3Hash sameHash() const { return V3Hash(text()); }
|
virtual V3Hash sameHash() const { return V3Hash(displayType()); }
|
||||||
virtual bool same(AstNode* samep) const {
|
virtual bool same(AstNode* samep) const { return displayType()==samep->castDisplay()->displayType(); }
|
||||||
return displayType()==samep->castDisplay()->displayType()
|
virtual int instrCount() const { return instrCountPli(); }
|
||||||
&& text()==samep->castDisplay()->text(); }
|
|
||||||
// op1,op2 used by AstNodeDisplay
|
|
||||||
AstDisplayType displayType() const { return m_displayType; }
|
AstDisplayType displayType() const { return m_displayType; }
|
||||||
void displayType(AstDisplayType type) { m_displayType = type; }
|
void displayType(AstDisplayType type) { m_displayType = type; }
|
||||||
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
|
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(); }
|
AstNode* filep() const { return op3p(); }
|
||||||
void filep(AstNodeVarRef* nodep) { setNOp3p(nodep); }
|
void filep(AstNodeVarRef* nodep) { setNOp3p(nodep); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstSFormat : public AstNodeDisplay {
|
struct AstSFormat : public AstNode {
|
||||||
// Parents: statement container
|
// Parents: statement container
|
||||||
// Children: string to load
|
// Children: string to load
|
||||||
// Children: varrefs to print
|
// Children: SFORMATF to generate print string
|
||||||
AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp)
|
AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp)
|
||||||
: AstNodeDisplay (fileline, text, exprsp) {
|
: AstNode (fileline) {
|
||||||
|
setOp1p(new AstSFormatF(fileline,text,exprsp));
|
||||||
setOp3p(lhsp);
|
setOp3p(lhsp);
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(SFormat, SFORMAT)
|
ASTNODE_NODE_FUNCS(SFormat, SFORMAT)
|
||||||
@ -1555,10 +1580,11 @@ struct AstSFormat : public AstNodeDisplay {
|
|||||||
virtual bool isSplittable() const { return true; }
|
virtual bool isSplittable() const { return true; }
|
||||||
virtual bool isOutputter() const { return false; }
|
virtual bool isOutputter() const { return false; }
|
||||||
virtual bool cleanOut() { return false; }
|
virtual bool cleanOut() { return false; }
|
||||||
virtual V3Hash sameHash() const { return V3Hash(text()); }
|
virtual int instrCount() const { return instrCountPli(); }
|
||||||
virtual bool same(AstNode* samep) const {
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
return text()==samep->castSFormat()->text(); }
|
virtual bool same(AstNode* samep) const { return true; }
|
||||||
// op1,op2 used by AstNodeDisplay
|
void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter
|
||||||
|
AstSFormatF* fmtp() const { return op1p()->castSFormatF(); }
|
||||||
AstNode* lhsp() const { return op3p(); }
|
AstNode* lhsp() const { return op3p(); }
|
||||||
void lhsp(AstNode* nodep) { setOp3p(nodep); }
|
void lhsp(AstNode* nodep) { setOp3p(nodep); }
|
||||||
};
|
};
|
||||||
|
@ -240,7 +240,7 @@ private:
|
|||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
insureClean(nodep->condp());
|
insureClean(nodep->condp());
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeDisplay* nodep, AstNUser*) {
|
virtual void visit(AstSFormatF* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
insureCleanAndNext (nodep->exprsp());
|
insureCleanAndNext (nodep->exprsp());
|
||||||
}
|
}
|
||||||
|
@ -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
|
// Substitute constants into displays. The main point of this is to
|
||||||
// simplify assertion methodologies which call functions with display's.
|
// 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.
|
// This eliminates a pile of wide temps, and makes the C a whole lot more readable.
|
||||||
|
@ -63,7 +63,8 @@ public:
|
|||||||
&& v3Global.opt.outputSplit() < splitSize()); }
|
&& v3Global.opt.outputSplit() < splitSize()); }
|
||||||
|
|
||||||
// METHODS
|
// 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 displayEmit(AstNode* nodep, bool isScan);
|
||||||
void displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
|
void displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
|
||||||
string vfmt, char fmtLetter);
|
string vfmt, char fmtLetter);
|
||||||
@ -203,9 +204,9 @@ public:
|
|||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||||
string text = nodep->text();
|
string text = nodep->fmtp()->text();
|
||||||
if (nodep->addNewline()) text += "\n";
|
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*) {
|
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||||
// For use under AstCCalls for dpiImports. ScopeNames under displays are handled in AstDisplay
|
// For use under AstCCalls for dpiImports. ScopeNames under displays are handled in AstDisplay
|
||||||
@ -214,13 +215,13 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstSFormat* nodep, AstNUser*) {
|
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*) {
|
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*) {
|
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*) {
|
virtual void visit(AstValuePlusArgs* nodep, AstNUser*) {
|
||||||
string prefix;
|
string prefix;
|
||||||
@ -1150,7 +1151,8 @@ void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
|
|||||||
*elistp = (*elistp)->nextp();
|
*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) {
|
bool isScan) {
|
||||||
AstNode* elistp = exprsp;
|
AstNode* elistp = exprsp;
|
||||||
|
|
||||||
@ -1193,8 +1195,6 @@ void EmitCStmts::displayNode(AstNode* nodep, const string& vformat, AstNode* exp
|
|||||||
case 'm': {
|
case 'm': {
|
||||||
emitDispState.pushFormat("%S");
|
emitDispState.pushFormat("%S");
|
||||||
emitDispState.pushArg(NULL, "vlSymsp->name()");
|
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");
|
if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
|
||||||
emitDispState.pushFormat(scopenamep->scopePrettyName());
|
emitDispState.pushFormat(scopenamep->scopePrettyName());
|
||||||
break;
|
break;
|
||||||
|
@ -196,7 +196,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
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*) {
|
virtual void visit(AstFScanF* nodep, AstNUser*) {
|
||||||
visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp());
|
visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp());
|
||||||
@ -205,7 +205,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||||||
visitNodeDisplay(nodep, nodep->fromp(), nodep->text(), nodep->exprsp());
|
visitNodeDisplay(nodep, nodep->fromp(), nodep->text(), nodep->exprsp());
|
||||||
}
|
}
|
||||||
virtual void visit(AstSFormat* nodep, AstNUser*) {
|
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*) {
|
virtual void visit(AstValuePlusArgs* nodep, AstNUser*) {
|
||||||
visitNodeDisplay(nodep, NULL, nodep->text(), nodep->exprsp());
|
visitNodeDisplay(nodep, NULL, nodep->text(), nodep->exprsp());
|
||||||
|
@ -180,7 +180,7 @@ private:
|
|||||||
m_setRefLvalue = true;
|
m_setRefLvalue = true;
|
||||||
nodep->lhsp()->iterateAndNext(*this);
|
nodep->lhsp()->iterateAndNext(*this);
|
||||||
m_setRefLvalue = false;
|
m_setRefLvalue = false;
|
||||||
nodep->exprsp()->iterateAndNext(*this);
|
nodep->fmtp()->iterateAndNext(*this);
|
||||||
}
|
}
|
||||||
m_setRefLvalue = last_setRefLvalue;
|
m_setRefLvalue = last_setRefLvalue;
|
||||||
}
|
}
|
||||||
|
@ -311,22 +311,16 @@ private:
|
|||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
expectFormat(nodep, nodep->text(), nodep->exprsp(), true);
|
expectFormat(nodep, nodep->text(), nodep->exprsp(), true);
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstSFormatF* nodep, AstNUser*) {
|
||||||
void expectNodeDisplay(AstNodeDisplay* nodep) {
|
nodep->iterateChildren(*this);
|
||||||
// AstSFormat also handled here
|
|
||||||
expectFormat(nodep, nodep->text(), nodep->exprsp(), false);
|
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->formatScopeTracking()) {
|
||||||
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeDisplay* nodep, AstNUser*) {
|
|
||||||
nodep->iterateChildren(*this);
|
|
||||||
expectNodeDisplay(nodep);
|
|
||||||
}
|
|
||||||
virtual void visit(AstDisplay* nodep, AstNUser* vup) {
|
virtual void visit(AstDisplay* nodep, AstNUser* vup) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
expectNodeDisplay(nodep);
|
|
||||||
if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||||
if (!m_assertp
|
if (!m_assertp
|
||||||
&& (nodep->displayType() == AstDisplayType::INFO
|
&& (nodep->displayType() == AstDisplayType::INFO
|
||||||
|
@ -195,7 +195,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VISITORS - Special
|
// VISITORS - Special
|
||||||
virtual void visit(AstNodeDisplay* nodep, AstNUser*) {
|
virtual void visit(AstSFormatF* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
//
|
//
|
||||||
UINFO(9," Display in "<<nodep->text()<<endl);
|
UINFO(9," Display in "<<nodep->text()<<endl);
|
||||||
|
@ -738,7 +738,7 @@ private:
|
|||||||
widthCheck(nodep,"Assign RHS",nodep->rhsp(),awidth,awidth);
|
widthCheck(nodep,"Assign RHS",nodep->rhsp(),awidth,awidth);
|
||||||
//if (debug()) nodep->dumpTree(cout," AssignOut: ");
|
//if (debug()) nodep->dumpTree(cout," AssignOut: ");
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeDisplay* nodep, AstNUser*) {
|
virtual void visit(AstSFormatF* nodep, AstNUser*) {
|
||||||
// Excludes NodeDisplay, see below
|
// Excludes NodeDisplay, see below
|
||||||
// TOP LEVEL NODE
|
// TOP LEVEL NODE
|
||||||
// Just let all arguments seek their natural sizes
|
// Just let all arguments seek their natural sizes
|
||||||
|
@ -2064,6 +2064,7 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
|
|||||||
| yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); }
|
| 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 '(' expr ')' { $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")"); }
|
||||||
| yD_RANDOM parenE { $$ = new AstRand($1); }
|
| 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_SIGNED '(' expr ')' { $$ = new AstSigned($1,$3); }
|
||||||
| yD_STIME parenE { $$ = new AstSel($1,new AstTime($1),0,32); }
|
| yD_STIME parenE { $$ = new AstSel($1,new AstTime($1),0,32); }
|
||||||
| yD_TIME parenE { $$ = new AstTime($1); }
|
| yD_TIME parenE { $$ = new AstTime($1); }
|
||||||
|
Loading…
Reference in New Issue
Block a user