module main import StdFile import StdBool import StdMisc import StdFunc import StdList import StdString import Data.Either import Data.Maybe import System.CommandLine import parse import lex :: Opts = { program :: String, lex :: Bool, parse :: Bool, fp :: Maybe String, help :: Bool} :: *StartType :== (LexerOutput, ParserOutput, *World) Start :: *World -> *StartType Start w # (args, w) = parseArgs w | args.help # (out, w) = stdio w # out = out <<< "\nUsage: " <<< args.program <<< " [opts] [FILENAME]\n" <<< "\t--help Show this help\n" <<< "\t--lex Lex only, is mutually exclusive with --parse\n" <<< "\t--parse Lex & Parse only\n\n" <<< "\tFILENAME File to parse, when unspecified stdin is parsed\n" # (_, w) = fclose out w = (Left "", Left "", w) # (stdin, w) = stdio w # (contents, stdin, w) = readFileOrStdin stdin args.fp w | args.lex = case contents of (Right cs) = (lexer cs, Left "Parsing Disabled", w) (Left e) = (Left e, Left "Parsing disabled", w) = case contents of (Left e) = (Left e, Left "", w) (Right cs) # lexout = lexer cs # parsout = parser lexout # stdin = stdin <<< (either (const "") toString parsout) # (_, w) = fclose stdin w = (lexout, parser lexout, w) parseArgs :: *World -> (Opts, *World) parseArgs w # ([p:args], w) = getCommandLine w = (pa args {program=p, lex=False, parse=False, fp=Nothing, help=False}, w) where pa :: [String] -> (Opts -> Opts) pa [] = id pa ["--help":r] = \o.pa r {o & help=True} pa ["--lex":r] = \o.pa r {o & lex=True, parse=False} pa ["--parse":r] = \o.pa r {o & lex=False, parse=True} pa [x:r] = \o.pa r {o & fp=Just x} readFileOrStdin :: *File (Maybe String) *World -> *(Either String [Char], *File, *World) readFileOrStdin stdin Nothing w # (cs, stdin) = readEntireFile stdin = (Right cs, stdin, w) readFileOrStdin stdin (Just fp) w # (b, fin, w) = fopen fp FReadText w | not b = (Left "Unable to open file", stdin, w) # (cs, fin) = readEntireFile fin # (b, w) = fclose fin w | not b = (Left "Unable to close file", stdin, w) = (Right cs, stdin, w) readEntireFile :: *File -> *([Char], *File) readEntireFile f # (b, c, f) = freadc f | not b = ([], f) # (cs, f) = readEntireFile f = ([c:cs], f)