1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
module snug
import StdEnv
import StdMaybe
import Data.Error
import Data.List
import System.CommandLine
import System.File
import System.FilePath
import Text
import MIPS.MIPS32
import Snug.Compile
import Snug.Parse
/* Note: after compiling with
* snug program.snug
* an assembly file program.s is generated, which can be run with SPIM using
* spim -delayed_branches <(cat driver.s program.s)
*/
Start w
# ([prog:args],w) = getCommandLine w
| length args <> 1 = abort ("Usage: " +++ prog +++ " INPUT\n")
# input = hd args
output = dropExtension input +++ ".s"
# (mbInput,w) = readFile input w
input = fromJust mbInput
| isNone mbInput = abort "Failed to read input\n"
# mbDefs = parseSnug input
defs = fromOk mbDefs
| isError mbDefs = abort ("Failed to parse: " +++ fromError mbDefs +++ "\n")
# assembly = compile "main" defs
# assembly = join "\n" (map toString assembly)
# (mbErr,w) = writeFile output assembly w
| isError mbErr = abort ("Failed to write output: " +++ toString (fromError mbErr) +++ "\n")
| otherwise = w
readFile :: !FilePath !*World -> (!?[Char], !*World)
readFile path w
# (ok,f,w) = fopen path FReadData w
| not ok = (?None, w)
# (contents,f) = read [] f
# (_,w) = fclose f w
= (?Just contents, w)
where
read :: ![Char] !*File -> (![Char], !*File)
read acc f
# (ok,c,f) = freadc f
| not ok = (reverse acc, f)
| otherwise = read [c:acc] f
|