55 lines
1.7 KiB
Haskell
55 lines
1.7 KiB
Haskell
module Main where
|
|
|
|
import Codegen.ClassFile (ClassFile, generateClassFile)
|
|
import Codegen.Serializer (serializeClassFile)
|
|
import qualified Data.ByteString as BS
|
|
import Grammar.AST (Program)
|
|
import Grammar.Parser (parse)
|
|
import Grammar.Scanner (Token, alexScanTokens)
|
|
import Grammar.TAST (TypedClass (Class))
|
|
import System.Environment (getArgs)
|
|
import Typecheck.SemanticChecker (typeCheckClass)
|
|
|
|
main :: IO ()
|
|
main = do
|
|
args <- getArgs
|
|
case args of
|
|
[path] -> runPipeline path
|
|
_ -> putStrLn "Usage: compoiler <input.java>"
|
|
|
|
runPipeline :: FilePath -> IO ()
|
|
runPipeline path = do
|
|
source <- readFile path
|
|
let tokens = scan source
|
|
let ast = parseProgram tokens
|
|
let typedClasses = typeCheckProgram ast
|
|
let classFiles = map generateClassFile typedClasses
|
|
mapM_ writeClassFile (zip typedClasses classFiles)
|
|
reportSuccess ast typedClasses classFiles
|
|
|
|
writeClassFile :: (TypedClass, ClassFile) -> IO ()
|
|
writeClassFile (tc, cf) = do
|
|
let outPath = "out/" ++ className tc ++ ".class"
|
|
BS.writeFile outPath (BS.pack (serializeClassFile cf))
|
|
putStrLn ("Written: " ++ outPath)
|
|
|
|
scan :: String -> [Token]
|
|
scan = alexScanTokens
|
|
|
|
parseProgram :: [Token] -> Program
|
|
parseProgram = parse
|
|
|
|
typeCheckProgram :: Program -> [TypedClass]
|
|
typeCheckProgram classes =
|
|
map (\cls -> typeCheckClass cls [] classes) classes
|
|
|
|
reportSuccess :: Program -> [TypedClass] -> [ClassFile] -> IO ()
|
|
reportSuccess ast typed classFiles = do
|
|
putStrLn ("Parsed classes: " ++ show (length ast))
|
|
putStrLn ("Typed classes: " ++ show (length typed))
|
|
putStrLn ("Generated class files: " ++ show (length classFiles))
|
|
putStrLn ("Class names: " ++ unwords (map className typed))
|
|
|
|
className :: TypedClass -> String
|
|
className (Class name _ _) = name
|