44@author: ballance
55'''
66
7+ from ast import BinOp
78from typing import Dict , Set
89import typing
10+ from vsc .model .bin_expr_type import BinExprType
911from vsc .model .constraint_block_model import ConstraintBlockModel
12+ from vsc .model .constraint_expr_model import ConstraintExprModel
1013from vsc .model .constraint_foreach_model import ConstraintForeachModel
1114from vsc .model .constraint_if_else_model import ConstraintIfElseModel
1215from vsc .model .constraint_inline_scope_model import ConstraintInlineScopeModel
1316from vsc .model .constraint_scope_model import ConstraintScopeModel
1417from vsc .model .expr_array_subscript_model import ExprArraySubscriptModel
18+ from vsc .model .expr_bin_model import ExprBinModel
1519from vsc .model .expr_fieldref_model import ExprFieldRefModel
1620from vsc .model .expr_literal_model import ExprLiteralModel
1721from vsc .model .expr_model import ExprModel
@@ -39,6 +43,7 @@ def __init__(self, bound_m : Dict[FieldModel,VariableBoundModel]):
3943 self .foreach_scope_s = []
4044 self .constraint_collector_s = []
4145 self .foreach_ref_expander = ForeachRefExpander (self .index_set )
46+ self .constraint_block = None
4247
4348 @staticmethod
4449 def build (m , bound_m : typing .Dict [FieldModel ,VariableBoundModel ]):
@@ -49,10 +54,6 @@ def build(m, bound_m : typing.Dict[FieldModel,VariableBoundModel]):
4954 builder .phase = 1
5055 m .accept (builder )
5156
52- # print("--> ArrayConstraintBuilder")
53- # print("Model: " + ModelPrettyPrinter.print(m))
54- # print("<-- ArrayConstraintBuilder")
55-
5657 return builder .constraints
5758
5859 def visit_constraint_foreach (self , f :ConstraintForeachModel ):
@@ -166,11 +167,30 @@ def visit_field_scalar_array(self, f:FieldArrayModel):
166167 range_l = size_bound .domain .range_l
167168 max_size = int (range_l [- 1 ][1 ])
168169
170+ # Composite arrays have a maximum size of their
171+ # current size, since the user must populate them
172+ if not f .is_scalar :
173+ if len (f .field_l ) < max_size :
174+ max_size = len (f .field_l )
175+
176+ if self .constraint_block is None :
177+ self .constraint_block = ConstraintBlockModel ("array_sz_c" )
178+ self .constraints .append (self .constraint_block )
179+
180+ # Add a constraint to limit the random size field
181+ self .constraint_block .addConstraint (ConstraintExprModel (
182+ ExprBinModel (
183+ ExprFieldRefModel (f .size ),
184+ BinExprType .Le ,
185+ ExprLiteralModel (len (f .field_l ), False , 32 )
186+ )
187+ ))
188+
169189 # TODO: how do we manage a max size here?
170190 if max_size > 100000 :
171191 raise Exception ("Max size for array " + f .name + " (" + str (max_size ) + " exceeds 100000" )
172192
173- if len (f .field_l ) < max_size :
193+ if len (f .field_l ) < max_size and f . is_scalar :
174194 # Extend the size appropriately
175195 for i in range (max_size - len (f .field_l )):
176196 f .add_field ()
@@ -179,5 +199,3 @@ def visit_field_scalar_array(self, f:FieldArrayModel):
179199 # Need to recurse into sub-fields for non-scalar arrays
180200 for sf in f .field_l :
181201 sf .accept (self )
182-
183-
0 commit comments