aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamil Staps2017-08-13 19:21:43 +0200
committerCamil Staps2017-08-13 19:21:48 +0200
commitbb762e08e950b4d6d16bf0782c3e8d689f28c5dc (patch)
treec01e0dbca3b9761a4fcadcfc34c15d4b5a0a0193
parentcleanup (diff)
Improved compiler interface (#8)
Specifically: - --check, --compile and --generate are implicit, there are --no-* options to disable. - --help added. - --run removed. - Renamed to silc (sil compiler). - Output files are relative to input file.
-rw-r--r--.gitignore6
-rw-r--r--Makefile2
-rw-r--r--Sil/Util/Parser.dcl1
-rw-r--r--Sil/Util/Parser.icl5
-rw-r--r--silc.icl (renamed from sil.icl)77
5 files changed, 58 insertions, 33 deletions
diff --git a/.gitignore b/.gitignore
index c8e7bf9..75943a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
Clean System Files/
-sil
-sil_compiled
-sil_compiled.dcl
+silc
+examples/
+!examples/*.sil
diff --git a/Makefile b/Makefile
index a9a1741..c9d5edb 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-BIN:=sil
+BIN:=silc
CLM:=clm
CLMFLAGS:=-nt -nr\
-l -no-pie\
diff --git a/Sil/Util/Parser.dcl b/Sil/Util/Parser.dcl
index 14dc022..e0046fa 100644
--- a/Sil/Util/Parser.dcl
+++ b/Sil/Util/Parser.dcl
@@ -47,6 +47,7 @@ satisfy :: (a -> Bool) -> Parser a a
check :: (a -> Bool) -> Parser a a
(until) infix 2 :: (Parser a b) (Parser a c) -> Parser a [b]
item :: a -> Parser a a | ==, name, toString a
+anyItem :: ([a] -> Parser a a) | ==, name, toString a
list :: [a] -> Parser a [a] | ==, name, toString a
seplist :: a (Parser a b) -> Parser a [b] | ==, name, toString a
seplistUntil :: a a (Parser a b) -> Parser a [b] | ==, name, toString a
diff --git a/Sil/Util/Parser.icl b/Sil/Util/Parser.icl
index e730313..154a989 100644
--- a/Sil/Util/Parser.icl
+++ b/Sil/Util/Parser.icl
@@ -1,6 +1,6 @@
implementation module Sil.Util.Parser
-from StdFunc import iter
+from StdFunc import iter, o
import StdList
import StdOverloaded
@@ -140,6 +140,9 @@ where
item :: a -> Parser a a | ==, name, toString a
item a = satisfy ((==) a) <#> name a
+anyItem :: ([a] -> Parser a a) | ==, name, toString a
+anyItem = foldr (<|>) empty o map item
+
list :: [a] -> Parser a [a] | ==, name, toString a
list as = mapM item as
diff --git a/sil.icl b/silc.icl
index 945faaa..4861d3c 100644
--- a/sil.icl
+++ b/silc.icl
@@ -1,4 +1,4 @@
-module sil
+module silc
import StdBool
import StdChar
@@ -16,7 +16,9 @@ from Data.Func import $
import Data.Functor
import Data.Tuple
import System.CommandLine
+import System.Directory
import System.File
+import System.FilePath
import System.Process
import ABC.Assembler
@@ -35,19 +37,19 @@ from Sil.Util.Printer import :: PrintState, instance zero PrintState,
, check :: Bool
, compile :: Bool
, generate :: Bool
- , run :: Bool
- , inputfile :: String
+ , help :: Bool
+ , inputfile :: Maybe String
}
instance zero CLI
where
zero =
{ prettyprint = False
- , check = False
- , compile = False
- , generate = False
- , run = False
- , inputfile = ""
+ , check = True
+ , compile = True
+ , generate = True
+ , help = False
+ , inputfile = Nothing
}
Start w
@@ -59,9 +61,25 @@ Start w
# err = err <<< toString (fromError args) <<< "\r\n"
= finish 1 io err w
#! args = seq (fromOk args) zero
-#! (file,w) = readFile args.inputfile w
+| args.help
+ # io = io <<< HELP
+ = finish 0 io err w
+| isNothing args.inputfile
+ # err = err <<< "No input file given.\r\n"
+ = finish 1 io err w
+# infile = fromJust args.inputfile
+# (dir, module, dclfile, sysfiles, abcfile) =
+ ( dir
+ , name
+ , dir </> addExtension name "dcl"
+ , dir </> "Clean System Files"
+ , dir </> "Clean System Files" </> addExtension name "abc")
+ with
+ (dir, name) = splitFileName $ if (ext == "sil") base` infile
+ (base`, ext) = splitExtension infile
+#! (file,w) = readFile infile w
| isError file
- # err = err <<< "Could not open '" <<< args.inputfile <<< "' for reading.\r\n"
+ # err = err <<< "Could not open '" <<< infile <<< "' for reading.\r\n"
= finish 1 io err w
#! prog = tokenise (fromString $ fromOk file) >>= parse
| isError prog
@@ -78,16 +96,17 @@ Start w
= finish 1 io err w
| not args.compile
= finish 0 io err w
-#! (ok,f,w) = fopen "sil_compiled.dcl" FWriteText w
+#! (ok,f,w) = fopen dclfile FWriteText w
| not ok
- # err = err <<< "Could not open 'sil_compiled.dcl' for writing\r\n"
+ # err = err <<< "Could not open '" <<< dclfile <<< "' for writing\r\n"
= finish 1 io err w
-#! f = f <<< "definition module sil_compiled"
+#! f = f <<< "definition module " <<< module
#! (_,w) = fclose f w
#! (_,w) = sleep 1 w
-#! (ok,f,w) = fopen "Clean System Files/sil_compiled.abc" FWriteText w
+#! (_,w) = createDirectory sysfiles w
+#! (ok,f,w) = fopen abcfile FWriteText w
| not ok
- # err = err <<< "Could not open 'sil_compiled.abc' for writing\r\n"
+ # err = err <<< "Could not open '" <<< abcfile <<< "' for writing\r\n"
= finish 1 io err w
#! prog = 'SC'.compile prog
| isError prog
@@ -97,31 +116,33 @@ Start w
#! (_,w) = fclose f w
| not args.generate
= finish 0 io err w
-#! (p,w) = callProcess "/opt/clean/bin/clm" ["-l", "-no-pie", "sil_compiled", "-o", "sil_compiled"] Nothing w
+#! (p,w) = callProcess "/opt/clean/bin/clm" ["-l", "-no-pie", module, "-o", module] (Just dir) w
| isError p
# err = err <<< snd (fromError p) <<< "\r\n"
= finish 1 io err w
| fromOk p <> 0
= finish (fromOk p) io err w
-| not args.run
- = finish 0 io err w
-#! (p,w) = callProcess "./sil_compiled" [] Nothing w
-| isError p
- # err = err <<< snd (fromError p) <<< "\r\n"
- = finish 1 io err w
= finish 0 io err w
where
arg :: Parser String (CLI -> CLI)
arg = peek >>= \opt ->
- ( (\ cli -> {cli & prettyprint=True}) <$ item "--pretty-print"
- <|> (\ cli -> {cli & check=True}) <$ item "--check"
- <|> (\ cli -> {cli & compile=True}) <$ item "--compile"
- <|> (\ cli -> {cli & generate=True}) <$ item "--generate"
- <|> (\ cli -> {cli & run=True}) <$ item "--run"
- <|> (\name cli -> {cli & inputfile=name}) <$> satisfy isFilename
+ ( (\ cli -> {cli & prettyprint=True}) <$ anyItem ["-p", "--pretty-print"]
+ <|> (\ cli -> {cli & check=False}) <$ item "--no-check"
+ <|> (\ cli -> {cli & compile=False}) <$ item "--no-compile"
+ <|> (\ cli -> {cli & generate=False}) <$ item "--no-generate"
+ <|> (\ cli -> {cli & help=True}) <$ anyItem ["-h", "--help"]
+ <|> (\name cli -> {cli & inputfile=Just name}) <$> satisfy isFilename
<?> P_Invalid "command line argument" opt
)
+ HELP = "silc: simple imperative language compiler\r\n\r\n" +++
+ "Usage: silc [-p|--pretty-print] [--no-check] [--no-compile] [--no-generate] [-h|--help] [FILE]\r\n\r\n" +++
+ "\t-p, --pretty-print Pretty-print program\r\n" +++
+ "\t--no-check Do not check program for common errors\r\n" +++
+ "\t--no-compile Do not compile program to ABC-code\r\n" +++
+ "\t--no-generate Do not generate machine code from ABC-code\r\n" +++
+ "\t-h, --help Print this help\r\n"
+
isFilename :: (String -> Bool)
isFilename = all (\c -> isAlphanum c || isMember c ['./-']) o fromString