1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2025-02-12 20:30:27 +00:00

checkProgram wasn't deeply evaluating the thing. Merge stuff.

This commit is contained in:
Cat's Eye Technologies 2014-04-02 19:25:41 +01:00
parent c0676f9efa
commit a68f8a97d6
5 changed files with 46 additions and 75 deletions

View File

@ -562,7 +562,7 @@ We cannot absolute-indexed a word.
= score: .word 0
= .alias screen 1024
| assign word screen $0400
| assign byte screen $0400
| routine main {
| lda screen
| cmp screen

View File

@ -18,11 +18,6 @@ usage = do
putStrLn "Usage: sixtypical (parse|check|analyze|emit) filename.60pical"
exitWith $ ExitFailure 1
checkProgram p =
case checkAndTransformProgram p of
Just newprog ->
True
main = do
args <- getArgs
case args of
@ -32,7 +27,9 @@ main = do
("parse", Right program) -> do
putStrLn $ show $ program
("check", Right program) -> do
putStrLn $ show $ checkProgram program
case checkAndTransformProgram program of
Just newprog ->
putStrLn $ programSummary newprog
("analyze", Right program) ->
case checkAndTransformProgram program of
Just newprog ->

View File

@ -9,38 +9,11 @@ allTrue = foldl (&&) True
trueOrDie message test =
if test then True else error message
-- in the following, we mean Named locations
routineUsedLocations (Routine _ instrs) = blockUsedLocations instrs
blockUsedLocations [] = []
blockUsedLocations (instr:instrs) =
(instrUsedLocations instr) ++ blockUsedLocations instrs
--instrUsedLocations (LOADIMM reg (NamedLocation loc)) = [loc]
instrUsedLocations (COPY (NamedLocation sz loc) _) = [loc]
instrUsedLocations (COPY _ (NamedLocation sz loc)) = [loc]
instrUsedLocations (CMP reg (NamedLocation sz loc)) = [loc]
-- TODO: JSR...
instrUsedLocations (IF _ branch b1 b2) =
blockUsedLocations b1 ++ blockUsedLocations b2
instrUsedLocations (REPEAT _ branch blk) =
blockUsedLocations blk
instrUsedLocations _ = []
allRoutineLocationsDeclared program routine =
allTrue (map (isDeclared) (routineUsedLocations routine))
where
isDeclared name = locationDeclared name program
allUsedLocationsDeclared p@(Program _ routines) =
allTrue (map (allRoutineLocationsDeclared p) routines)
-- --
isUnique [] = True
isUnique (x:xs) = (not (x `elem` xs)) && isUnique xs
-- --
noDuplicateDecls program =
isUnique $ declaredLocationNames program
@ -49,20 +22,6 @@ noDuplicateRoutines program =
-- 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 sz 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
noIndexedAccessOfNonTables p@(Program decls routines) =
let
mappedProgram = mapProgramRoutines (checkInstr) p
@ -151,31 +110,35 @@ numberInstruction i iid = (i, iid)
fillOutNamedLocationTypes p@(Program decls routines) =
mapProgramRoutines (xform) p
where
xform j@(COPY src dest) =
xform (COPY src dest) =
COPY (resolve src) (resolve dest)
xform j@(CMP dest other) =
xform (CMP dest other) =
CMP (resolve dest) (resolve other)
xform j@(ADD dest other) =
xform (ADD dest other) =
ADD (resolve dest) (resolve other)
xform j@(AND dest other) =
xform (AND dest other) =
AND (resolve dest) (resolve other)
xform j@(SUB dest other) =
xform (SUB dest other) =
SUB (resolve dest) (resolve other)
xform j@(OR dest other) =
xform (OR dest other) =
OR (resolve dest) (resolve other)
xform j@(JMPVECTOR dest) =
JMPVECTOR (resolve dest)
xform j@(IF iid branch b1 b2) =
xform (JMPVECTOR dest) =
case (resolve dest) of
d@(NamedLocation (Just Vector) _) ->
JMPVECTOR d
_ ->
error ("jmp to non-vector '" ++ (show dest) ++ "'")
xform (IF iid branch b1 b2) =
IF iid branch (mapBlock xform b1) (mapBlock xform b2)
xform j@(REPEAT iid branch blk) =
xform (REPEAT iid branch blk) =
REPEAT iid branch (mapBlock xform blk)
xform j@(DELTA dest val) =
xform (DELTA dest val) =
DELTA (resolve dest) val
xform j@(SEI blk) =
xform (SEI blk) =
SEI (mapBlock xform blk)
xform j@(COPYVECTOR src dest) =
xform (COPYVECTOR src dest) =
COPYVECTOR (resolve src) (resolve dest)
xform j@(COPYROUTINE name dest) =
xform (COPYROUTINE name dest) =
COPYROUTINE name (resolve dest)
xform other =
other
@ -185,17 +148,23 @@ fillOutNamedLocationTypes p@(Program decls routines) =
(NamedLocation (Just $ getDeclLocationType decl) name)
_ ->
error ("undeclared location '" ++ name ++ "'")
resolve (Indirect loc) =
(Indirect (resolve loc))
resolve (Indexed loc reg) =
(Indexed (resolve loc) (resolve reg))
resolve (IndirectIndexed loc reg) =
(IndirectIndexed (resolve loc) (resolve reg))
resolve other =
other
-- - - - - - -
checkAndTransformProgram :: Program -> Maybe Program
checkAndTransformProgram program =
if
trueOrDie "missing 'main' routine" (routineDeclared "main" program) &&
trueOrDie "undeclared location" (allUsedLocationsDeclared program) &&
trueOrDie "duplicate location name" (noDuplicateDecls program) &&
trueOrDie "duplicate routine name" (noDuplicateRoutines program) &&
trueOrDie "jmp to non-vector" (noJmpsToNonVectors program) &&
trueOrDie "undeclared routine" (noUseOfUndeclaredRoutines program) &&
trueOrDie "indexed access of non-table" (noIndexedAccessOfNonTables program)
then
@ -205,5 +174,3 @@ checkAndTransformProgram program =
in
Just program''
else Nothing
-- - - - - - -

View File

@ -54,11 +54,11 @@ emitInstr p r (COPY A Y) = "tay"
emitInstr p r (COPY X A) = "txa"
emitInstr p r (COPY Y A) = "tya"
emitInstr p r (COPY A (Indexed (NamedLocation st label) X)) = "sta " ++ label ++ ", x"
emitInstr p r (COPY A (Indexed (NamedLocation st label) Y)) = "sta " ++ label ++ ", y"
emitInstr p r (COPY A (Indexed (NamedLocation (Just ByteTable) label) X)) = "sta " ++ label ++ ", x"
emitInstr p r (COPY A (Indexed (NamedLocation (Just ByteTable) label) Y)) = "sta " ++ label ++ ", y"
emitInstr p r (COPY (Indexed (NamedLocation st label) X) A) = "lda " ++ label ++ ", x"
emitInstr p r (COPY (Indexed (NamedLocation st label) Y) A) = "lda " ++ label ++ ", y"
emitInstr p r (COPY (Indexed (NamedLocation (Just ByteTable) label) X) A) = "lda " ++ label ++ ", x"
emitInstr p r (COPY (Indexed (NamedLocation (Just ByteTable) label) Y) A) = "lda " ++ label ++ ", y"
emitInstr p r (COPY A (IndirectIndexed (NamedLocation st label) Y)) = "sta (" ++ label ++ "), y"

View File

@ -84,6 +84,10 @@ data Program = Program [Decl] [Routine]
-- -- -- accessors and helpers -- -- --
-- bit of a hack to deepseq the eval
programSummary p@(Program decls routs) =
show ((length $ show p) < 99999)
getRoutineName (Routine name _) = name
getDeclLocationName (Assign name _ _) = name
@ -128,11 +132,14 @@ mapRoutines f (rout:routs) =
mapProgramRoutines :: (Instruction -> Instruction) -> Program -> Program
mapProgramRoutines f (Program decls routs) = Program decls $ mapRoutines f routs
lookupDecl (Program [] _) _ = Nothing
lookupDecl (Program (decl:decls) routs) name =
lookupDecl (Program decls _) name =
lookupDecl' (filter (isLocationDecl) decls) name
lookupDecl' [] _ = Nothing
lookupDecl' (decl:decls) name =
if
(getDeclLocationName decl) == name
then
Just decl
else
lookupDecl (Program decls routs) name
lookupDecl' decls name