Skip to content

Commit 9f846ea

Browse files
committed
Correct a few issues with dereferencing an expression
Signed-off-by: Matthew Ballance <[email protected]>
1 parent ae044cc commit 9f846ea

File tree

3 files changed

+75
-32
lines changed

3 files changed

+75
-32
lines changed

src/vsc/types.py

+32-29
Original file line numberDiff line numberDiff line change
@@ -176,31 +176,33 @@ def not_inside(self, rhs):
176176
raise Exception("Unsupported 'not_inside' argument of type " + str(type(rhs)))
177177

178178
def __getattr__(self, name):
179-
ret = None
180-
em = object.__getattribute__(self, "em")
181-
fm_t = Expr2FieldTypeVisitor().fieldtype(em)
182-
183-
# This pops 'this expr' off the stack, so we can
184-
# replace it with an extended expression
185-
pop_expr()
186-
187-
if fm_t is not None:
188-
if name in fm_t.field_id_m.keys():
189-
idx = fm_t.field_id_m[name]
190-
ret = expr(ExprIndexedFieldRefModel(em, [idx]))
191-
else:
192-
raise Exception("Field %s not in type %s" % (name, fm_t.name))
179+
if not expr_mode():
180+
return object.__getattribute__(self, name)
193181
else:
194-
fm = Expr2FieldVisitor().field(em)
182+
ret = None
183+
em = object.__getattribute__(self, "em")
184+
fm_t = Expr2FieldTypeVisitor().fieldtype(em)
195185

196-
if name in fm.field_id_m.keys():
197-
idx = fm.field_id_m[name]
198-
ret = expr(ExprIndexedFieldRefModel(em, [idx]))
186+
# This pops 'this expr' off the stack, so we can
187+
# replace it with an extended expression
188+
pop_expr()
189+
190+
if fm_t is not None:
191+
if name in fm_t.field_id_m.keys():
192+
idx = fm_t.field_id_m[name]
193+
ret = expr(ExprIndexedFieldRefModel(em, [idx]))
194+
else:
195+
raise Exception("Field %s not in type %s" % (name, fm_t.name))
199196
else:
200-
raise Exception("Composite %s does not contain a field \"%s\"" % (
201-
fm.name, name))
197+
fm = Expr2FieldVisitor().field(em)
202198

203-
return ret
199+
if name in fm.field_id_m.keys():
200+
idx = fm.field_id_m[name]
201+
ret = expr(ExprIndexedFieldRefModel(em, [idx]))
202+
else:
203+
raise Exception("Composite %s does not contain a field \"%s\"" % (
204+
fm.name, name))
205+
return ret
204206

205207
def __getitem__(self, k):
206208
if is_expr_mode():
@@ -859,15 +861,16 @@ def _id_fields(self, it, parent):
859861

860862
fid = 0
861863
for fn in dir(it):
862-
fo = getattr(it, fn)
863-
if hasattr(fo, "_int_field_info"):
864-
fi = fo._int_field_info
865-
fi.id = fid
866-
fi.parent = it._int_field_info
867-
fid += 1
864+
if not fn.startswith("__") and fn not in ("sum","product","size"):
865+
fo = getattr(it, fn)
866+
if hasattr(fo, "_int_field_info"):
867+
fi = fo._int_field_info
868+
fi.id = fid
869+
fi.parent = it._int_field_info
870+
fid += 1
868871

869-
if fi.is_composite:
870-
self._id_fields(fo, fi)
872+
if fi.is_composite:
873+
self._id_fields(fo, fi)
871874

872875
def get_model(self):
873876
if self._int_field_info.model is None:

src/vsc/visitors/expr2fieldtype_visitor.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ def visit_expr_array_subscript(self, s : ExprArraySubscriptModel):
5757

5858
if Expr2FieldTypeVisitor.DEBUG_EN:
5959
print("--> visit_expr_array_subscript(visit_type)")
60-
t = self.type
61-
self.type = None
62-
t.accept(self)
60+
if self.type is not None:
61+
t = self.type
62+
self.type = None
63+
t.accept(self)
64+
6365
if Expr2FieldTypeVisitor.DEBUG_EN:
6466
print("<-- visit_expr_array_subscript(visit_type)")
6567

ve/unit/test_compound_obj.py

+38
Original file line numberDiff line numberDiff line change
@@ -572,3 +572,41 @@ def eq_c(self):
572572

573573
item = Parent()
574574
item.randomize(debug=False)
575+
576+
def test_nested_objects2(self):
577+
@vsc.randobj
578+
class Field(object):
579+
def __init__(self):
580+
self.d = vsc.rand_uint8_t()
581+
582+
@vsc.randobj
583+
class Child1(object):
584+
def __init__(self):
585+
self.b = vsc.rand_list_t(Child2(), 2)
586+
587+
@vsc.randobj
588+
class Child2(object):
589+
def __init__(self):
590+
self.c = vsc.rand_attr(Field())
591+
592+
@vsc.randobj
593+
class Parent(object):
594+
def __init__(self):
595+
self.a = vsc.rand_list_t(Child1(), 2)
596+
597+
@vsc.constraint
598+
def eq_c(self):
599+
self.a[0].b[0].c.d == self.a[1].b[0].c.d
600+
601+
item = Parent()
602+
item.randomize()
603+
print(f"{item.a[0].b[0].c.d} {item.a[1].b[0].c.d}")
604+
605+
def test_nested_objects3(self):
606+
@vsc.randobj
607+
class Item(object):
608+
def __init__(self):
609+
self.a = vsc.list_t(vsc.rand_list_t(vsc.rand_bit_t(2), 2))
610+
pass
611+
612+
item = Item()

0 commit comments

Comments
 (0)