deriving (Eq,Ord,Show)
data Exp =
- BExp Exp BOp Exp
+ EAss Ident Exp
| EVar Ident
- | EAss Ident Exp
| EInt Integer
| ENeg Exp
| EBool Bool
| EReadB
| ExpT Type Exp
| EDefault
- | OpExp Exp Op Exp
+ | BiOpExp Exp Op Exp
| EPost Ident Op
deriving (Eq,Ord,Show)
Program [Stm]
deriving (Eq,Ord,Show)
-data BOp =
+data Op =
Lt
| ELt
| Gt
| EGt
| Eq
| NEq
- deriving (Eq,Ord,Show)
-
-data Op =
- Plus
+ | Plus
| Minus
| Times
| Div
\begin{tabular}{lll}
{\nonterminal{Exp}} & {\arrow} &{\nonterminal{Ident}} {\terminal{{$=$}}} {\nonterminal{Exp}} \\
- & {\delimit} &{\nonterminal{Exp1}} {\nonterminal{BOp}} {\nonterminal{Exp1}} \\
+ & {\delimit} &{\nonterminal{Exp1}} {\nonterminal{Op0}} {\nonterminal{Exp1}} \\
& {\delimit} &{\nonterminal{Exp1}} \\
\end{tabular}\\
\end{tabular}\\
\begin{tabular}{lll}
-{\nonterminal{BOp}} & {\arrow} &{\terminal{{$<$}}} \\
+{\nonterminal{Op0}} & {\arrow} &{\terminal{{$<$}}} \\
& {\delimit} &{\terminal{{$<$}{$=$}}} \\
& {\delimit} &{\terminal{{$>$}}} \\
& {\delimit} &{\terminal{{$>$}{$=$}}} \\
\begin{tabular}{lll}
{\nonterminal{Op}} & {\arrow} &{\nonterminal{Op1}} \\
& {\delimit} &{\nonterminal{Op2}} \\
+ & {\delimit} &{\nonterminal{Op0}} \\
\end{tabular}\\
\begin{tabular}{lll}
Exp :: { Exp }
Exp : Ident '=' Exp { EAss $1 $3 }
- | Exp1 BOp Exp1 { BExp $1 $2 $3 }
+ | Exp1 Op0 Exp1 { compExp_ $1 $2 $3 }
| Exp1 { $1 }
Stms : ListStm { Program (reverse $1) }
-BOp :: { BOp }
-BOp : '<' { Lt }
+Op0 :: { Op }
+Op0 : '<' { Lt }
| '<=' { ELt }
| '>' { Gt }
| '>=' { EGt }
Op :: { Op }
Op : Op1 { $1 }
| Op2 { $1 }
+ | Op0 { $1 }
Type :: { Type }
myLexer = tokens
decl_ t_ v_ = SDecl t_ v_ EDefault
if_ e_ s_ = SIf e_ s_ SNoop
-op1_ e1_ o_ e2_ = OpExp e1_ o_ e2_
-op2_ e1_ o_ e2_ = OpExp e1_ o_ e2_
+compExp_ e1_ o_ e2_ = BiOpExp e1_ o_ e2_
+op1_ e1_ o_ e2_ = BiOpExp e1_ o_ e2_
+op2_ e1_ o_ e2_ = BiOpExp e1_ o_ e2_
postIncr_ i_ = EPost i_ Plus
postDecr_ i_ = EPost i_ Minus
}
instance Print Exp where
prt i e = case e of
EAss id exp -> prPrec i 0 (concatD [prt 0 id , doc (showString "=") , prt 0 exp])
- BExp exp0 bop exp -> prPrec i 0 (concatD [prt 1 exp0 , prt 0 bop , prt 1 exp])
EVar id -> prPrec i 3 (concatD [prt 0 id])
EInt n -> prPrec i 3 (concatD [prt 0 n])
ENeg exp -> prPrec i 3 (concatD [doc (showString "-") , prt 3 exp])
EReadB -> prPrec i 3 (concatD [doc (showString "readBool")])
ExpT type' exp -> prPrec i 0 (concatD [prt 0 type' , prt 0 exp])
EDefault -> prPrec i 0 (concatD [])
- OpExp exp0 op exp -> prPrec i 0 (concatD [prt 0 exp0 , prt 0 op , prt 0 exp])
+ BiOpExp exp0 op exp -> prPrec i 0 (concatD [prt 0 exp0 , prt 0 op , prt 0 exp])
EPost id op -> prPrec i 0 (concatD [prt 0 id , prt 1 op])
Program stms -> prPrec i 0 (concatD [prt 0 stms])
-instance Print BOp where
+instance Print Op where
prt i e = case e of
Lt -> prPrec i 0 (concatD [doc (showString "<")])
ELt -> prPrec i 0 (concatD [doc (showString "<=")])
EGt -> prPrec i 0 (concatD [doc (showString ">=")])
Eq -> prPrec i 0 (concatD [doc (showString "==")])
NEq -> prPrec i 0 (concatD [doc (showString "!=")])
-
-
-instance Print Op where
- prt i e = case e of
Plus -> prPrec i 1 (concatD [doc (showString "+")])
Minus -> prPrec i 1 (concatD [doc (showString "-")])
Times -> prPrec i 2 (concatD [doc (showString "*")])
transExp :: Exp -> Result
transExp x = case x of
EAss id exp -> failure x
- BExp exp0 bop exp -> failure x
EVar id -> failure x
EInt n -> failure x
ENeg exp -> failure x
EReadB -> failure x
ExpT type' exp -> failure x
EDefault -> failure x
- OpExp exp0 op exp -> failure x
+ BiOpExp exp0 op exp -> failure x
EPost id op -> failure x
Program stms -> failure x
-transBOp :: BOp -> Result
-transBOp x = case x of
+transOp :: Op -> Result
+transOp x = case x of
Lt -> failure x
ELt -> failure x
Gt -> failure x
EGt -> failure x
Eq -> failure x
NEq -> failure x
-
-
-transOp :: Op -> Result
-transOp x = case x of
Plus -> failure x
Minus -> failure x
Times -> failure x
-module Typecheck where
+module Typecheck (typeCheckExp, typeCheckStm, typeCheckVar) where
import Abssyntax
import Control.Monad.State
type Types = Map Ident Type
+inList :: Eq a => a -> [a] -> Bool
+inList _ [] = False
+inList a (x:xs) = if a == x then True else inList a xs
+
typeCheckExp :: (MonadState Types m) => Exp -> m Type
-typeCheckExp (BExp e o e') = do
- TInt <- typeCheckExp e
- TInt <- typeCheckExp e'
- return TBool
-typeCheckExp (OpExp e o e') = do
- TInt <- typeCheckExp e
- TInt <- typeCheckExp e'
- return TInt
+typeCheckExp (BiOpExp e o e') = do
+ t1 <- typeCheckExp e
+ t2 <- typeCheckExp e'
+ if not(t1 == t2) then fail ""
+ else case inList o [Eq,NEq] of
+ True -> return TBool
+ False -> if not(t1 == TInt) then fail ""
+ else case inList o [Plus,Minus,Times,Div] of
+ True -> return TInt
+ False -> return TBool
typeCheckExp (EVar i) = typeCheckVar i
typeCheckExp (EAss i e) = do
a <- typeCheckVar i
SPrint. Stm ::= "print" Exp ";" ;
EAss. Exp ::= Ident "=" Exp;
-BExp. Exp ::= Exp1 BOp Exp1 ;
+compExp. Exp ::= Exp1 Op0 Exp1 ;
+define compExp e1 o e2 = BiOpExp e1 o e2 ;
op1. Exp1 ::= Exp1 Op1 Exp2 ;
-define op1 e1 o e2 = OpExp e1 o e2 ;
+define op1 e1 o e2 = BiOpExp e1 o e2 ;
op2. Exp2 ::= Exp2 Op2 Exp3 ;
-define op2 e1 o e2 = OpExp e1 o e2 ;
+define op2 e1 o e2 = BiOpExp e1 o e2 ;
postIncr. Exp3 ::= Ident "++" ;
define postIncr i = EPost i Plus ;
postDecr. Exp3 ::= Ident "--" ;
EVar. Exp3 ::= Ident ;
EInt. Exp3 ::= Integer ;
ENeg. Exp3 ::= "-" Exp3 ;
+-- ENot. Exp3 ::= "!" Exp3 ;
EBool. Exp3 ::= Bool ;
EReadI. Exp3 ::= "readInt" ;
EReadB. Exp3 ::= "readBool" ;
Program. Stms ::= [Stm] ;
-Lt. BOp ::= "<" ;
-ELt. BOp ::= "<=" ;
-Gt. BOp ::= ">" ;
-EGt. BOp ::= ">=" ;
-Eq. BOp ::= "==" ;
-NEq. BOp ::= "!=" ;
+Lt. Op0 ::= "<" ;
+ELt. Op0 ::= "<=" ;
+Gt. Op0 ::= ">" ;
+EGt. Op0 ::= ">=" ;
+Eq. Op0 ::= "==" ;
+NEq. Op0 ::= "!=" ;
Plus. Op1 ::= "+" ;
Minus. Op1 ::= "-" ;
_. Op ::= Op1;
_. Op ::= Op2;
+_. Op ::= Op0;
internal ExpT. Exp ::= Type Exp ;
internal SNoop. Stm ::= ;
internal EDefault. Exp ::= ;
-internal OpExp. Exp ::= Exp Op Exp ;
+internal BiOpExp. Exp ::= Exp Op Exp ;
internal NoType. Type ::= ;
internal EPost. Exp ::= Ident Op1 ;