77
88module Main (main ) where
99
10+ import AST
11+ import Compiler
1012import Control.Exception (IOException , SomeException , try )
1113import Control.Monad (foldM )
14+ import Data.Char (isSpace )
1215import qualified Data.Map as Map
1316import qualified Data.Vector as Vector
14- import System.Environment (getArgs )
15- import System.Exit (ExitCode (ExitFailure , ExitSuccess ), exitSuccess , exitWith )
16- import System.IO (hFlush , hIsTerminalDevice , hPutStrLn , isEOF , stderr , stdin , stdout )
17- import Data.Char (isSpace )
18-
19- import AST
20- import Compiler
2117import Desugar
2218import Disasm
2319import SExprParser
20+ import System.Environment (getArgs )
21+ import System.Exit (ExitCode (ExitFailure , ExitSuccess ), exitSuccess , exitWith )
22+ import System.FilePath (takeExtension )
23+ import System.IO (hFlush , hIsTerminalDevice , hPutStrLn , isEOF , stderr , stdin , stdout )
2424import TopineurParser
2525import VM
26- import System.FilePath (takeExtension )
2726
2827main :: IO ()
2928main = do
3029 args <- getArgs
3130 let (noCache, restArgs) = parseFlags args
32- config = defaultConfig { cfgUseCache = not noCache }
31+ config = defaultConfig {cfgUseCache = not noCache}
3332 case restArgs of
3433 [] -> repl
3534 [" --help" ] -> printHelp
35+ [" -h" ] -> printHelp
3636 [" --disasm" , file] -> disasmFile config file
37+ [" -d" , file] -> disasmFile config file
3738 [" --ast" , file] -> showAst file
39+ [" -a" , file] -> showAst file
3840 [" --compiled" , file] -> showCompiled config file
41+ [" -c" , file] -> showCompiled config file
3942 [" --bytecode" , file] -> showBytecode config file
43+ [" -b" , file] -> showBytecode config file
4044 [" --parse-top" , file] -> parseTopineurFile file
41- [" --version" ] -> putStrLn " GLaDOS version 1.0.0\n The Topineur and Lisp compiler."
45+ [" -p" , file] -> parseTopineurFile file
46+ [" --version" ] -> version
47+ [" -v" ] -> version
4248 [file] -> runFile config file
4349 _ ->
4450 exitWithError " Invalid arguments. Use --help for usage."
4551 where
4652 parseFlags :: [String ] -> (Bool , [String ])
4753 parseFlags xs = (" --no-cache" `elem` xs, filter (/= " --no-cache" ) xs)
4854
55+ version = putStrLn " GLaDOS version 1.0.0\n The Topineur and Lisp compiler."
56+
4957exitWithError :: String -> IO a
5058exitWithError msg =
5159 hPutStrLn stderr (" [ERROR] : " ++ msg)
@@ -67,21 +75,23 @@ renderValue VUnit = "#<void>"
6775renderValue (VList values) = " (" ++ unwords (map renderValue values) ++ " )"
6876renderValue (VTuple values) = " #(" ++ unwords (map renderValue values) ++ " )"
6977renderValue (VObject name fields) =
70- " #<object:" ++ name ++ " {" ++
71- intercalate " , " (map (\ (k, v) -> k ++ " : " ++ renderValue v) fields) ++
72- " }>"
78+ " #<object:"
79+ ++ name
80+ ++ " {"
81+ ++ intercalate " , " (map (\ (k, v) -> k ++ " : " ++ renderValue v) fields)
82+ ++ " }>"
7383 where
7484 intercalate _ [] = " "
7585 intercalate _ [x] = x
76- intercalate sep (x: xs) = x ++ sep ++ intercalate sep xs
86+ intercalate sep (x : xs) = x ++ sep ++ intercalate sep xs
7787
7888runProgram :: String -> IO (Either String Value )
7989runProgram source =
8090 case compileWithDefs defaultConfig source of
8191 Left err -> return $ Left (formatCompileError err)
8292 Right (code, defs) -> do
8393 let allCodeObjects = Map. insert " main" code defs
84- initialVmState = initVMState { vCodeObjects = allCodeObjects }
94+ initialVmState = initVMState {vCodeObjects = allCodeObjects}
8595 vmState <- initializeGlobals initialVmState defs
8696 execResult <- try (execVM vmState code) :: IO (Either SomeException (Either VMError Value ))
8797 case execResult of
@@ -92,34 +102,35 @@ runProgram source =
92102initializeGlobals :: VMState -> Map. Map Name CodeObject -> IO VMState
93103initializeGlobals vmState defs =
94104 foldM
95- (\ state (name, codeObj) ->
96- if coArity codeObj == 0
97- then do
98- result <- execVM state codeObj
99- case result of
100- Right val ->
101- return $ state { vGlobals = Map. insert name val (vGlobals state) }
102- Left _err -> return state
103- else return state)
105+ ( \ state (name, codeObj) ->
106+ if coArity codeObj == 0
107+ then do
108+ result <- execVM state codeObj
109+ case result of
110+ Right val ->
111+ return $ state {vGlobals = Map. insert name val (vGlobals state)}
112+ Left _err -> return state
113+ else return state
114+ )
104115 vmState
105116 (Map. toList defs)
106117
107118runProgramWithSource :: CompilerConfig -> String -> String -> IO (Either String Value )
108119runProgramWithSource config source filePath =
109120 let isTopineur = takeExtension filePath == " .top"
110- in if isTopineur
111- then do
112- compileResult <- compileTopineurFile config filePath
113- case compileResult of
121+ in if isTopineur
122+ then do
123+ compileResult <- compileTopineurFile config filePath
124+ case compileResult of
125+ Left err -> return $ Left (formatCompileError err)
126+ Right (code, defs) -> execute code defs
127+ else case compileWithDefs config source of
114128 Left err -> return $ Left (formatCompileError err)
115129 Right (code, defs) -> execute code defs
116- else case compileWithDefs config source of
117- Left err -> return $ Left (formatCompileError err)
118- Right (code, defs) -> execute code defs
119130 where
120131 execute code defs = do
121132 let allCodeObjects = Map. insert " main" code defs
122- initialVmState = initVMState { vCodeObjects = allCodeObjects }
133+ initialVmState = initVMState {vCodeObjects = allCodeObjects}
123134 vmState <- initializeGlobals initialVmState defs
124135 execResult <- try (execVM vmState code) :: IO (Either SomeException (Either VMError Value ))
125136 case execResult of
@@ -131,29 +142,30 @@ printHelp :: IO ()
131142printHelp =
132143 mapM_
133144 putStrLn
134- [ " GLaDOS - A LISP and Topineur compiler and VM"
135- , " "
136- , " Usage:"
137- , " ./glados [file] Compile and run a LISP file"
138- , " ./glados --disasm [file] Disassemble a LISP file"
139- , " ./glados --ast [file] Show AST of a LISP file"
140- , " ./glados --compiled [file] Show compiled code of a LISP file"
141- , " ./glados --bytecode [file] Show bytecode instructions of a LISP file"
142- , " ./glados --parse-top [file] Show parsed structure of a Topineur file"
143- , " ./glados Start REPL (interactive mode)"
144- , " ./glados --help Show this help message"
145- , " "
146- , " Options:"
147- , " --no-cache Disable bytecode cache (.topo files)"
148- , " "
149- , " Examples:"
150- , " ./glados program.lisp"
151- , " ./glados program.top"
152- , " ./glados --no-cache program.top"
153- , " ./glados --disasm program.lisp"
154- , " ./glados --ast program.lisp"
155- , " ./glados --compiled program.lisp"
156- , " ./glados --parse-topineur program.top"
145+ [ " GLaDOS - A LISP and Topineur compiler and VM" ,
146+ " " ,
147+ " Usage:" ,
148+ " ./glados [file] Compile and run a TOPINEUR or LISP file" ,
149+ " ./glados -d|--disasm [file] Disassemble a TOPINEUR or LISP file" ,
150+ " ./glados -a|--ast [file] Show AST of a TOPINEUR or LISP file" ,
151+ " ./glados -c|--compiled [file] Show compiled code of a TOPINEUR or LISP file" ,
152+ " ./glados -b|--bytecode [file] Show bytecode instructions of a TOPINEUR or LISP file" ,
153+ " ./glados -p|--parse-top [file] Show parsed structure of a Topineur file" ,
154+ " ./glados Start REPL (interactive mode)" ,
155+ " ./glados -h|--help Show this help message" ,
156+ " ./glados -v|--version Show version information" ,
157+ " " ,
158+ " Options:" ,
159+ " --no-cache Disable bytecode cache (.topo files)" ,
160+ " " ,
161+ " Examples:" ,
162+ " ./glados program.lisp" ,
163+ " ./glados program.top" ,
164+ " ./glados --no-cache program.top" ,
165+ " ./glados -d program.lisp" ,
166+ " ./glados -a program.lisp" ,
167+ " ./glados -c program.lisp" ,
168+ " ./glados -p program.top"
157169 ]
158170
159171runFile :: CompilerConfig -> FilePath -> IO ()
@@ -178,7 +190,7 @@ valueToExitCode (VInt n)
178190 | n == 0 = ExitSuccess
179191 | otherwise = ExitFailure (fromInteger n)
180192valueToExitCode VUnit = ExitSuccess
181- valueToExitCode _ = ExitSuccess -- Default to success for other types
193+ valueToExitCode _ = ExitSuccess -- Default to success for other types
182194
183195disasmFile :: CompilerConfig -> FilePath -> IO ()
184196disasmFile config file = do
@@ -197,24 +209,25 @@ disasmFile config file = do
197209 >> dumpCodeObject code
198210 >> putStrLn " \n === Nested Definitions ==="
199211 >> mapM_
200- (\ (name, obj) ->
201- putStrLn (" \n --- " ++ name ++ " ---" )
202- >> dumpCodeObject obj)
212+ ( \ (name, obj) ->
213+ putStrLn (" \n --- " ++ name ++ " ---" )
214+ >> dumpCodeObject obj
215+ )
203216 (Map. toList defs)
204217 >> exitSuccess
205- else
206- case compileWithDefs config source of
207- Left err -> exitWithError (formatCompileError err)
208- Right (code, defs) ->
209- putStrLn " === Main Code ==="
210- >> dumpCodeObject code
211- >> putStrLn " \n === Nested Definitions ==="
212- >> mapM_
213- (\ (name, obj) ->
218+ else case compileWithDefs config source of
219+ Left err -> exitWithError (formatCompileError err)
220+ Right (code, defs) ->
221+ putStrLn " === Main Code ==="
222+ >> dumpCodeObject code
223+ >> putStrLn " \n === Nested Definitions ==="
224+ >> mapM_
225+ ( \ (name, obj) ->
214226 putStrLn (" \n --- " ++ name ++ " ---" )
215- >> dumpCodeObject obj)
216- (Map. toList defs)
217- >> exitSuccess
227+ >> dumpCodeObject obj
228+ )
229+ (Map. toList defs)
230+ >> exitSuccess
218231
219232showAst :: FilePath -> IO ()
220233showAst file = do
@@ -249,24 +262,25 @@ showCompiled config file = do
249262 >> dumpCodeInfo code
250263 >> putStrLn " \n === Nested Definitions ==="
251264 >> mapM_
252- (\ (name, obj) ->
253- putStrLn (" \n --- " ++ name ++ " ---" )
254- >> dumpCodeInfo obj)
265+ ( \ (name, obj) ->
266+ putStrLn (" \n --- " ++ name ++ " ---" )
267+ >> dumpCodeInfo obj
268+ )
255269 (Map. toList defs)
256270 >> exitSuccess
257- else
258- case compileWithDefs config source of
259- Left err -> exitWithError (formatCompileError err)
260- Right (code, defs) ->
261- putStrLn " === Main Code ==="
262- >> dumpCodeInfo code
263- >> putStrLn " \n === Nested Definitions ==="
264- >> mapM_
265- (\ (name, obj) ->
271+ else case compileWithDefs config source of
272+ Left err -> exitWithError (formatCompileError err)
273+ Right (code, defs) ->
274+ putStrLn " === Main Code ==="
275+ >> dumpCodeInfo code
276+ >> putStrLn " \n === Nested Definitions ==="
277+ >> mapM_
278+ ( \ (name, obj) ->
266279 putStrLn (" \n --- " ++ name ++ " ---" )
267- >> dumpCodeInfo obj)
268- (Map. toList defs)
269- >> exitSuccess
280+ >> dumpCodeInfo obj
281+ )
282+ (Map. toList defs)
283+ >> exitSuccess
270284
271285showBytecode :: CompilerConfig -> FilePath -> IO ()
272286showBytecode config file = do
@@ -285,24 +299,25 @@ showBytecode config file = do
285299 >> dumpBytecode code
286300 >> putStrLn " \n === Nested Definitions ==="
287301 >> mapM_
288- (\ (name, obj) ->
289- putStrLn (" \n --- " ++ name ++ " ---" )
290- >> dumpBytecode obj)
302+ ( \ (name, obj) ->
303+ putStrLn (" \n --- " ++ name ++ " ---" )
304+ >> dumpBytecode obj
305+ )
291306 (Map. toList defs)
292307 >> exitSuccess
293- else
294- case compileWithDefs config source of
295- Left err -> exitWithError (formatCompileError err)
296- Right (code, defs) ->
297- putStrLn " === Main Bytecode ==="
298- >> dumpBytecode code
299- >> putStrLn " \n === Nested Definitions ==="
300- >> mapM_
301- (\ (name, obj) ->
308+ else case compileWithDefs config source of
309+ Left err -> exitWithError (formatCompileError err)
310+ Right (code, defs) ->
311+ putStrLn " === Main Bytecode ==="
312+ >> dumpBytecode code
313+ >> putStrLn " \n === Nested Definitions ==="
314+ >> mapM_
315+ ( \ (name, obj) ->
302316 putStrLn (" \n --- " ++ name ++ " ---" )
303- >> dumpBytecode obj)
304- (Map. toList defs)
305- >> exitSuccess
317+ >> dumpBytecode obj
318+ )
319+ (Map. toList defs)
320+ >> exitSuccess
306321
307322parseTopineurFile :: FilePath -> IO ()
308323parseTopineurFile file = do
0 commit comments