module Main where

import System.Environment 
import System.IO 
import Data.Char
type Env = [(String, [Nest])]
type Stack = [Nest]
readLine :: String -> Nest

Our evaluation routine

eval :: String -> [Nest]
eval str = bigStep [] e []
  where  Nested e = readLine str

evalFile file = do
  str <- readFile file
  return $ eval str

main = do
  fn <- getArgs
  case fn of
      [] -> error "Need file.nst to evaluate."
      (x:xs) -> do res <- evalFile $ fn !! 0
                   putStrLn (show res)

Parse a number of words or nested structures.

parseSingle :: Parser Nest

parseExpr = do
  x <- many parseSingle
  return $ Nested x

Parse a nested structure starting with [ and ending with ]

parseNest :: Parser Nest
parseFloat :: Parser Nest
parseInt :: Parser Nest

Parse a simple word without any spaces or nesting between them.

parseWord :: Parser Nest
parseBool :: Parser Nest
parseString :: Parser Nest

Our abstract syntax datastructure

data Nest = W String
          | I Int
          | F Float
          | B Bool
          | S String
          | Nested [Nest]
  deriving (Show, Eq)

Can you define the bigStep semantics of the given? See below for an example.

bigStep :: Env -> [Nest] -> Stack -> [Nest]

Base case. Nothing on execution stack.

bigStep _ [] r = r

BigStep semantics for literals. i.e integers, floats strings and nests evaluate to themselves.

bigStep env (Nested n: xs) ys = bigStep env xs (Nested n: ys)
bigStep env (I i: xs) ys = bigStep env xs (I i: ys)

TODO: implement the same for Float, Boolean, and String

BigStep Semantics for addition.

bigStep env (W "+": xs) (I i: I j: ys) = bigStep env xs (I (i+j): ys)

TODO: implement the same for - : if you have - a b , then the result of (a - b) should be on the stack. same for *. Can you implement it for division? (hint, remember to use F Float for result)

TODO: implement the same for dup : duplicate the topmost element.

TODO: implement the same for swap : swap the two topmost elements.

TODO: implement the same for pop : remove the topmost element.

Remember the i combinator? that is

[1 2] i + == 3
[1 2 +] i == 3

TODO: implement the i. - pull out the topmost nesting out of the stack and push it into the execution queue

Implementing definitions.

bigStep env (W ".":xs) (Nested ((W w):as):ys) = bigStep ((w,as):env) xs ys

bigStep env (W x :xs) ys = bigStep env (def ++ xs) ys
  where Just def = lookup x env

Final case Nothing else matches.

bigStep _ x res = res