sem update'
[cc1516.git] / spl.icl
1 module spl
2
3 import StdFile
4 import StdBool
5 import StdMisc
6 import StdFunc
7 import StdTuple
8 import StdList
9 import StdString
10 import Data.Either
11 import Data.Maybe
12 import Data.Func
13 import System.CommandLine
14 import GenPrint
15 from Text import class Text(concat), instance Text String
16
17 import parse
18 import lex
19 import sem
20 import AST
21 from yard import :: Error, instance toString Error
22
23 :: Opts = {
24 version :: Bool,
25 program :: String,
26 lex :: Bool,
27 parse :: Bool,
28 fp :: Maybe String,
29 help :: Bool}
30
31 derive gPrint TokenValue
32
33 Start :: *World -> *World
34 Start w
35 # (args, w) = parseArgs w
36 # (stdin, w) = stdio w
37 | args.version
38 # stdin = stdin
39 <<< "spl 0.1 (17 march 2016)\n"
40 <<< "Copyright Pim Jager and Mart Lubbers\n"
41 = snd $ fclose stdin w
42 | args.help
43 # stdin = stdin
44 <<< "Usage: " <<< args.program <<< " [OPTION] [FILE]\n"
45 <<< "<spl> ::= <spl> <parser> <lexer>\n"
46 <<< "Lex parse and either FILE or stdin\n"
47 <<< "\n"
48 <<< "Options:\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 = snd $ fclose stdin w
54 # (contents, stdin, w) = readFileOrStdin stdin args.fp w
55 = case contents of
56 (Left cs) = snd $ fclose (stdin <<< cs) w
57 (Right cs)
58 # lexOut = lexer cs
59 # stdin = if (not args.lex) stdin (case lexOut of
60 (Right toks) =
61 stdin <<< "//LEXER\n" <<< printTokens toks <<< "//LEXER\n"
62 _ = stdin)
63 # parseOut = parser lexOut
64 # stdin = if (not args.parse) stdin (case parseOut of
65 (Right ast) =
66 stdin <<< "//PARSER\n" <<< toString ast <<< "//PARSER\n"
67 (Left parse) = stdin <<< toString parse)
68 # semOut = sem parseOut
69 # stdin = case semOut of
70 (Right ast) =
71 stdin <<< "//TYPE\n" <<< toString ast <<< "//TYPE\n"
72 (Left parse) = stdin <<< toString parse
73 = snd $ fclose stdin w
74 where
75 printTokens :: [Token] -> String
76 printTokens ts = concat $ flatten $ map pt ts
77 where
78 pt ({line,col},token) = [toString line, ":",
79 toString col, ": ", printToString token, "\n"]
80
81 parseArgs :: *World -> (Opts, *World)
82 parseArgs w
83 # ([p:args], w) = getCommandLine w
84 = (pa args {
85 program=p,
86 version=False,
87 lex=False,
88 parse=True,
89 fp=Nothing,
90 help=False}, w)
91 where
92 pa :: [String] Opts -> Opts
93 pa [] o = o
94 pa ["--help":r] o = pa r {o & help=True}
95 pa ["--version":r] o = pa r {o & version=True}
96 pa ["--lex":r] o = pa r {o & lex=True}
97 pa ["--no-lex":r] o = pa r {o & lex=False}
98 pa ["--parse":r] o = pa r {o & parse=True}
99 pa ["--no-parse":r] o = pa r {o & parse=False}
100 pa [x:r] o = pa r {o & fp=Just x}
101
102 readFileOrStdin :: *File (Maybe String) *World -> *(Either String [Char], *File, *World)
103 readFileOrStdin stdin Nothing w
104 # (cs, stdin) = readEntireFile stdin
105 = (Right cs, stdin, w)
106 readFileOrStdin stdin (Just fp) w
107 # (b, fin, w) = fopen fp FReadText w
108 | not b = (Left "Unable to open file", stdin, w)
109 # (cs, fin) = readEntireFile fin
110 # (b, w) = fclose fin w
111 | not b = (Left "Unable to close file", stdin, w)
112 = (Right cs, stdin, w)
113
114 readEntireFile :: *File -> *([Char], *File)
115 readEntireFile f
116 # (b, c, f) = freadc f
117 | not b = ([], f)
118 # (cs, f) = readEntireFile f
119 = ([c:cs], f)