Skip to content

Commit

Permalink
replicated assignment patterns: store and evaluate each expression on…
Browse files Browse the repository at this point in the history
…ly once
  • Loading branch information
MikePopoloski committed Nov 24, 2022
1 parent efd2e8e commit 0f5933d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 28 deletions.
71 changes: 43 additions & 28 deletions source/ast/expressions/AssignmentExpressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1166,14 +1166,27 @@ Expression& Expression::bindAssignmentPattern(Compilation& comp,
}

ConstantValue AssignmentPatternExpressionBase::evalImpl(EvalContext& context) const {
size_t replCount = 1;
if (kind == ExpressionKind::ReplicatedAssignmentPattern) {
auto countVal = as<ReplicatedAssignmentPatternExpression>()
.count()
.eval(context)
.integer()
.as<int32_t>();
ASSERT(countVal >= 0);
replCount = size_t(*countVal);
}

if (type->isIntegral()) {
SmallVector<SVInt> values;
for (auto elem : elements()) {
ConstantValue v = elem->eval(context);
if (!v)
return nullptr;
for (size_t i = 0; i < replCount; i++) {
for (auto elem : elements()) {
ConstantValue v = elem->eval(context);
if (!v)
return nullptr;

values.push_back(v.integer());
values.push_back(v.integer());
}
}

return SVInt::concat(values);
Expand Down Expand Up @@ -1205,21 +1218,25 @@ ConstantValue AssignmentPatternExpressionBase::evalImpl(EvalContext& context) co
else if (type->isQueue()) {
SVQueue result;
result.maxBound = type->getCanonicalType().as<QueueType>().maxBound;
for (auto elem : elements()) {
result.emplace_back(elem->eval(context));
if (result.back().bad())
return nullptr;
for (size_t i = 0; i < replCount; i++) {
for (auto elem : elements()) {
result.emplace_back(elem->eval(context));
if (result.back().bad())
return nullptr;
}
}

result.resizeToBound();
return result;
}
else {
std::vector<ConstantValue> values;
for (auto elem : elements()) {
values.emplace_back(elem->eval(context));
if (values.back().bad())
return nullptr;
for (size_t i = 0; i < replCount; i++) {
for (auto elem : elements()) {
values.emplace_back(elem->eval(context));
if (values.back().bad())
return nullptr;
}
}

return values;
Expand Down Expand Up @@ -1273,16 +1290,15 @@ static span<const Expression* const> bindExpressionList(
SourceRange sourceRange, bool& bad) {

SmallVector<const Expression*> elems;
for (size_t i = 0; i < replCount; i++) {
for (auto item : items) {
auto& expr = Expression::bindRValue(elementType, *item,
item->getFirstToken().location(), context);
elems.push_back(&expr);
bad |= expr.bad();
}
for (auto item : items) {
auto& expr = Expression::bindRValue(elementType, *item, item->getFirstToken().location(),
context);
elems.push_back(&expr);
bad |= expr.bad();
}

if (!bad && expectedCount && expectedCount != elems.size()) {
// TODO: overflow
if (!bad && expectedCount && expectedCount != elems.size() * replCount) {
auto& diag = context.addDiag(diag::WrongNumberAssignmentPatterns, sourceRange);
diag << patternType << expectedCount << elems.size();
bad = true;
Expand Down Expand Up @@ -1864,6 +1880,7 @@ Expression& ReplicatedAssignmentPatternExpression::forStruct(
for (auto& field : structScope.membersOfType<FieldSymbol>())
types.push_back(&field.getType());

// TODO: overflow
if (types.size() != syntax.items.size() * count) {
auto& diag = context.addDiag(diag::WrongNumberAssignmentPatterns, sourceRange);
diag << type << types.size() << syntax.items.size() * count;
Expand All @@ -1873,13 +1890,11 @@ Expression& ReplicatedAssignmentPatternExpression::forStruct(
bool bad = false;
size_t index = 0;
SmallVector<const Expression*> elems;
for (size_t i = 0; i < count; i++) {
for (auto item : syntax.items) {
auto& expr = Expression::bindRValue(*types[index++], *item,
item->getFirstToken().location(), context);
elems.push_back(&expr);
bad |= expr.bad();
}
for (auto item : syntax.items) {
auto& expr = Expression::bindRValue(*types[index++], *item,
item->getFirstToken().location(), context);
elems.push_back(&expr);
bad |= expr.bad();
}

auto result = comp.emplace<ReplicatedAssignmentPatternExpression>(type, countExpr,
Expand Down
6 changes: 6 additions & 0 deletions tests/unittests/EvalTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2311,6 +2311,12 @@ struct {
"[[[1,1],64'h2,6'b10,32'd2,[[3.14],[3.14]]],"
"[[1,1],64'h2,6'b10,32'd2,[[3.14],[3.14]]]]]");

session.eval("int q[$] = '{3{5}};");
CHECK(session.eval("q").toString() == "[5,5,5]");

session.eval("logic [11:0] r = '{12{4'd3}};");
CHECK(session.eval("r").integer() == 4095);

NO_SESSION_ERRORS;
}

Expand Down

0 comments on commit 0f5933d

Please sign in to comment.