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
import Orchid.Tokenizer (runTokenizer)
import Orchid.Data (Token(..), renderToken, describeToken)
import qualified Data.Text.IO.Utf8 as Text.IO
import Data.Text (Text)
import qualified Options.Applicative as Options
import Options.Applicative ((<**>))
import qualified System.IO
import qualified Text.Colour.Chunk as Colors
import qualified Text.Colour.Capabilities as TerminalCapabilities
data Arguments = Arguments {
sourceFile :: Maybe String,
outputFile :: Maybe String
}
makeArgumentParser :: Options.ParserInfo Arguments
makeArgumentParser = Options.info
(parseArguments <**> Options.helper)
(Options.fullDesc <> Options.progDesc "Transforms an Orchid source file into another form" <> Options.header "orchid-cli: The Orchid compiler")
parseArguments :: Options.Parser Arguments
parseArguments = do
sourceFile <- parseSourceFile
outputFile <- parseOutputFile
return Arguments { .. }
parseSourceFile :: Options.Parser (Maybe String)
parseSourceFile = Options.optional $ Options.strArgument (Options.metavar "SOURCE_FILE" <> Options.help "The source file to process")
parseOutputFile :: Options.Parser (Maybe String)
parseOutputFile = Options.optional $ Options.strOption (Options.short 'o' <> Options.long "output-file" <> Options.metavar "OUTPUT_FILE" <> Options.help "The output file to process")
main :: IO ()
main = runOrchidToolchain =<< Options.execParser makeArgumentParser
runOrchidToolchain :: Arguments -> IO ()
runOrchidToolchain (Arguments sourceFile outputFile) = do
source <- readSourceFile sourceFile
let result = runTokenizer (filenameOf sourceFile) source
case result of
Left e -> putStrLn e
Right tokens -> renderTokens outputFile tokens
filenameOf :: Maybe String -> String
filenameOf (Just filename) = filename
filenameOf Nothing = "<standard input>"
readSourceFile :: Maybe String -> IO Text
readSourceFile (Just sourceFile) = Text.IO.readFile sourceFile
readSourceFile Nothing = Text.IO.getContents
renderTokens :: Maybe String -> [Token] -> IO ()
renderTokens outputFile tokens = do
outputHandle <- case outputFile of
Just path -> System.IO.openFile path System.IO.WriteMode
Nothing -> return System.IO.stdout
mapM_ (Text.IO.hPutStrLn outputHandle . displayToken) tokens
System.IO.hClose outputHandle
displayToken :: Token -> Text
displayToken token = "> " <> description <> ": " <> colorRepresentation representation where
representation = renderToken token
description = describeToken token
colorRepresentation :: Text -> Text
colorRepresentation text = Colors.renderChunkText TerminalCapabilities.With8Colours colored where
colored = Colors.fore Colors.cyan chunk
chunk = Colors.chunk text