VVP: array-pattern object values for class queue properties

Support IVL_EX_ARRAY_PATTERN in object evaluation for queue-typed class properties: build an empty queue and append pattern elements, matching darray array-pattern object handling. Fix vec4 stack use so %queue/append_word/v is not double-popped. Update class queue locator regression to use direct c.q = '{...} assignment.

Made-with: Cursor
This commit is contained in:
mjoekhan 2026-04-28 22:17:13 +05:00
parent c189cc2642
commit 7fe2ddda0b
2 changed files with 49 additions and 24 deletions

View File

@ -15,15 +15,7 @@ module test;
initial begin
c = new;
c.q.push_back(4);
c.q.push_back(7);
c.q.push_back(2);
c.q.push_back(5);
c.q.push_back(7);
c.q.push_back(1);
c.q.push_back(6);
c.q.push_back(3);
c.q.push_back(1);
c.q = '{4, 7, 2, 5, 7, 1, 6, 3, 1};
r = c.q.find() with (item > 3);
`check(r.size, 5);

View File

@ -173,35 +173,62 @@ static int eval_darray_new(ivl_expr_t ex)
return errors;
}
/* Build a dynamic-array object value from an array pattern expression. */
static int eval_darray_pattern_object(ivl_expr_t ex)
/* Build a queue/dynamic-array object value from an array pattern expression. */
static int eval_array_pattern_object(ivl_expr_t ex)
{
int errors = 0;
ivl_type_t net_type = ivl_expr_net_type(ex);
if (!net_type || ivl_type_base(net_type) != IVL_VT_DARRAY)
if (!net_type)
return 1;
ivl_variable_type_t base_type = ivl_type_base(net_type);
if (base_type != IVL_VT_DARRAY && base_type != IVL_VT_QUEUE)
return 1;
ivl_type_t element_type = ivl_type_element(net_type);
if (!element_type)
return 1;
unsigned size_reg = allocate_word();
fprintf(vvp_out, " %%ix/load %u, %u, 0;\n", size_reg, ivl_expr_parms(ex));
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
darray_new(element_type, size_reg);
unsigned max_elems = ivl_expr_parms(ex);
if (base_type == IVL_VT_QUEUE) {
unsigned max_size = ivl_type_queue_max(net_type);
if (max_size != 0 && max_elems > max_size) {
fprintf(stderr, "%s:%u: Warning: Array pattern assignment has more "
"elements (%u) than bounded queue supports (%u).\n"
" Only using first %u elements.\n",
ivl_expr_file(ex), ivl_expr_lineno(ex), max_elems, max_size, max_size);
max_elems = max_size;
}
fprintf(vvp_out, " %%queue/new_empty/v;\n");
} else {
unsigned size_reg = allocate_word();
fprintf(vvp_out, " %%ix/load %u, %u, 0;\n", size_reg, max_elems);
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
darray_new(element_type, size_reg);
}
switch (ivl_type_base(element_type)) {
case IVL_VT_BOOL:
case IVL_VT_LOGIC:
for (unsigned idx = 0; idx < ivl_expr_parms(ex); idx += 1) {
for (unsigned idx = 0; idx < max_elems; idx += 1) {
draw_eval_vec4(ivl_expr_parm(ex, idx));
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%set/dar/obj/vec4 3;\n");
fprintf(vvp_out, " %%pop/vec4 1;\n");
if (base_type == IVL_VT_QUEUE) {
fprintf(vvp_out, " %%queue/append_word/v %u;\n",
ivl_type_packed_width(element_type));
} else {
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%set/dar/obj/vec4 3;\n");
fprintf(vvp_out, " %%pop/vec4 1;\n");
}
}
break;
case IVL_VT_REAL:
for (unsigned idx = 0; idx < ivl_expr_parms(ex); idx += 1) {
for (unsigned idx = 0; idx < max_elems; idx += 1) {
if (base_type == IVL_VT_QUEUE) {
fprintf(vvp_out, "; ERROR: eval_array_pattern_object: queue real "
"element type not implemented\n");
errors += 1;
break;
}
draw_eval_real(ivl_expr_parm(ex, idx));
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%set/dar/obj/real 3;\n");
@ -209,7 +236,13 @@ static int eval_darray_pattern_object(ivl_expr_t ex)
}
break;
case IVL_VT_STRING:
for (unsigned idx = 0; idx < ivl_expr_parms(ex); idx += 1) {
for (unsigned idx = 0; idx < max_elems; idx += 1) {
if (base_type == IVL_VT_QUEUE) {
fprintf(vvp_out, "; ERROR: eval_array_pattern_object: queue string "
"element type not implemented\n");
errors += 1;
break;
}
draw_eval_string(ivl_expr_parm(ex, idx));
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%set/dar/obj/str 3;\n");
@ -217,7 +250,7 @@ static int eval_darray_pattern_object(ivl_expr_t ex)
}
break;
default:
fprintf(vvp_out, "; ERROR: eval_darray_pattern_object: unsupported "
fprintf(vvp_out, "; ERROR: eval_array_pattern_object: unsupported "
"element type %d\n", ivl_type_base(element_type));
errors += 1;
break;
@ -823,7 +856,7 @@ int draw_eval_object(ivl_expr_t ex)
return eval_object_ufunc(ex);
case IVL_EX_ARRAY_PATTERN:
return eval_darray_pattern_object(ex);
return eval_array_pattern_object(ex);
case IVL_EX_SFUNC:
/* Queue locator `with` may report IVL_VT_DARRAY in ivl; handle by name. */