diff options
author | Camil Staps | 2016-04-27 10:37:13 +0200 |
---|---|---|
committer | Camil Staps | 2016-04-27 10:37:13 +0200 |
commit | 1af150e798c1580be42bc9e8f3880edbeb6fef29 (patch) | |
tree | 7f924f98de03ab054481f2050e5fd551a4dc9855 /run.icl | |
parent | Initial commit (diff) |
Nicer cli
Diffstat (limited to 'run.icl')
-rw-r--r-- | run.icl | 82 |
1 files changed, 82 insertions, 0 deletions
@@ -0,0 +1,82 @@ +module run + +import StdEnv, StdDebug + +import GenEq + +import Data.Maybe, Data.List +from Data.Func import $ + +import System.CommandLine, System.GetOpt + +import Smurf +import SmurfParse + +:: SmurfOpt = Break Char | BreakAll | IFile String | Verbose + +derive gEq SmurfOpt +instance == SmurfOpt where == a b = a === b + +Start :: *World -> *World +Start w +// Options +# (cmd, w) = getCommandLine w +# (opts,_,errs) = getOpt Permute options cmd +| errs <> [] = error errs w +# breakstms + = if (isMember BreakAll opts) + [Push "", Input, Output, Cat, Head, Tail, Quotify, Put, Get, Exec] + [fromChar c \\ (Break c) <- opts] +# inputs = [f \\ (IFile f) <- opts] +| length inputs <> 1 = error ["Exactly one input file required"] w +# verbose = isMember Verbose opts +// Read input file +# (_, f, w) = fopen (hd inputs) FReadText w +# (pgm, f) = freads f 100000 +# (_, w) = fclose f w +# mbPgm = parse $ fromString pgm +| isNothing mbPgm = error ["Couldn't parse input file as a Smurf program "] w +# pgm = fromJust mbPgm +// Start interpreting +# (io, w) = stdio w +# io = loop verbose breakstms pgm zero io += snd $ fclose io w +where + loop :: Bool ![Stm] !Program !State !*File -> *File + loop v brk p st f + # p = if v (trace (foldl (+++) "" (map toString p) +++ "\n") p) p + # (mbProgSt, f) = step p st f + | isNothing mbProgSt = f <<< "NOTHING!!!\n" + # (prog, st) = fromJust mbProgSt + | isEmpty prog = f <<< "\n---------------------------\n" <<< toString st + | not (isBrk prog) = loop v brk prog st f + # f = f <<< "---> " <<< toString (hd prog) <<< " ? " + # (cmd, f) = freadline f + | cmd == "" = loop v [] prog st (f <<< "\n") // Ctrl-D: stop breaking + # cmd = cmd % (0, size cmd - 2) + | cmd == "state" = loop v brk prog st (f <<< toString st) // Print state + = loop v brk prog st f + where + isBrk :: Program -> Bool + isBrk [] = False + isBrk [(Push _):_] = isMember (Push "") brk + isBrk [stm:_] = isMember stm brk + + options = [ Option ['i'] ["infile"] + (ReqArg IFile "FILE") "Smurf file" + , Option ['b'] ["break"] + (ReqArg (\s->Break s.[0]) "STM") "Break on statement" + , Option ['B'] ["break-all"] + (NoArg BreakAll) "Break on all statements" + , Option ['v'] ["verbose"] + (NoArg Verbose) "Print all programs to stderr" + ] + + error :: [String] *World -> *World + error errs w + # (io, w) = stdio w + # io = io <<< foldl (+++) "" (intersperse "\n" errs) <<< "\n" + # io = io <<< usageInfo "CleanSmurf: a Clean Smurf interpreter" options + # io = io <<< "\n\n" + = snd $ fclose io w + |