aboutsummaryrefslogtreecommitdiff
path: root/sil.icl
blob: 1ca0c81befa2e43cb25030eabc050b2d8d17096f (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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
module sil

import StdBool
import StdChar
import StdFile
from StdFunc import o, seq
import StdList
import StdOverloaded
import StdString

import Control.Applicative
import Control.Monad
import Data.Error
from Data.Func import $
import Data.Functor
import System.CommandLine
import System.File

import ABC.Assembler

import qualified Sil.Compile as SC
from Sil.Compile import :: CompileError, instance toString CompileError
import Sil.Parse
import Sil.Parse.Parser
from Sil.Syntax import :: Program
from Sil.Util import :: PrintState, instance zero PrintState,
	class PrettyPrinter(..), instance PrettyPrinter Program

:: CLI =
	{ prettyprint :: Bool
	, compile     :: Bool
	, inputfile   :: String
	}

instance zero CLI
where
	zero =
		{ prettyprint = False
		, compile     = False
		, inputfile   = ""
		}

Start w
# (io,w) = stdio w
# (cmd,w)  = getCommandLine w
# (args,_) = runParser (arg until eof) $ tl cmd
| isError args
	# io = io <<< toString (fromError args) <<< "\r\n"
	# (_,w) = fclose io w
	= w
# args = seq (fromOk args) zero
# (file,w) = readFile args.inputfile w
| isError file
	# io = io <<< "Could not open '" <<< args.inputfile <<< "'.\r\n"
	# (_,w) = fclose io w
	= w
# prog = tokenise (fromString $ fromOk file) >>= parse
| isError prog
	# io = io <<< toString (fromError prog) <<< "\r\n"
	# (_,w) = fclose io w
	= w
# io = if args.prettyprint
	(io <<< print zero (fromOk prog) <<< "\r\n")
	io
# io = if args.compile
	(io <<< ('SC'.compile (fromOk prog)) <<< "\r\n")
	io
# (_,w) = fclose io w
= w
where
	arg :: Parser String (CLI -> CLI)
	arg = peek >>= \opt ->
		(   item "--pretty-print" *> pure (\cli -> {cli & prettyprint=True})
		<|> item "--compile" *> pure (\cli -> {cli & compile=True})
		<|> (satisfy isFilename >>= \name -> pure (\cli -> {cli & inputfile=name}))
		<?> Invalid "command line argument" opt
		)

	isFilename :: (String -> Bool)
	isFilename = all (\c -> isAlphanum c || isMember c ['.']) o fromString

instance <<< (MaybeError e a) | <<< e & <<< a
where
	<<< f (Ok a) = f <<< a
	<<< f (Error e) = f <<< e

instance <<< CompileError where <<< f e = f <<< toString e