Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve parseability of type and constant string representations #649

Merged
merged 10 commits into from
Nov 5, 2022
4 changes: 3 additions & 1 deletion bindings/python/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ void registerTypes(py::module_& m) {
typePrintingOptions.def_readwrite("addSingleQuotes", &TypePrintingOptions::addSingleQuotes)
.def_readwrite("elideScopeNames", &TypePrintingOptions::elideScopeNames)
.def_readwrite("printAKA", &TypePrintingOptions::printAKA)
.def_readwrite("anonymousTypeStyle", &TypePrintingOptions::anonymousTypeStyle);
.def_readwrite("anonymousTypeStyle", &TypePrintingOptions::anonymousTypeStyle)
.def_readwrite("skipScopedTypeNames", &TypePrintingOptions::anonymousTypeStyle)
.def_readwrite("fullEnumType", &TypePrintingOptions::anonymousTypeStyle);

py::enum_<TypePrintingOptions::AnonymousTypeStyle>(typePrintingOptions, "AnonymousTypeStyle")
.value("SystemName", TypePrintingOptions::SystemName)
Expand Down
2 changes: 2 additions & 0 deletions include/slang/ast/types/TypePrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ struct SLANG_EXPORT TypePrintingOptions {
bool addSingleQuotes = false;
bool elideScopeNames = false;
bool printAKA = false;
bool skipScopedTypeNames = false;
paulsc96 marked this conversation as resolved.
Show resolved Hide resolved
bool fullEnumType = false;

enum AnonymousTypeStyle { SystemName, FriendlyName } anonymousTypeStyle = SystemName;
};
Expand Down
4 changes: 3 additions & 1 deletion include/slang/numeric/ConstantValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ class SLANG_EXPORT ConstantValue {
Variant& getVariant() { return value; }
const Variant& getVariant() const { return value; }

std::string toString() const;
std::string toString(
bitwidth_t abbreviateThresholdBits = SVInt::DefaultStringAbbreviationThresholdBits,
bool exactUnknowns = false, bool useAssignmentPatterns = false) const;
size_t hash() const;

[[nodiscard]] bool empty() const;
Expand Down
12 changes: 8 additions & 4 deletions include/slang/numeric/SVInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,15 @@ class SLANG_EXPORT SVInt : SVIntStorage {
static SVInt createFillZ(bitwidth_t bitWidth, bool isSigned);

[[nodiscard]] size_t hash() const;
void writeTo(SmallVectorBase<char>& buffer, LiteralBase base) const;
void writeTo(SmallVectorBase<char>& buffer, LiteralBase base,
bitwidth_t abbreviateThresholdBits = DefaultStringAbbreviationThresholdBits) const;
void writeTo(SmallVectorBase<char>& buffer, LiteralBase base, bool includeBase,
bitwidth_t abbreviateThresholdBits = MAX_BITS) const;
std::string toString() const;
std::string toString(LiteralBase base) const;
std::string toString(
bitwidth_t abbreviateThresholdBits = DefaultStringAbbreviationThresholdBits,
bool exactUnknowns = false) const;
std::string toString(LiteralBase base, bitwidth_t abbreviateThresholdBits =
DefaultStringAbbreviationThresholdBits) const;
std::string toString(LiteralBase base, bool includeBase,
bitwidth_t abbreviateThresholdBits = MAX_BITS) const;

Expand Down Expand Up @@ -550,7 +554,7 @@ class SLANG_EXPORT SVInt : SVIntStorage {
static const SVInt One;

/// The default threshold, in bits, to use for abbreviating toString results
/// when calling one of the simple toString() methods that doesn't take a user
/// when calling one of the simple toString() methods without passing a user
/// provided threshold.
static constexpr bitwidth_t DefaultStringAbbreviationThresholdBits = 128;

Expand Down
26 changes: 20 additions & 6 deletions source/ast/types/TypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ void TypePrinter::visit(const EnumType& type, string_view overrideName) {
buffer->append(overrideName);
}
else {
buffer->append("enum{");
buffer->append("enum");
if (options.fullEnumType) {
buffer->append(" " + type.baseType.toString());
}
buffer->append("{");

bool first = true;
for (const auto& member : type.values()) {
Expand All @@ -101,7 +105,9 @@ void TypePrinter::visit(const EnumType& type, string_view overrideName) {
}
buffer->append("}");

if (!overrideName.empty())
if (options.skipScopedTypeNames)
;
else if (!overrideName.empty())
buffer->append(overrideName);
else {
printScope(type.getParentScope());
Expand Down Expand Up @@ -142,7 +148,9 @@ void TypePrinter::visit(const PackedStructType& type, string_view overrideName)

appendMembers(type);

if (!overrideName.empty())
if (options.skipScopedTypeNames)
;
else if (!overrideName.empty())
buffer->append(overrideName);
else {
printScope(type.getParentScope());
Expand All @@ -167,7 +175,9 @@ void TypePrinter::visit(const PackedUnionType& type, string_view overrideName) {

appendMembers(type);

if (!overrideName.empty())
if (options.skipScopedTypeNames)
;
else if (!overrideName.empty())
buffer->append(overrideName);
else {
printScope(type.getParentScope());
Expand Down Expand Up @@ -241,7 +251,9 @@ void TypePrinter::visit(const UnpackedStructType& type, string_view overrideName
buffer->append("struct");
appendMembers(type);

if (!overrideName.empty())
if (options.skipScopedTypeNames)
;
else if (!overrideName.empty())
buffer->append(overrideName);
else {
printScope(type.getParentScope());
Expand All @@ -263,7 +275,9 @@ void TypePrinter::visit(const UnpackedUnionType& type, string_view overrideName)
buffer->append("union");
appendMembers(type);

if (!overrideName.empty())
if (options.skipScopedTypeNames)
;
else if (!overrideName.empty())
buffer->append(overrideName);
else {
printScope(type.getParentScope());
Expand Down
39 changes: 25 additions & 14 deletions source/numeric/ConstantValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ struct always_false : std::false_type {};

const ConstantValue ConstantValue::Invalid;

std::string ConstantValue::toString() const {
std::string ConstantValue::toString(bitwidth_t abbreviateThresholdBits, bool exactUnknowns,
bool useAssignmentPatterns) const {
return std::visit(
[](auto&& arg) {
[abbreviateThresholdBits, exactUnknowns, useAssignmentPatterns](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, std::monostate>)
return "<unset>"s;
else if constexpr (std::is_same_v<T, SVInt>)
return arg.toString();
return arg.toString(abbreviateThresholdBits, exactUnknowns);
else if constexpr (std::is_same_v<T, real_t>)
return fmt::format("{}", double(arg));
else if constexpr (std::is_same_v<T, shortreal_t>)
Expand All @@ -37,51 +38,61 @@ std::string ConstantValue::toString() const {
return "$"s;
else if constexpr (std::is_same_v<T, Elements>) {
FormatBuffer buffer;
buffer.append("[");
buffer.append(useAssignmentPatterns ? "'{"sv : "["sv);
for (auto& element : arg) {
buffer.append(element.toString());
buffer.append(element.toString(abbreviateThresholdBits, exactUnknowns,
useAssignmentPatterns));
buffer.append(",");
}

if (!arg.empty())
buffer.pop_back();
buffer.append("]");
buffer.append(useAssignmentPatterns ? "}"sv : "]"sv);
return buffer.str();
}
else if constexpr (std::is_same_v<T, std::string>)
return fmt::format("\"{}\"", arg);
else if constexpr (std::is_same_v<T, Map>) {
FormatBuffer buffer;
buffer.append("[");
buffer.append(useAssignmentPatterns ? "'{"sv : "["sv);
for (auto& [key, val] : *arg)
buffer.format("{}:{},", key.toString(), val.toString());
buffer.format("{}:{},",
key.toString(abbreviateThresholdBits, exactUnknowns,
useAssignmentPatterns),
val.toString(abbreviateThresholdBits, exactUnknowns,
useAssignmentPatterns));

if (arg->defaultValue)
buffer.format("default:{}", arg->defaultValue.toString());
buffer.format("default:{}",
arg->defaultValue.toString(abbreviateThresholdBits, exactUnknowns,
useAssignmentPatterns));
else if (!arg->empty())
buffer.pop_back();

buffer.append("]");
buffer.append(useAssignmentPatterns ? "}"sv : "]"sv);
return buffer.str();
}
else if constexpr (std::is_same_v<T, Queue>) {
FormatBuffer buffer;
buffer.append("[");
buffer.append(useAssignmentPatterns ? "'{"sv : "["sv);
for (auto& element : *arg) {
buffer.append(element.toString());
buffer.append(element.toString(abbreviateThresholdBits, exactUnknowns,
useAssignmentPatterns));
buffer.append(",");
}

if (!arg->empty())
buffer.pop_back();
buffer.append("]");
buffer.append(useAssignmentPatterns ? "}"sv : "]"sv);
return buffer.str();
}
else if constexpr (std::is_same_v<T, Union>) {
if (!arg->activeMember)
return "(unset)"s;

return fmt::format("({}) {}", *arg->activeMember, arg->value.toString());
return fmt::format("({}) {}", *arg->activeMember,
arg->value.toString(abbreviateThresholdBits, exactUnknowns,
useAssignmentPatterns));
}
else {
static_assert(always_false<T>::value, "Missing case");
Expand Down
16 changes: 9 additions & 7 deletions source/numeric/SVInt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,25 +637,26 @@ std::ostream& operator<<(std::ostream& os, const SVInt& rhs) {
return os;
}

std::string SVInt::toString() const {
std::string SVInt::toString(bitwidth_t abbreviateThresholdBits, bool exactUnknowns) const {
// guess the base to use
LiteralBase base;
if (bitWidth < 8 || (unknownFlag && bitWidth <= 64))
// unknown bits require binary base for lossless representation
if (bitWidth < 8 || (unknownFlag && exactUnknowns) || (unknownFlag && bitWidth <= 64))
base = LiteralBase::Binary;
else if (bitWidth <= 32 || signFlag)
base = LiteralBase::Decimal;
else
base = LiteralBase::Hex;

return toString(base);
return toString(base, abbreviateThresholdBits);
}

std::string SVInt::toString(LiteralBase base) const {
std::string SVInt::toString(LiteralBase base, bitwidth_t abbreviateThresholdBits) const {
// Append the base unless we're a signed 32-bit base 10 integer.
bool includeBase = base != LiteralBase::Decimal || bitWidth != 32 || !signFlag || unknownFlag;

SmallVector<char> buffer;
writeTo(buffer, base, includeBase, DefaultStringAbbreviationThresholdBits);
writeTo(buffer, base, includeBase, abbreviateThresholdBits);
return std::string(buffer.begin(), buffer.end());
}

Expand All @@ -666,10 +667,11 @@ std::string SVInt::toString(LiteralBase base, bool includeBase,
return std::string(buffer.begin(), buffer.end());
}

void SVInt::writeTo(SmallVectorBase<char>& buffer, LiteralBase base) const {
void SVInt::writeTo(SmallVectorBase<char>& buffer, LiteralBase base,
bitwidth_t abbreviateThresholdBits) const {
// Append the base unless we're a signed 32-bit base 10 integer.
bool includeBase = base != LiteralBase::Decimal || bitWidth != 32 || !signFlag || unknownFlag;
writeTo(buffer, base, includeBase);
writeTo(buffer, base, includeBase, abbreviateThresholdBits);
}

void SVInt::writeTo(SmallVectorBase<char>& buffer, LiteralBase base, bool includeBase,
Expand Down