1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-11-22 01:32:13 +00:00

No duplicate routine names, jmps must be to vectors.

This commit is contained in:
Cat's Eye Technologies 2014-04-01 22:29:50 +01:00
parent cb0fe91a8a
commit 22d061fb73
2 changed files with 61 additions and 21 deletions

View File

@ -264,7 +264,6 @@ TODO
* Work out the analyses again and document them
* `repeat jmp`
* Addressing modes; rename instructions to match
* no two routines with same name
Tests
-----
@ -339,14 +338,24 @@ Even in inner blocks.
| }
? undeclared location
No duplicate declarations.
No duplicate location names in declarations.
| reserve word score
| assign word score 4000
| routine main {
| nop
| }
? duplicate declaration
? duplicate location name
No duplicate routine names..
| routine main {
| nop
| }
| routine main {
| txa
| }
? duplicate routine name
We can jump to a vector.
@ -358,11 +367,19 @@ We can jump to a vector.
We can't jump to a word.
*| reserve word blah
*| routine main {
*| jmp blah
*| }
*? wtf
| reserve word blah
| routine main {
| jmp blah
| }
? jmp to non-vector
We can't jump to a byte.
| assign byte screen 1024
| routine main {
| jmp screen
| }
? jmp to non-vector
-> Tests for functionality "Emit ASM for SixtyPical program"

View File

@ -19,7 +19,15 @@ getDeclLocationName (Reserve name _) = name
locationDeclared locName (Program decls _) =
elem locName (map (getDeclLocationName) decls)
where
lookupDecl (Program [] _) _ = Nothing
lookupDecl (Program (decl:decls) routs) name =
if
(getDeclLocationName decl) == name
then
Just decl
else
lookupDecl (Program decls routs) name
-- in the following, we mean Named locations
@ -48,26 +56,41 @@ allRoutineLocationsDeclared program routine =
allUsedLocationsDeclared p@(Program _ routines) =
allTrue (map (allRoutineLocationsDeclared p) routines)
isUnique [] = True
isUnique (x:xs) = (not (x `elem` xs)) && isUnique xs
noDuplicateDecls p@(Program decls routines) =
collectDecls decls []
isUnique (map (getDeclLocationName) decls)
noDuplicateRoutines p@(Program decls routines) =
isUnique (map (getRoutineName) routines)
where
collectDecls [] acc = True
collectDecls (decl:decls) acc =
if
name `elem` acc
then
error ("duplicate declaration '" ++ name ++ "'")
else
collectDecls decls (name:acc)
where
name = getDeclLocationName decl
getRoutineName (Routine name _) = name
-- wow. efficiency is clearly our watchword
-- (and sarcasm is our backup watchword)
noJmpsToNonVectors p@(Program decls routines) =
let
mappedProgram = mapProgramRoutines (checkInstr) p
in
mappedProgram == p
where
checkInstr j@(JMPVECTOR (NamedLocation g)) =
case lookupDecl p g of
Just (Assign _ Vector _) -> j
Just (Reserve _ Vector) -> j
Just _ -> (COPY A A)
Nothing -> (COPY A A)
checkInstr other = other
checkAndTransformProgram :: Program -> Maybe Program
checkAndTransformProgram program =
if
trueOrDie "missing 'main' routine" (routineDeclared "main" program) &&
trueOrDie "undeclared location" (allUsedLocationsDeclared program) &&
noDuplicateDecls program
trueOrDie "duplicate location name" (noDuplicateDecls program) &&
trueOrDie "duplicate routine name" (noDuplicateRoutines program) &&
trueOrDie "jmp to non-vector" (noJmpsToNonVectors program)
then
Just $ numberProgramLoops program
else Nothing