import StdFile
import StdBool
+import StdMisc
+import StdFunc
+import StdTuple
+import StdList
+import StdString
+import Data.Either
+import Data.Maybe
+import Data.Func
+import System.CommandLine
+import GenPrint
+from Text import class Text(concat), instance Text String
import parse
import lex
+from yard import :: Error, instance toString Error
-Start :: *World -> (LexerOutput, ParserOutput, *World)
+:: Opts = {
+ version :: Bool,
+ program :: String,
+ lex :: Bool,
+ parse :: Bool,
+ fp :: Maybe String,
+ help :: Bool}
+
+derive gPrint TokenValue
+
+Start :: *World -> *World
Start w
-# (out, w) = stdio w
-# (toparse, out) = readEntireFile out
-# (_, w) = fclose out w
-= (lexer toparse, parse (lexer toparse), w)
+# (args, w) = parseArgs w
+# (stdin, w) = stdio w
+| args.version
+ # stdin = stdin
+ <<< "main 0.1 (17 march 2016)\n"
+ <<< "Copyright Pim Jager and Mart Lubbers\n"
+ = snd $ fclose stdin w
+| args.help
+ # stdin = stdin
+ <<< "Usage: " <<< args.program <<< " [OPTION] [FILE]\n"
+ <<< "Lex parse and either FILE or stdin\n"
+ <<< "\n"
+ <<< "Options:\n"
+ <<< " --help Show this help\n"
+ <<< " --version Show the version\n"
+ <<< " --[no-]lex Lexer output(default: disabled)\n"
+ <<< " --[no-]parse Parser output(default: enabled)\n"
+ = snd $ fclose stdin w
+# (contents, stdin, w) = readFileOrStdin stdin args.fp w
+= case contents of
+ (Left cs) = snd $ fclose (stdin <<< cs) w
+ (Right cs)
+ # lexOut = lexer cs
+ # stdin = if (not args.lex) stdin (case lexOut of
+ (Right toks) =
+ stdin <<< "---LEXER\n" <<< printTokens toks <<< "---LEXER\n"
+ _ = stdin)
+ # parseOut = parser lexOut
+ # stdin = if (not args.parse) stdin (case parser lexOut of
+ (Right ast) =
+ stdin <<< "---PARSER\n" <<< toString ast <<< "---PARSER\n"
+ (Left parse) = stdin <<< toString parse)
+ = snd $ fclose stdin w
+ where
+ printTokens :: [Token] -> String
+ printTokens ts = concat $ flatten $ map pt ts
+ where
+ pt {line,column,token} = [toString line, ":",
+ toString column, ": ", printToString token, "\n"]
+
+parseArgs :: *World -> (Opts, *World)
+parseArgs w
+# ([p:args], w) = getCommandLine w
+= (pa args {
+ program=p,
+ version=False,
+ lex=False,
+ parse=True,
+ fp=Nothing,
+ help=False}, w)
+where
+ pa :: [String] Opts -> Opts
+ pa [] o = o
+ pa ["--help":r] o = pa r {o & help=True}
+ pa ["--version":r] o = pa r {o & version=True}
+ pa ["--lex":r] o = pa r {o & lex=True}
+ pa ["--no-lex":r] o = pa r {o & lex=False}
+ pa ["--parse":r] o = pa r {o & parse=True}
+ pa ["--no-parse":r] o = pa r {o & parse=False}
+ 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