4739c359e5761d9930563fa6c421da93ed95ae07
[cc1516.git] / src / main.icl
1 module main
2
3 import StdFile
4 import StdBool
5 import StdMisc
6 import StdFunc
7 import StdList
8 import StdString
9 import Data.Either
10 import Data.Maybe
11 import System.CommandLine
12
13 import parse
14 import lex
15
16 :: Opts = {
17 program :: String,
18 lex :: Bool,
19 parse :: Bool,
20 fp :: Maybe String,
21 help :: Bool}
22
23 :: *StartType :== (LexerOutput, ParserOutput, *World)
24
25 parseArgs :: *World -> (Opts, *World)
26 parseArgs w
27 # ([p:args], w) = getCommandLine w
28 = (pa args {program=p, lex=False, parse=False, fp=Nothing, help=False}, w)
29 where
30 pa :: [String] -> (Opts -> Opts)
31 pa [] = id
32 pa ["--help":r] = \o.pa r {o & help=True}
33 pa ["--lex":r] = \o.pa r {o & lex=True, parse=False}
34 pa ["--parse":r] = \o.pa r {o & lex=False, parse=True}
35 pa [x:r] = \o.pa r {o & fp=Just x}
36
37 //Start :: *World -> (LexerOutput, ParserOutput, *World)
38 //Start w
39 //# (args, w) = getCommandLine w
40 //# (toparse, out) = readEntireFile out
41 //= (lexer toparse, parse (lexer toparse), w)
42
43 Start :: *World -> *StartType
44 Start w
45 # (args, w) = parseArgs w
46 | args.help = help args.program w
47 # (stdin, w) = stdio w
48 # (contents, stdin, w) = readFileOrStdin stdin args.fp w
49 | args.lex = case contents of
50 (Right cs) = (lexer cs, Left "Parsing Disabled", w)
51 (Left e) = (Left e, Left "Parsing disabled", w)
52 = case contents of
53 (Left e) = (Left e, Left "", w)
54 (Right cs) = let lexOut = lexer cs in (lexOut, parser lexOut, w)
55
56 readFileOrStdin :: *File (Maybe String) *World -> *(Either String [Char], *File, *World)
57 readFileOrStdin stdin Nothing w
58 # (cs, stdin) = readEntireFile stdin
59 = (Right cs, stdin, w)
60 readFileOrStdin stdin (Just fp) w
61 # (b, fin, w) = fopen fp FReadText w
62 | not b = (Left "Unable to open file", stdin, w)
63 # (cs, fin) = readEntireFile fin
64 # (_, w) = fclose fin w
65 = (Right cs, stdin, w)
66
67 readEntireFile :: *File -> *([Char], *File)
68 readEntireFile f
69 # (b, c, f) = freadc f
70 | not b = ([], f)
71 # (cs, f) = readEntireFile f
72 = ([c:cs], f)
73
74 help :: String *World -> *StartType
75 help p w
76 # (out, w) = stdio w
77 # out = out <<< "\nUsage: " <<< p <<< " [opts] [FILENAME]\n"
78 <<< "\t--help Show this help\n"
79 <<< "\t--lex Lex only, is mutually exclusive with --parse\n"
80 <<< "\t--parse Lex & Parse only\n\n"
81 <<< "\tFILENAME File to parse, when unspecified stdin is parsed\n"
82 # (_, w) = fclose out w
83 = (Left "", Left "", w)
84