13 import System.CommandLine
15 from Text import class Text(concat), instance Text String
20 from yard import :: Error, instance toString Error
31 derive gPrint TokenValue
33 Start :: *World -> *World
35 # (args, w) = parseArgs w
36 # (stdin, w) = stdio w
39 <<< "spl 0.1 (17 march 2016)\n"
40 <<< "Copyright Pim Jager and Mart Lubbers\n"
41 = snd $ fclose stdin w
44 <<< "Usage: " <<< args.program <<< " [OPTION] [FILE]\n"
45 <<< "<spl> ::= <spl> <parser> <lexer>\n"
46 <<< "Lex parse and either FILE or stdin\n"
49 <<< " --help Show this help\n"
50 <<< " --version Show the version\n"
51 <<< " --[no-]lex Lexer output(default: disabled)\n"
52 <<< " --[no-]parse Parser output(default: enabled)\n"
53 <<< " --[no-]selftest Feed pprint parse back(default: disabled)\n"
54 = snd $ fclose stdin w
55 # (contents, stdin, w) = readFileOrStdin stdin args.fp w
57 (Left cs) = snd $ fclose (stdin <<< cs) w
60 # stdin = if (not args.lex) stdin (case lexOut of
62 stdin <<< "---LEXER\n" <<< printTokens toks <<< "---LEXER\n"
64 # parseOut = parser lexOut
65 # stdin = if (not args.parse) stdin (case parser lexOut of
67 stdin <<< "---PARSER\n" <<< toString ast <<< "---PARSER\n"
68 (Left parse) = stdin <<< toString parse)
69 = snd $ fclose stdin w
71 printTokens :: [Token] -> String
72 printTokens ts = concat $ flatten $ map pt ts
74 pt ({line,col},token) = [toString line, ":",
75 toString col, ": ", printToString token, "\n"]
77 parseArgs :: *World -> (Opts, *World)
79 # ([p:args], w) = getCommandLine w
89 pa :: [String] Opts -> Opts
91 pa ["--help":r] o = pa r {o & help=True}
92 pa ["--version":r] o = pa r {o & version=True}
93 pa ["--lex":r] o = pa r {o & lex=True}
94 pa ["--no-lex":r] o = pa r {o & lex=False}
95 pa ["--parse":r] o = pa r {o & parse=True}
96 pa ["--no-parse":r] o = pa r {o & parse=False}
97 pa ["--selftest":r] o = pa r {o & selftest=True}
98 pa ["--no-selftest":r] o = pa r {o & selftest=False}
99 pa [x:r] o = pa r {o & fp=Just x}
101 readFileOrStdin :: *File (Maybe String) *World -> *(Either String [Char], *File, *World)
102 readFileOrStdin stdin Nothing w
103 # (cs, stdin) = readEntireFile stdin
104 = (Right cs, stdin, w)
105 readFileOrStdin stdin (Just fp) w
106 # (b, fin, w) = fopen fp FReadText w
107 | not b = (Left "Unable to open file", stdin, w)
108 # (cs, fin) = readEntireFile fin
109 # (b, w) = fclose fin w
110 | not b = (Left "Unable to close file", stdin, w)
111 = (Right cs, stdin, w)
113 readEntireFile :: *File -> *([Char], *File)
115 # (b, c, f) = freadc f
117 # (cs, f) = readEntireFile f