mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-04-06 17:39:38 +00:00
Statics are always writeable. Statics are always meaningful.
This commit is contained in:
parent
b829836cdc
commit
55331e9c54
@ -53,6 +53,12 @@ class IncompatibleConstraintsError(ConstraintsError):
|
||||
pass
|
||||
|
||||
|
||||
def routine_has_static(routine, ref):
|
||||
if not hasattr(routine, 'statics'):
|
||||
return False
|
||||
return ref in [static.location for static in routine.statics]
|
||||
|
||||
|
||||
class Context(object):
|
||||
"""
|
||||
A location is touched if it was changed (or even potentially
|
||||
@ -112,6 +118,9 @@ class Context(object):
|
||||
def assert_meaningful(self, *refs, **kwargs):
|
||||
exception_class = kwargs.get('exception_class', UnmeaningfulReadError)
|
||||
for ref in refs:
|
||||
# statics are always meaningful
|
||||
if routine_has_static(self.routine, ref):
|
||||
continue
|
||||
if ref.is_constant() or ref in self.routines:
|
||||
pass
|
||||
elif isinstance(ref, LocationRef):
|
||||
@ -129,6 +138,9 @@ class Context(object):
|
||||
def assert_writeable(self, *refs, **kwargs):
|
||||
exception_class = kwargs.get('exception_class', ForbiddenWriteError)
|
||||
for ref in refs:
|
||||
# statics are always writeable
|
||||
if routine_has_static(self.routine, ref):
|
||||
continue
|
||||
if ref not in self._writeable:
|
||||
message = '%s in %s' % (ref.name, self.routine.name)
|
||||
if kwargs.get('message'):
|
||||
@ -231,7 +243,7 @@ class Analyzer(object):
|
||||
for ref in type_.outputs:
|
||||
context.assert_meaningful(ref, exception_class=UnmeaningfulOutputError)
|
||||
for ref in context.each_touched():
|
||||
if ref not in type_.outputs and ref not in type_.trashes:
|
||||
if ref not in type_.outputs and ref not in type_.trashes and not routine_has_static(routine, ref):
|
||||
message = '%s in %s' % (ref.name, routine.name)
|
||||
raise ForbiddenWriteError(message)
|
||||
self.current_routine = None
|
||||
|
@ -145,7 +145,7 @@ class LocationRef(Ref):
|
||||
# just to be sure.
|
||||
equal = isinstance(other, self.__class__) and other.name == self.name
|
||||
if equal:
|
||||
assert other.type == self.type
|
||||
assert other.type == self.type, repr((self, other))
|
||||
return equal
|
||||
|
||||
def __hash__(self):
|
||||
|
@ -14,6 +14,9 @@ class SymEntry(object):
|
||||
self.ast_node = ast_node
|
||||
self.model = model
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%r, %r)" % (self.__class__.__name__, self.ast_node, self.model)
|
||||
|
||||
|
||||
class Parser(object):
|
||||
def __init__(self, text):
|
||||
@ -221,12 +224,7 @@ class Parser(object):
|
||||
else:
|
||||
statics = self.statics()
|
||||
|
||||
self.current_statics = {}
|
||||
for defn in statics:
|
||||
name = defn.name
|
||||
if name in self.symbols or name in self.current_statics:
|
||||
raise SyntaxError('Symbol "%s" already declared' % name)
|
||||
self.current_statics[name] = SymEntry(defn, defn.location)
|
||||
self.current_statics = self.compose_statics_dict(statics)
|
||||
block = self.block()
|
||||
self.current_statics = {}
|
||||
|
||||
@ -237,6 +235,15 @@ class Parser(object):
|
||||
location=location, statics=statics
|
||||
)
|
||||
|
||||
def compose_statics_dict(self, statics):
|
||||
c = {}
|
||||
for defn in statics:
|
||||
name = defn.name
|
||||
if name in self.symbols or name in self.current_statics:
|
||||
raise SyntaxError('Symbol "%s" already declared' % name)
|
||||
c[name] = SymEntry(defn, defn.location)
|
||||
return c
|
||||
|
||||
def labels(self):
|
||||
accum = []
|
||||
accum.append(self.label())
|
||||
|
@ -2283,3 +2283,29 @@ The new style routine definitions support typedefs.
|
||||
| copy foo, vec
|
||||
| }
|
||||
= ok
|
||||
|
||||
### static ###
|
||||
|
||||
When memory locations are defined static to a routine, they cannot be
|
||||
directly input, nor directly output; and since they are always initialized,
|
||||
they cannot be trashed. Thus, they really don't participate in the analysis.
|
||||
|
||||
| define foo routine
|
||||
| inputs x
|
||||
| outputs x
|
||||
| trashes z, n
|
||||
| static byte t : 0
|
||||
| {
|
||||
| st x, t
|
||||
| inc t
|
||||
| ld x, t
|
||||
| }
|
||||
|
|
||||
| define main routine
|
||||
| trashes a, x, z, n
|
||||
| static byte t : 0
|
||||
| {
|
||||
| ld x, t
|
||||
| call foo
|
||||
| }
|
||||
= ok
|
||||
|
Loading…
x
Reference in New Issue
Block a user