1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-06-07 22:29:27 +00:00

Checks for undeclared locations.

This commit is contained in:
Cat's Eye Technologies 2014-04-01 13:29:45 +01:00
parent 25b419b7c8
commit 16e29c9dc9
2 changed files with 52 additions and 12 deletions

View File

@ -110,9 +110,9 @@ Tests
A program may reserve and assign.
| reserve word score
| assign word scram 4000
| assign word screen 4000
| routine main {
| lda scram
| lda screen
| cmp score
| }
= True
@ -120,7 +120,31 @@ A program may reserve and assign.
All declarations (`reserve`s and `assign`s) must come before any `routines`.
| routine main {
| lda scram
| lda score
| }
| reserve word score
? expecting "routine"
All locations used in all routines must be declared first.
| reserve word score
| routine main {
| lda score
| cmp screen
| }
? undeclared location
Even in inner blocks.
| reserve word score
| assign word screen 4000
| routine main {
| lda score
| cmp screen
| beq {
| lda score
| } else {
| lda fnord
| }
| }
? undeclared location

View File

@ -4,6 +4,11 @@ module SixtyPical.Checker where
import SixtyPical.Model
allTrue = foldl (&&) True
trueOrDie message test =
if test then True else error message
routineDeclared routName (Program _ routines) =
elem routName (map (getRoutineName) routines)
where
@ -15,16 +20,27 @@ locationDeclared locName (Program decls _) =
getLocationName (Assign name _ _) = name
getLocationName (Reserve name _) = name
mainDeclared program =
if
routineDeclared "main" program
then
True
else
error "missing 'main' routine"
routineUsedLocations (Routine _ instrs) = blockUsedLocations instrs
blockUsedLocations [] = []
blockUsedLocations (instr:instrs) =
(instrUsedLocations instr) ++ blockUsedLocations instrs
instrUsedLocations (LOAD reg loc) = [loc]
instrUsedLocations (CMP reg loc) = [loc]
-- TODO: JSR...
instrUsedLocations (IFEQ b1 b2) =
blockUsedLocations b1 ++ blockUsedLocations b2
instrUsedLocations _ = []
allRoutineLocationsDeclared program routine =
allTrue (map (isDeclared) (routineUsedLocations routine))
where
isDeclared name = locationDeclared name program
allUsedLocationsDeclared p@(Program _ routines) =
True
allTrue (map (allRoutineLocationsDeclared p) routines)
checkProgram program =
mainDeclared program && allUsedLocationsDeclared program
trueOrDie "missing 'main' routine" (routineDeclared "main" program) &&
trueOrDie "undeclared location" (allUsedLocationsDeclared program)