diff --git a/README.markdown b/README.markdown index 2a4048a..0134610 100644 --- a/README.markdown +++ b/README.markdown @@ -182,3 +182,33 @@ No duplicate declarations. | nop | } ? duplicate declaration + + -> Tests for functionality "Emit ASM for SixtyPical program" + + -> Functionality "Emit ASM for SixtyPical program" is implemented by + -> shell command "bin/sixtypical emit %(test-file)" + + | reserve word score + | assign word screen 4000 + | routine main { + | lda screen + | tax + | tay + | cmp score + | ldx score + | txa + | ldy score + | tya + | } + = (decl) + = (decl) + = main: + = lda screen + = tax + = tay + = cmp score + = (instr) + = txa + = (instr) + = tya + = rts diff --git a/src/Main.hs b/src/Main.hs index 74a22f4..8708629 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -10,11 +10,12 @@ import SixtyPical.Model import SixtyPical.Parser (parseProgram) import SixtyPical.Checker (checkProgram) import SixtyPical.Analyzer (analyzeProgram) +import SixtyPical.Emitter (emitProgram) -- -- -- -- driver -- -- -- -- usage = do - putStrLn "Usage: sixtypical (parse|check|analyze) filename.60pical" + putStrLn "Usage: sixtypical (parse|check|analyze|emit) filename.60pical" exitWith $ ExitFailure 1 main = do @@ -28,7 +29,15 @@ main = do ("check", Right program) -> do putStrLn $ show $ checkProgram program ("analyze", Right program) -> do - putStrLn $ show $ analyzeProgram program + case checkProgram program of + True -> + putStrLn $ show $ analyzeProgram program + ("emit", Right program) -> do + case checkProgram program of + True -> + case analyzeProgram program of + _ -> + putStr $ emitProgram program (_, Left problem) -> do hPutStrLn stderr (show problem) exitWith $ ExitFailure 1 diff --git a/src/SixtyPical/Emitter.hs b/src/SixtyPical/Emitter.hs new file mode 100644 index 0000000..e6e0059 --- /dev/null +++ b/src/SixtyPical/Emitter.hs @@ -0,0 +1,35 @@ +-- encoding: UTF-8 + +module SixtyPical.Emitter where + +import SixtyPical.Model + +emitProgram p@(Program decls routines) = + emitDecls p decls ++ + emitRoutines p routines + +emitDecls _ [] = "" +emitDecls p (decl:decls) = + emitDecl p decl ++ "\n" ++ emitDecls p decls + +emitDecl p _ = "(decl)" + +emitRoutines _ [] = "" +emitRoutines p (rout:routs) = + emitRoutine p rout ++ "\n" ++ emitRoutines p routs + +emitRoutine p r@(Routine name instrs) = + name ++ ":\n" ++ emitInstrs p r instrs ++ " rts\n" + +emitInstrs _ _ [] = "" +emitInstrs p r (instr:instrs) = + " " ++ emitInstr p r instr ++ "\n" ++ emitInstrs p r instrs + +emitInstr p r (LOAD A label) = "lda " ++ label +emitInstr p r (CMP A label) = "cmp " ++ label + +emitInstr p r (COPY A X) = "tax" +emitInstr p r (COPY A Y) = "tay" +emitInstr p r (COPY X A) = "txa" +emitInstr p r (COPY Y A) = "tya" +emitInstr p r _ = "(instr)"