{- CSci 556: Multiparadigm Programming
   Expression Language Compiler for Stack Virtual Machine
   Spring 2017 
   H. Conrad Cunningham

1234567890123456789012345678901234567890123456789012345678901234567890

2017-04-03: Original version
2017-05-23: Updated to be consistent with parser code

-}

module SInstr
where

import Data.Char

type NumType = Int
type Name    = String 
type Env     = [(Name,NumType)]

data Expr = Add Expr Expr 
          | Mul Expr Expr  
          | Var Name 
          | Val NumType
            deriving Show

data SInstr = SVal NumType
            | SVar Name
            | SPop
            | SSwap
            | SDup
            | SAdd
            | SMul
            deriving (Show, Eq)
                        

data SState = SState [NumType] Int
              deriving (Show, Eq)

execSInstr :: SState -> Env -> SInstr -> (SState, Env)
execSInstr (SState es pc) env (SVal i) = (SState (i:es) (pc+1), env)
execSInstr (SState es pc) env (SVar v) = 
  case lookup v env of
    Just i -> (SState (i:es) (pc+1), env)
    Nothing -> error ("Variable " ++ show v ++ " undefined")
execSInstr  (SState es pc) env SPop  = (SState es pc, env) -- Dummy
execSInstr  (SState es pc) env SSwap = (SState es pc, env) -- Dummy
execSInstr  (SState es pc) env SDup  = (SState es pc, env) -- Dummy
execSInstr  (SState es pc) env SAdd  =
  case es of
    (r:l:xs) -> (SState ((l+r):xs) (pc+1), env)
    _        -> error ("Cannot Add. Stack too short: " ++ show es)
execSInstr  (SState es pc) env SMul = (SState es pc, env) -- Dummy


execSeq :: SState -> Env -> [SInstr] -> (SState, Env) 
