From 16e29c9dc9fc12e4c4c68ed0b7da648608b3372b Mon Sep 17 00:00:00 2001 From: Cat's Eye Technologies Date: Tue, 1 Apr 2014 13:29:45 +0100 Subject: [PATCH] Checks for undeclared locations. --- README.markdown | 30 +++++++++++++++++++++++++++--- src/SixtyPical/Checker.hs | 34 +++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/README.markdown b/README.markdown index 3a7c90f..918aa18 100644 --- a/README.markdown +++ b/README.markdown @@ -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 diff --git a/src/SixtyPical/Checker.hs b/src/SixtyPical/Checker.hs index 94d2883..26ac73f 100644 --- a/src/SixtyPical/Checker.hs +++ b/src/SixtyPical/Checker.hs @@ -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)