packages feed

uu-cco-examples-0.1.0.1: src/CCO/Arith/AG/Evaluation.ag

imports
{
import CCO.Feedback         (Feedback, errorMessage)
import CCO.Printing         (wrapped, showable, Printable (pp))
import CCO.SourcePos        (Source (..), Pos (..), SourcePos (..))
import CCO.Tree             (ATerm (App), Tree (fromTree, toTree))
import CCO.Tree.Parser      (parseTree, app, arg)
import Control.Applicative  ((<$>))
import Control.Monad        (when)
}

-------------------------------------------------------------------------------
-- Syntax
-------------------------------------------------------------------------------

{
-- | Type of values.
data Val = VNum Num_  -- ^ Numeral.

instance Tree Val where
  fromTree (VNum n) = App "Num" [fromTree n]
  toTree = parseTree [app "Num" (VNum <$> arg)]

instance Printable Val where
  pp (VNum n) = showable n  
}

-------------------------------------------------------------------------------
-- Evaluation
-------------------------------------------------------------------------------

attr Tm Tm_
  syn val :: {Feedback Val}

sem Tm_
  | Num lhs.val = return (VNum @n)
  | Add lhs.val = do VNum n1 <- @t1.val
                     VNum n2 <- @t2.val
                     return (VNum (n1 + n2))
  | Sub lhs.val = do VNum n1 <- @t1.val
                     VNum n2 <- @t2.val
                     return (VNum (if n2 > n1 then 0 else (n1 - n2)))
  | Mul lhs.val = do VNum n1 <- @t1.val
                     VNum n2 <- @t2.val
                     return (VNum (n1 * n2))
  | Div lhs.val = do VNum n1 <- @t1.val
                     VNum n2 <- @t2.val
                     when (n2 == 0) (errDivByZero @lhs.pos)
                     return (VNum (n1 `div` n2))

-------------------------------------------------------------------------------
-- Run-time errors
-------------------------------------------------------------------------------

{
-- | Produces a division-by-zero error.
errDivByZero :: SourcePos -> Feedback ()
errDivByZero pos =
  errorMessage . wrapped $
  describeSourcePos pos ++ ": Run-time error: division by zero."
}