Support string.atoi and similar methods, bug1289.

This commit is contained in:
Wilson Snyder 2018-08-25 13:49:37 -04:00
parent b02e353ad1
commit aaac5d4685
3 changed files with 44 additions and 7 deletions

View File

@ -15,6 +15,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
*** Add new reloop optimization for repetitive assignment compression.
*** Support string.atoi and similar methods, bug1289. [Joel Holdsworth]
**** Fix internals to be C++ null-pointer-check clean.
**** Fix internals to avoid 'using namespace std'.

View File

@ -1599,7 +1599,7 @@ private:
0, selwidth));
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
} else {
nodep->v3error("Unknown built-in enum method '"<<nodep->fromp()->prettyTypeName()<<"'");
nodep->v3error("Unknown built-in enum method '"<<nodep->prettyName()<<"'");
}
}
else if (AstUnpackArrayDType* arrayType = VN_CAST(fromDtp, UnpackArrayDType)) {
@ -1638,18 +1638,29 @@ private:
nodep->deleteTree(); VL_DANGLING(nodep);
}
else {
nodep->v3error("Unknown built-in array method '"<<nodep->fromp()->prettyTypeName()<<"'");
nodep->v3error("Unknown built-in array method '"<<nodep->prettyName()<<"'");
}
}
else if (basicp && basicp->isString()) {
// Method call on string
if (nodep->name() == "len") {
// Constant value
if (nodep->pinsp()) nodep->v3error("Arguments passed to string.len method, but it does not take arguments");
AstNode* newp = new AstLenN(nodep->fileline(), nodep->fromp()->unlinkFrBack());
nodep->replaceWith(newp);
pushDeletep(nodep); VL_DANGLING(nodep);
} else if (nodep->name() == "itoa") {
replaceWithSFormat(nodep, "%0d"); VL_DANGLING(nodep);
} else if (nodep->name() == "hextoa") {
replaceWithSFormat(nodep, "%0x"); VL_DANGLING(nodep);
} else if (nodep->name() == "octtoa") {
replaceWithSFormat(nodep, "%0o"); VL_DANGLING(nodep);
} else if (nodep->name() == "bintoa") {
replaceWithSFormat(nodep, "%0b"); VL_DANGLING(nodep);
} else if (nodep->name() == "realtoa") {
replaceWithSFormat(nodep, "%g"); VL_DANGLING(nodep);
} else {
nodep->v3error("Unsupported: built-in string method '"<<nodep->fromp()->prettyTypeName()<<"'");
nodep->v3error("Unsupported: built-in string method '"<<nodep->prettyName()<<"'");
}
}
else {
@ -3505,6 +3516,26 @@ private:
return newp;
}
//----------------------------------------------------------------------
// METHODS - strings
void replaceWithSFormat(AstMethodSel* nodep, const string& format) {
// For string.itoa and similar, replace with SFormatF
AstArg* argp = VN_CAST(nodep->pinsp(), Arg);
if (!argp) {
nodep->v3error("Argument needed for string."
+nodep->prettyName()+" method");
return;
}
AstNodeVarRef* fromp = VN_CAST(nodep->fromp()->unlinkFrBack(), VarRef);
AstNode* newp = new AstAssign(nodep->fileline(), fromp,
new AstSFormatF(nodep->fileline(), format, false,
argp->exprp()->unlinkFrBack()));
fromp->lvalue(true);
nodep->replaceWith(newp);
pushDeletep(nodep); VL_DANGLING(nodep);
}
//----------------------------------------------------------------------
// METHODS - data types

View File

@ -36,12 +36,12 @@ module t (/*AUTOARG*/
s="101"; `checkh(s.atooct(), 'o101);
s="101"; `checkh(s.atobin(), 'b101);
s="1.23"; `checkg(s.atoreal(), 1.23);
`endif
s.itoa(123); `checks(s, "123");
s.hextoa(123); `checks(s, "7b");
s.octtoa(123); `checks(s, "173");
s.bintoa(123); `checks(s, "1111011");
s.realtoa(1.23); `checks(s, "1.23");
`endif
end
// Check runtime
@ -53,15 +53,17 @@ module t (/*AUTOARG*/
end
else if (cyc==1) begin
`checkh(s.len(),4);
end
`ifndef VERILATOR
else if (cyc==2) begin
s.putc(2, "z");
end
else if (cyc==2) begin
else if (cyc==3) begin
`checks(s, "12z4");
`checkh(s.getc(2), "z");
s="abCD";
end
else if (cyc==3) begin
else if (cyc==4) begin
`checks(s.toupper(), "ABCD");
`checks(s.tolower(), "abcd");
s="b";
@ -84,6 +86,9 @@ module t (/*AUTOARG*/
end
else if (cyc==8) begin
`checkg(s.atoreal(), 1.23);
end
`endif
else if (cyc==9) begin
s.itoa(123);
end
else if (cyc==10) begin
@ -104,7 +109,6 @@ module t (/*AUTOARG*/
end
else if (cyc==14) begin
`checks(s, "1.23");
`endif
end
else if (cyc==99) begin
$write("*-* All Finished *-*\n");