175 | 175 |
(location.name, self.current_routine.name)
|
176 | 176 |
)
|
177 | 177 |
|
178 | |
def assert_affected_within(self, name, affected, limited_to):
|
|
178 |
def assert_affected_within(self, name, affecting_type, limiting_type):
|
|
179 |
assert name in ('inputs', 'outputs', 'trashes')
|
|
180 |
affected = getattr(affecting_type, name)
|
|
181 |
limited_to = getattr(limiting_type, name)
|
179 | 182 |
overage = affected - limited_to
|
180 | 183 |
if not overage:
|
181 | 184 |
return
|
182 | |
message = 'in %s: %s are %s but affects %s which exceeds it by: %s ' % (
|
|
185 |
message = 'in %s: %s for %s are %s\n\nbut %s affects %s\n\nwhich exceeds it by: %s ' % (
|
183 | 186 |
self.current_routine.name, name,
|
184 | |
LocationRef.format_set(limited_to), LocationRef.format_set(affected), LocationRef.format_set(overage)
|
|
187 |
limiting_type, LocationRef.format_set(limited_to),
|
|
188 |
affecting_type, LocationRef.format_set(affected),
|
|
189 |
LocationRef.format_set(overage)
|
185 | 190 |
)
|
186 | 191 |
raise IncompatibleConstraintsError(message)
|
187 | 192 |
|
|
389 | 394 |
if src.type == dest.type:
|
390 | 395 |
pass
|
391 | 396 |
elif isinstance(src.type, RoutineType) and isinstance(dest.type, VectorType):
|
392 | |
self.assert_affected_within('inputs', src.type.inputs, dest.type.of_type.inputs)
|
393 | |
self.assert_affected_within('outputs', src.type.outputs, dest.type.of_type.outputs)
|
394 | |
self.assert_affected_within('trashes', src.type.trashes, dest.type.of_type.trashes)
|
|
397 |
self.assert_affected_within('inputs', src.type, dest.type.of_type)
|
|
398 |
self.assert_affected_within('outputs', src.type, dest.type.of_type)
|
|
399 |
self.assert_affected_within('trashes', src.type, dest.type.of_type)
|
395 | 400 |
else:
|
396 | 401 |
raise TypeMismatchError((src, dest))
|
397 | 402 |
else:
|
|
450 | 455 |
# and that this routine's trashes and output constraints are a
|
451 | 456 |
# superset of the called routine's
|
452 | 457 |
current_type = self.current_routine.location.type
|
453 | |
self.assert_affected_within('outputs', type_.outputs, current_type.outputs)
|
454 | |
self.assert_affected_within('trashes', type_.trashes, current_type.trashes)
|
|
458 |
self.assert_affected_within('outputs', type_, current_type)
|
|
459 |
self.assert_affected_within('trashes', type_, current_type)
|
455 | 460 |
|
456 | 461 |
self.has_encountered_goto = True
|
457 | 462 |
elif opcode == 'trash':
|