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:
parent
cb0fe91a8a
commit
22d061fb73
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user