module main import StdEnv import Data.Either import Data.Functor import Control.Monad => qualified join import System.GetOpt import System.CommandLine import parse import ast import check import int import gen chars :: *File -> ([Char], *File) chars f # (ok,c,f) = freadc f | not ok = ([], f) # (cs,f) = chars f = ([c:cs], f) :: Mode = MHelp | MLex | MParse | MType | MInterpret | MGen opts :: [OptDescr (Mode -> Mode)] opts = [ Option ['?'] ["help"] (NoArg (const MHelp)) "Display this message" , Option ['l'] ["lex"] (NoArg (const MLex)) "Up to and including lexing" , Option ['p'] ["parse"] (NoArg (const MParse)) "Up to and including parse" , Option ['t'] ["type"] (NoArg (const MType)) "Up to and including typing" , Option ['i'] ["interpret"] (NoArg (const MInterpret)) "Up to and including interpretation" , Option ['g'] ["gen"] (NoArg (const MGen)) "Up to and including generation" ] Start :: *World -> Either [String] [String] Start w # ([argv0:args], w) = getCommandLine w # (mode, positionals, errs) = getOpt Permute opts args # mode = foldl (o) id mode MInterpret | not (errs =: []) = Left [e +++ "\n"\\e<-errs] | not (positionals =: []) = Left ["Positional arguments not allowed"] # (io, w) = stdio w # (cs, io) = chars io # (_, w) = fclose io w = case mode of MHelp = Left [usageInfo ("Usage: " +++ argv0 +++ " [opts]\n") opts] MLex = map (\x->toString x +++ "\n") <$> lex cs MParse = map (\x->toString x +++ "\n") <$> (lex cs >>= parse) MType = (\(e, x)->["type: ",toString x, "\n", toString e]) <$> (lex cs >>= parse >>= check) MInterpret = (\x->[toString x]) <$> (lex cs >>= parse >>= check >>= int o fst) MGen = lex cs >>= parse >>= check >>= gen o fst