aboutsummaryrefslogtreecommitdiff
path: root/snug-clean/src/snug.icl
blob: 45b39a174b134bd6d12f13a35ded4c540e933643 (plain) (blame)
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
53
54
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")
	# mbAssembly = compile "main" defs
	  assembly = fromOk mbAssembly
	| isError mbAssembly = abort ("Failed to compile: " +++ fromError mbAssembly +++ "\n")
	# 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