Commit 02c7299a authored by Camil Staps's avatar Camil Staps 🍃

Find modules instead of requiring sapl files to be given on the command-line

parent 27c75fa4
......@@ -11,6 +11,7 @@ from Data.Func import $, mapSt, seqSt
from Data.Map import fromList, newMap
import Data.Maybe
import System.CommandLine
import System.Environment
import System.File
import System.FilePath
import System.Options
......@@ -21,7 +22,10 @@ import Sapl.Target.CleanFlavour
import Sapl.Target.JS.CodeGeneratorJS
:: Options =
{ sapl_files :: ![FilePath]
{ home :: !Maybe FilePath
, paths :: ![FilePath]
, libraries :: ![String]
, modules :: ![String]
, trampoline :: !Bool
, output :: !Maybe FilePath
, beautify :: !Maybe FilePath
......@@ -29,7 +33,10 @@ import Sapl.Target.JS.CodeGeneratorJS
defaultOptions :: Options
defaultOptions =
{ sapl_files = []
{ home = Nothing
, paths = ["."]
, libraries = ["StdEnv"]
, modules = []
, trampoline = False
, output = Nothing
, beautify = Nothing
......@@ -48,19 +55,21 @@ defaultParserState =
}
Start w
# ([prog:opts],w) = getCommandLine w
# ([prog:args],w) = getCommandLine w
# noUsage = Nothing
# usage = Just ("Usage: " +++ prog +++ " [-t|--trampoline] [-b|--beautify PROG] -o OUTPUT INPUT [INPUT..]")
# usage = Just ("Usage: " +++ prog +++ " [OPTIONS] -o OUTPUT MOD [MOD..]")
# opts = parseOptions optionDescription opts defaultOptions
# opts = defaultOptions
# (home,w) = getEnvironmentVariable "CLEAN_HOME" w
# opts = parseOptions optionDescription args {opts & home=home}
| isError opts = error noUsage (join "\n" $ fromError opts) w
# opts = fromOk opts
| isEmpty opts.sapl_files = error usage "No sapl files given" w
| isEmpty opts.modules = error usage "No modules given" w
| isNothing opts.output = error usage "No output file given" w
| isNothing opts.output && isJust opts.beautify = error Nothing "Cannot use beautifier when outputting to stdout" w
# (files,(pst,w)) = mapSt (parseFile opts) opts.sapl_files (defaultParserState,w)
# (files,(pst,w)) = mapSt (parseModule opts) opts.modules (defaultParserState,w)
| any isNothing files = error Nothing "Parsing failed" w
# (ok,out,w) = case opts.output of
......@@ -82,7 +91,22 @@ Start w
where
optionDescription :: Option Options
optionDescription = WithHelp True $ Options
[ Shorthand "-t" "--trampoline" $ Flag
[ Shorthand "-H" "--clean-home" $ Option
"--clean-home"
(\h opts -> Ok {opts & home=Just h})
"DIR"
"Clean installation directory (default: $CLEAN_HOME)"
, Shorthand "-IL" "--include-lib" $ Option
"--include-lib"
(\l opts -> Ok {opts & libraries=opts.libraries ++ [l]})
"LIB"
"Library to include when searching for modules"
, Shorthand "-I" "--include" $ Option
"--include"
(\d opts -> Ok {opts & paths=opts.paths ++ [d]})
"DIR"
"Directory to include when searching for modules"
, Shorthand "-t" "--trampoline" $ Flag
"--trampoline"
(\opts -> Ok {opts & trampoline=True})
"Turn on trampoline code"
......@@ -97,9 +121,9 @@ where
"OUTPUT"
"File to write output to"
, Operand False
(\f opts -> Just $ Ok {opts & sapl_files=opts.sapl_files ++ [f]})
"INPUT"
"Sapl files to generate code for"
(\m opts -> Just $ Ok {opts & modules=opts.modules ++ [m]})
"MODULE"
"Modules to generate code for"
]
error :: !(Maybe String) !String !*World -> *World
......@@ -113,15 +137,35 @@ error usage s w
# w = setReturnCode 1 w
= w
parseFile :: !Options !FilePath !*(!ParserState,!*World) -> *(!Maybe String, !*(!ParserState,!*World))
parseFile opts fp (pst,w)
parseModule :: !Options !String !*(!ParserState,!*World) -> *(!Maybe String, !*(!ParserState,!*World))
parseModule opts mod (pst,w)
#! (fp,w) = findModule opts.paths opts.libraries w
| isNothing fp = (Nothing, (pst, error Nothing ("Could not find " +++ mod) w))
#! fp = fromJust fp
#! (f,w) = readFile fp w
| isError f = (Nothing, (pst, error Nothing (fromError f <+ " " +++ fp) w))
#! f = fromOk f
#! parseRes = parse (tokensWithPositions f)
| isError parseRes = (Nothing, (pst, error Nothing (fp +++ ": " <+ fromError parseRes) w))
| isError parseRes = (Nothing, (pst, error Nothing (mod +++ ": " <+ fromError parseRes) w))
#! (_,pst`) = fromOk parseRes
= (Just f, (mergeParserStates pst` (Just pst),w))
where
modparts = split "." mod
modPath = foldl (</>) "" (init modparts)
modBasename = last modparts
findModule :: ![FilePath] ![String] !*World -> *(!Maybe FilePath, !*World)
findModule [] [lib:libs] w | isJust opts.home
# (e,w) = fileExists filename w
= if e (Just filename, w) (findModule [] libs w)
where
filename = (fromJust opts.home </> "lib" </> lib </> modPath </> "Clean System Files" </> modBasename +++ ".sapl")
findModule [path:paths] libs w
# (e,w) = fileExists filename w
= if e (Just filename, w) (findModule paths libs w)
where
filename = (path </> modPath </> "Clean System Files" </> modBasename +++ ".sapl")
findModule _ _ w = (Nothing, w)
genCode :: !Options !String !*(!*File,!ParserState,!*World) -> *(!*File,!ParserState,!*World)
genCode opts sapl (out,pst,w)
......
......@@ -16,7 +16,7 @@ Global
ShowGC: False
ShowStackSize: False
MarkingCollector: False
DisableRTSFlags: False
DisableRTSFlags: True
StandardRuntimeEnv: True
Profile
Memory: False
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment