mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-04-13 18:37:03 +00:00
Checks for undeclared locations.
This commit is contained in:
parent
25b419b7c8
commit
16e29c9dc9
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user