Skip to main content

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>"