mirror of
https://github.com/catseye/SixtyPical.git
synced 2024-11-26 14:49:15 +00:00
Add specific error for uninit outputs. Sketch if
analysis.
This commit is contained in:
parent
f92056d640
commit
6192a6a7f8
@ -18,6 +18,10 @@ class UninitializedAccessError(StaticAnalysisError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class UninitializedOutputError(StaticAnalysisError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class IllegalWriteError(StaticAnalysisError):
|
class IllegalWriteError(StaticAnalysisError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -44,13 +48,14 @@ class Context():
|
|||||||
self._store.setdefault(ref.name, UNINITIALIZED)
|
self._store.setdefault(ref.name, UNINITIALIZED)
|
||||||
self._writeables.add(ref.name)
|
self._writeables.add(ref.name)
|
||||||
|
|
||||||
def assertInitialized(self, *refs):
|
def assertInitialized(self, *refs, **kwargs):
|
||||||
|
exception_class = kwargs.get('exception_class', UninitializedAccessError)
|
||||||
for ref in refs:
|
for ref in refs:
|
||||||
if isinstance(ref, ConstantRef):
|
if isinstance(ref, ConstantRef):
|
||||||
pass
|
pass
|
||||||
elif isinstance(ref, LocationRef):
|
elif isinstance(ref, LocationRef):
|
||||||
if self.get(ref) != INITIALIZED:
|
if self.get(ref) != INITIALIZED:
|
||||||
raise UninitializedAccessError(ref.name)
|
raise exception_class(ref.name)
|
||||||
else:
|
else:
|
||||||
raise ValueError(ref)
|
raise ValueError(ref)
|
||||||
|
|
||||||
@ -94,7 +99,7 @@ def analyze_routine(routine, routines):
|
|||||||
context = Context(routine.inputs, routine.outputs, routine.trashes)
|
context = Context(routine.inputs, routine.outputs, routine.trashes)
|
||||||
analyze_block(routine.block, context, routines)
|
analyze_block(routine.block, context, routines)
|
||||||
for ref in routine.outputs:
|
for ref in routine.outputs:
|
||||||
context.assertInitialized(ref)
|
context.assertInitialized(ref, exception_class=UninitializedOutputError)
|
||||||
|
|
||||||
|
|
||||||
def analyze_block(block, context, routines):
|
def analyze_block(block, context, routines):
|
||||||
@ -154,6 +159,10 @@ def analyze_instr(instr, context, routines):
|
|||||||
context.assertWriteable(ref)
|
context.assertWriteable(ref)
|
||||||
context.setUninitialized(ref)
|
context.setUninitialized(ref)
|
||||||
elif opcode == 'if':
|
elif opcode == 'if':
|
||||||
pass
|
context1 = context.clone()
|
||||||
|
context2 = context.clone()
|
||||||
|
analyze_block(instr.block1, context1, routines)
|
||||||
|
analyze_block(instr.block2, context2, routines)
|
||||||
|
reconcile_contexts(context1, context2, output=context)
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
Sixtypical Analysis
|
SixtyPical Analysis
|
||||||
===================
|
===================
|
||||||
|
|
||||||
This is a test suite, written in [Falderal][] format, for the Sixtypical
|
This is a test suite, written in [Falderal][] format, for the SixtyPical
|
||||||
static analysis rules.
|
static analysis rules.
|
||||||
|
|
||||||
[Falderal]: http://catseye.tc/node/Falderal
|
[Falderal]: http://catseye.tc/node/Falderal
|
||||||
|
|
||||||
-> Functionality "Analyze Sixtypical program" is implemented by
|
-> Functionality "Analyze SixtyPical program" is implemented by
|
||||||
-> shell command "bin/sixtypical --analyze %(test-body-file)"
|
-> shell command "bin/sixtypical --analyze %(test-body-file)"
|
||||||
|
|
||||||
-> Tests for functionality "Analyze Sixtypical program"
|
-> Tests for functionality "Analyze SixtyPical program"
|
||||||
|
|
||||||
### Rudiments ###
|
### Rudiments ###
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ If a routine declares it outputs a location, that location should be initialized
|
|||||||
| {
|
| {
|
||||||
| ld x, 0
|
| ld x, 0
|
||||||
| }
|
| }
|
||||||
? UninitializedAccessError: a
|
? UninitializedOutputError: a
|
||||||
|
|
||||||
| routine main
|
| routine main
|
||||||
| inputs a
|
| inputs a
|
||||||
@ -318,7 +318,7 @@ You can't output a value that the thing you called trashed.
|
|||||||
| ld x, 0
|
| ld x, 0
|
||||||
| call foo
|
| call foo
|
||||||
| }
|
| }
|
||||||
? UninitializedAccessError: lives
|
? UninitializedOutputError: lives
|
||||||
|
|
||||||
...unless you write to it yourself afterwards.
|
...unless you write to it yourself afterwards.
|
||||||
|
|
||||||
@ -402,14 +402,14 @@ Both blocks of an `if` are analyzed.
|
|||||||
|
|
||||||
| routine foo
|
| routine foo
|
||||||
| inputs a
|
| inputs a
|
||||||
| outputs a
|
| outputs x
|
||||||
| trashes z, n, c
|
| trashes a, z, n, c
|
||||||
| {
|
| {
|
||||||
| cmp a, 42
|
| cmp a, 42
|
||||||
| if z {
|
| if z {
|
||||||
| ld a, 7
|
| ld x, 7
|
||||||
| } else {
|
| } else {
|
||||||
| ld a, 23
|
| ld x, 23
|
||||||
| }
|
| }
|
||||||
| }
|
| }
|
||||||
= ok
|
= ok
|
||||||
|
Loading…
Reference in New Issue
Block a user