Runxy
A video on this section can be found here.
This command line interface allows to run e.g.
$ runhaskell Runxy.hs factorial.xy 5
120
for the file factorial.xy. The usage is
runhaskell Runxy.hs <filename> <Int>
Alternatively, for faster execution time, you can compile Runxy.hs
with
$ ghc --make Runxy.hs
and then run it with
$ ./Runxy <filename> <Int>
You can also use optimization options, such as
$ ghc --make -O2 Runxy.hs
We name the module Main
even though the file is called Runxy.hs
, so that we can compile to produce an executable as explained above:
module Main where
import System.Environment
We import the module System.Environment
so that we can read the command line arguments with getArgs
. We also need to import our own modules:
import AbstractSyntax
import Parser
import Interpreter
Because our little language doesn't have IO facilities, we use the variable x
to hold the input and the variable y
to hold the output. So this function creates a storage with the value x
for the variable "x"
, and with all other variables uninitialized, giving an error if we try to use them:
initialStorage :: Integer -> Storage
initialStorage x = update "x" x emptyStorage
Now, given a program in abstract syntax and a value for x
, we run it with the above interpreter, and extract the value of the variable "y"
.
runxy :: Program -> Integer -> Integer
runxy p x = m' "y"
where
m = initialStorage x
m' = run p m
Finally, the main
function reads the command line arguments with getArgs
, then uses the module Parser
to parse the file, and the module Interpreter
to run the syntax tree produced by the parser on the given integer:
main :: IO()
main =
do
args <- getArgs
if length args == 2
then
do
concreteProgram <- readFile (args !! 0)
let abstractProgram = parseProgram concreteProgram
let x = read(args !! 1)
let y = runxy abstractProgram x
putStrLn (show y)
else
putStrLn "Usage: runhaskell Runxy.hs <filename> <Integer>"