working main program and part of parser
[cc1516.git] / src / main.icl
index 9bc8d20..4739c35 100644 (file)
@@ -2,16 +2,67 @@ 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
 
-Start :: *World -> (LexerOutput, ParserOutput, *World)
+:: Opts = {
+       program :: String,
+       lex :: Bool,
+       parse :: Bool,
+       fp :: Maybe String,
+       help :: Bool}
+
+:: *StartType :== (LexerOutput, ParserOutput, *World)
+
+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}
+
+//Start :: *World -> (LexerOutput, ParserOutput, *World)
+//Start w
+//# (args, w) = getCommandLine w
+//# (toparse, out) = readEntireFile out
+//= (lexer toparse, parse (lexer toparse), w)
+
+Start :: *World -> *StartType
 Start w
-# (out, w) = stdio w
-# (toparse, out) = readEntireFile out
-# (_, w) = fclose out w
-= (lexer toparse, parse (lexer toparse), w)
+# (args, w) = parseArgs w
+| args.help = help args.program 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) = let lexOut = lexer cs in (lexOut, parser lexOut, w)
+
+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
+# (_, w) = fclose fin w
+= (Right cs, stdin, w)
 
 readEntireFile :: *File -> *([Char], *File)
 readEntireFile f
@@ -19,3 +70,15 @@ readEntireFile f
 | not b = ([], f)
 # (cs, f) = readEntireFile f
 = ([c:cs], f)
+
+help :: String *World -> *StartType
+help p w
+# (out, w) = stdio w
+# out = out <<< "\nUsage: " <<< p <<< " [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)
+