-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.hs
115 lines (101 loc) · 3.82 KB
/
main.hs
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import Parser
import Nodes
import DefCheck
import CodeGen
import JsCodeGen
import EitherUtility
import Modes
import ReduceMethods
import Data.Void
import Data.Char
import MergeDefs
import System.Exit
import System.Environment
import Data.List
import qualified Data.Set as Set
import Debug.Trace
import System.Process
import Text.Megaparsec as P
import GHC.IO.Encoding
remIncludes =
do
P.many Parser.newline
ls <- Parser.includes Lib
P.many Parser.newline
is <- Parser.includes Mod
return (ls, is)
foldS :: Set.Set String -> [(String, String, String)] -> IO [(Set.Set String, Node)]
foldS _ [] = return []
foldS s [(dir, fn, ftxt)] = sequence [fParse s dir fn ftxt] :: IO [(Set.Set String, Node)]
foldS s ((dir, fn, ftxt):xs) =
do
tre@(che, _) <- fParse s dir fn ftxt
ls <- foldS che xs
return $ tre : ls
fParse :: Set.Set String -> String -> String -> String -> IO (Set.Set String, Node)
fParse cache dir fn fstr =
do
let str = filter (/= '\t') fstr
let (libs, incs) = res where
res = case P.runParser remIncludes fn str of
Right is -> is
Left e -> error (P.errorBundlePretty e)
let (ns, ios) = (
map extractString (extractList incs),
mapM (readFile . (\x -> dir ++ "/" ++ extractString x)) (extractList incs)
)
let lns = filter (not . (`Set.member` cache)) (map extractString (extractList libs))
let nCache = cache `Set.union` Set.fromList (filter (\ s -> head s == '*') lns)
txs <- ios
let
sepStatic x = if head s == '*' then "./libs/" ++ tail s ++ "/main.slt" else dir ++ "/" ++ s ++ "/main.slt" where s = extractString x
libs <- mapM (readFile . sepStatic) (extractList libs)
let sepStatic s = if head s == '*' then "./libs/" ++ tail s else dir ++ "/" ++ s
let lbs = zip3 (map sepStatic lns) lns libs
libs <- foldS nCache lbs
let ps = zipWith (P.runParser (Parser.parse [])) ns txs
let ins = mapE id ps :: Either (ParseErrorBundle String Data.Void.Void) [Node]
case ins of
Right xs ->
case P.runParser (Parser.parse $ map snd libs ++ xs) fn str of
Right n -> return (nCache, n)
Left e -> error $ P.errorBundlePretty e
Left n -> error (P.errorBundlePretty n)
compile :: CompileMode m => m -> String -> String -> IO ()
compile mode fstr fn =
do
(_, nd) <- fParse Set.empty "." fn fstr
let tnd = mergeMultipleNode nd
case DefCheck.checkDefinitions (Right tnd) Nothing of
Right n -> writeFile (binGen mode) $ wholeCodeGen mode outName n
Left str -> error str
compileFile :: CompileMode m => m -> FilePath -> IO ()
compileFile m fn = readFile fn >>= \f -> compile m f fn
runFileMode :: CompileMode m => m -> String -> IO ()
runFileMode m fn = compileFile m fn *> callCommand (callUtilityBin m)
runMode :: CompileMode m => m -> IO ()
runMode = flip runFileMode "main.slt"
run :: IO ()
run = runMode Lua
runFile :: FilePath -> IO ()
runFile = runFileMode Lua
runFileJIT :: FilePath -> IO ()
runFileJIT = runFileMode LuaJIT
runJIT :: IO ()
runJIT = runMode LuaJIT
runJS :: IO ()
runJS = runFileMode Deno "main.slt"
runFileJS :: FilePath -> IO ()
runFileJS = runFileMode Deno
main :: IO ()
main =
do
args <- getArgs
dispatch $ map (map toLower) args where
dispatch [] = compileFile Lua "main.slt"
dispatch ["run"] = run
dispatch ["run", a] = runFile a
dispatch ["jit"] = runJIT
dispatch ["jit", a] = runFileJIT a
dispatch [a] = compileFile Lua a
dispatch xs = error $ "Unexpected arguments " ++ intercalate ", " xs