ewe-0.1.0.43: src-ag/Language/EWE/CheckGrammar.ag
imports
{
import qualified Data.Set as Set
import qualified Data.Map as Map
import Language.EWE.AbsSyn
import Language.EWE.Utils
}
attr Prog
syn res :: {Either String ()}
attr Equates
chn idMemRef :: {Map.Map String Int}
attr Equ
chn idMemRef :: {Map.Map String Int}
syn res :: {Either String ()}
attr Stmts
chn labelDef :: {Set.Set String}
inh labelFound :: {Set.Set String}
inh idMemRefDef :: {Map.Map String Int}
syn res use {(<-->)} {Right ()} :: {Either String ()}
attr Stmt
chn labelDef :: {Set.Set String}
inh labelFound :: {Set.Set String}
inh idMemRefDef :: {Map.Map String Int}
syn res :: {Either String ()}
attr Instr
inh labelFound :: {Set.Set String}
inh idMemRefDef :: {Map.Map String Int}
syn res :: {Either String ()}
attr Labels
syn res :: { Either String () }
chn labelDef :: { Set.Set String }
syn copy :: self
attr MRef
inh idMemRefDef :: { Map.Map String Int }
syn res :: { Either String () }
sem Equ
| Tuple lhs.res = { if @x1 `Map.member` @lhs.idMemRef
then Left $ @x1 ++ " was already defined "
else Right ()
}
.idMemRef = { Map.insert @x1 @x2 @lhs.idMemRef }
sem Labels
| Cons lhs.res = { isLabelNotDef @hd @tl.labelDef }
.labelDef = { Set.insert @hd @tl.labelDef }
| Nil lhs.res = { Right () }
.labelDef = { @lhs.labelDef }
sem Prog
| Prg stms.labelDef = { Set.empty }
.labelFound = { @stms.labelDef }
.idMemRefDef = { @equates.idMemRef }
equates.idMemRef = { Map.empty }
sem Stmt
| Stmt loc.res1 = {
let f (e,er,s) lbl = if Set.member lbl s
then (True,
lbl ++ " is already defined\n" ++ er,
s)
else (e, er, Set.insert lbl s)
(e', errs', set') = foldl f (False,"",@lhs.labelDef) @labels.copy
in if e'
then Left errs'
else Right ()
}
lhs.res = { @res1 <--> @instr.res }
sem MRef
| MRefI lhs.res = Right ()
| MRefId lhs.res = isMemRefDef @string @lhs.idMemRefDef
sem Instr
| IMMI lhs.res = { @dest.res }
| IMMS lhs.res = { @dest.res }
| IMRPC lhs.res = { @dest.res }
| SPC lhs.res = { @oper.res }
| IMMM lhs.res = { @dest.res <--> @oper.res }
| IAdd lhs.res = { @dest.res <--> @left.res <--> @right.res }
| ISub lhs.res = { @dest.res <--> @left.res <--> @right.res }
| IMul lhs.res = { @dest.res <--> @left.res <--> @right.res }
| IDiv lhs.res = { @dest.res <--> @left.res <--> @right.res }
| IMod lhs.res = { @dest.res <--> @left.res <--> @right.res }
| IMRI lhs.res = { @dest.res <--> @oper.res }
| IMMR lhs.res = { @dest.res <--> @oper.res }
| IRI lhs.res = { @oper.res }
| IWI lhs.res = { @oper.res }
| IRS lhs.res = { @left.res <--> @right.res }
| IWS lhs.res = { @oper.res }
| IGI lhs.res = { Right () }
| IGS lhs.res = { isLabelDef @string @lhs.labelFound }
| IFI lhs.res = { @bcond.res <--> @then.res }
| IFS lhs.res = { isLabelDef @string @lhs.labelFound <--> @bcond.res <--> @then.res}
| IH lhs.res = { Right () }
| IB lhs.res = { Right () }
| INI lhs.res = { Right () }
include "AbsSyn.ag"
include "PPProg.ag"
{
isLabelDef :: String -> Set.Set String -> Either String ()
isLabelDef str sets
| str `Set.member` sets = Right ()
| otherwise = Left $ "Label: " ++ str ++ " is not defined "
isLabelNotDef :: String -> Set.Set String -> Either String ()
isLabelNotDef str sets
| str `Set.member` sets = Left $ "Label: " ++ str ++ " is already defined "
| otherwise = Right ()
isMemRefDef :: String -> Map.Map String Int -> Either String ()
isMemRefDef str map
| str `Map.member` map = Right ()
| otherwise = Left $ "Mem Ref: " ++ str ++ " is not defined"
}