packages feed

AspectAG-0.5.0.0: examples/Expr.hs

{-# LANGUAGE TypeOperators #-}

{-# LANGUAGE
             TypeFamilies,
             FlexibleContexts,
             ScopedTypeVariables,
             NoMonomorphismRestriction,
             ImplicitParams,
             ExtendedDefaultRules,
             UnicodeSyntax,
             DataKinds,
             TypeApplications,
             PartialTypeSignatures,
             AllowAmbiguousTypes
#-}


module Expr where

import System.Exit (exitFailure)
import Language.Grammars.AspectAG
import Control.Monad
import Control.Applicative
import Data.Proxy
import GHC.TypeLits
import Data.Map
import Data.Maybe
import Debug.Trace
import Language.Grammars.AspectAG.TH

type Nt_Expr = 'NT "Expr"
expr = Label @ Nt_Expr

type P_Add = 'Prd "p_Add" Nt_Expr
add = Label @ P_Add

type P_Val = 'Prd "p_Val" Nt_Expr
val = Label @ P_Val

type P_Var = 'Prd "p_Var" Nt_Expr
var = Label @ P_Var


leftAdd   = Label @ ('Chi "leftAdd"   P_Add ('Left Nt_Expr))
rightAdd  = Label @ ('Chi "rightAdd"  P_Add ('Left Nt_Expr))
ival      = Label @ ('Chi "ival"      P_Val ('Right ('T Int)))
vname     = Label @ ('Chi "vname"     P_Var ('Right ('T String)))

eval = Label @ ('Att "eval" Int)
env  = Label @ ('Att "env"  (Map String Int))

add_eval  =  syndefM eval add  $ (+) <$> at leftAdd eval <*> at rightAdd eval
val_eval  =  syndefM eval val  $ ter ival
var_eval  =  syndefM eval var  $ slookup <$> ter vname <*> at lhs env

slookup nm = fromJust . Data.Map.lookup nm

aspEval   =  traceAspect (Proxy @ ('Text "eval"))
          $  add_eval .+: val_eval .+: var_eval .+: emptyAspect


add_leftAdd_env  = inhdefM env add leftAdd  $ at lhs env
add_rightAdd_env = inhdefM env add rightAdd $ at lhs env
-- val_ival_env = inhdefM env val ival $ at lhs env

aspEnv  =  traceAspect (Proxy @ ('Text "env"))
        $  add_leftAdd_env .+: add_rightAdd_env .+: emptyAspect 


asp = aspEval .:+: aspEnv


data Expr = Val Int
          | Var String
          | Add Expr Expr
       deriving Show



sem_Expr asp (Add l r) = knitAspect add asp
                           $  leftAdd  .=. sem_Expr asp l
                          .*. rightAdd .=. sem_Expr asp r
                          .*.  EmptyRec
sem_Expr asp (Val i)   = knitAspect val asp$
                          ival  .=. sem_Lit i .*. EmptyRec
sem_Expr asp (Var v)   = knitAspect var asp$
                          vname .=. sem_Lit v .*. EmptyRec

evalExpr e m = sem_Expr asp e (env =. m .*. emptyAtt) #. eval


exampleExpr =  Add (Val (-9)) (Add (Var "x") (Val 2))
exampleEval =  evalExpr exampleExpr (insert "x" 5 Data.Map.empty)