From 6192a6a7f8507d17a6854412fc9a7a97babdf448 Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Fri, 16 Oct 2015 09:38:38 +0100 Subject: [PATCH] Add specific error for uninit outputs. Sketch `if` analysis. --- src/sixtypical/analyzer.py | 17 +++++++++++++---- tests/SixtyPical Analysis.md | 20 ++++++++++---------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/sixtypical/analyzer.py b/src/sixtypical/analyzer.py index 71e3a1b..817b039 100644 --- a/src/sixtypical/analyzer.py +++ b/src/sixtypical/analyzer.py @@ -18,6 +18,10 @@ class UninitializedAccessError(StaticAnalysisError): pass +class UninitializedOutputError(StaticAnalysisError): + pass + + class IllegalWriteError(StaticAnalysisError): pass @@ -44,13 +48,14 @@ class Context(): self._store.setdefault(ref.name, UNINITIALIZED) 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: if isinstance(ref, ConstantRef): pass elif isinstance(ref, LocationRef): if self.get(ref) != INITIALIZED: - raise UninitializedAccessError(ref.name) + raise exception_class(ref.name) else: raise ValueError(ref) @@ -94,7 +99,7 @@ def analyze_routine(routine, routines): context = Context(routine.inputs, routine.outputs, routine.trashes) analyze_block(routine.block, context, routines) for ref in routine.outputs: - context.assertInitialized(ref) + context.assertInitialized(ref, exception_class=UninitializedOutputError) def analyze_block(block, context, routines): @@ -154,6 +159,10 @@ def analyze_instr(instr, context, routines): context.assertWriteable(ref) context.setUninitialized(ref) 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: raise NotImplementedError diff --git a/tests/SixtyPical Analysis.md b/tests/SixtyPical Analysis.md index 7f90117..3c8478e 100644 --- a/tests/SixtyPical Analysis.md +++ b/tests/SixtyPical Analysis.md @@ -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. [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)" - -> Tests for functionality "Analyze Sixtypical program" + -> Tests for functionality "Analyze SixtyPical program" ### Rudiments ### @@ -42,7 +42,7 @@ If a routine declares it outputs a location, that location should be initialized | { | ld x, 0 | } - ? UninitializedAccessError: a + ? UninitializedOutputError: a | routine main | inputs a @@ -318,7 +318,7 @@ You can't output a value that the thing you called trashed. | ld x, 0 | call foo | } - ? UninitializedAccessError: lives + ? UninitializedOutputError: lives ...unless you write to it yourself afterwards. @@ -402,14 +402,14 @@ Both blocks of an `if` are analyzed. | routine foo | inputs a - | outputs a - | trashes z, n, c + | outputs x + | trashes a, z, n, c | { | cmp a, 42 | if z { - | ld a, 7 + | ld x, 7 | } else { - | ld a, 23 + | ld x, 23 | } | } = ok