13 import System.CommandLine
15 from Text import class Text(concat), instance Text String
19 from yard import :: Error, instance toString Error
28 derive gPrint TokenValue
30 Start :: *World -> *World
32 # (args, w) = parseArgs w
35 # out = out <<< "Usage: " <<< args.program <<< " [opts] [FILENAME]\n"
36 <<< "\t--help Show this help\n"
37 <<< "\t--[no-]lex Lexer output(default: disabled)\n"
38 <<< "\t--[no-]parse Parser output(default: enabled)\n\n"
39 <<< "\tFILENAME File to parse, when unspecified stdin is parsed\n"
41 # (stdin, w) = stdio w
42 # (contents, stdin, w) = readFileOrStdin stdin args.fp w
44 (Left cs) = snd $ fclose (stdin <<< cs) w
47 # stdin = if (not args.lex) stdin (case lexOut of
49 stdin <<< "---LEXER\n" <<< printTokens toks <<< "---LEXER\n"
51 # parseOut = parser lexOut
52 # stdin = if (not args.parse) stdin (case parser lexOut of
54 stdin <<< "---PARSER\n" <<< toString ast <<< "---PARSER\n"
55 (Left parse) = stdin <<< toString parse)
56 = snd $ fclose stdin w
58 printTokens :: [Token] -> String
59 printTokens ts = concat $ flatten $ map pt ts
61 pt {line,column,token} = [toString line, ":",
62 toString column, ": ", printToString token, "\n"]
64 parseArgs :: *World -> (Opts, *World)
66 # ([p:args], w) = getCommandLine w
67 = (pa args {program=p, lex=False, parse=True, fp=Nothing, help=False}, w)
69 pa :: [String] Opts -> Opts
71 pa ["--help":r] o = pa r {o & help=True}
72 pa ["--lex":r] o = pa r {o & lex=True}
73 pa ["--no-lex":r] o = pa r {o & lex=False}
74 pa ["--parse":r] o = pa r {o & parse=True}
75 pa ["--no-parse":r] o = pa r {o & parse=False}
76 pa [x:r] o = pa r {o & fp=Just x}
78 readFileOrStdin :: *File (Maybe String) *World -> *(Either String [Char], *File, *World)
79 readFileOrStdin stdin Nothing w
80 # (cs, stdin) = readEntireFile stdin
81 = (Right cs, stdin, w)
82 readFileOrStdin stdin (Just fp) w
83 # (b, fin, w) = fopen fp FReadText w
84 | not b = (Left "Unable to open file", stdin, w)
85 # (cs, fin) = readEntireFile fin
86 # (b, w) = fclose fin w
87 | not b = (Left "Unable to close file", stdin, w)
88 = (Right cs, stdin, w)
90 readEntireFile :: *File -> *([Char], *File)
92 # (b, c, f) = freadc f
94 # (cs, f) = readEntireFile f