* src/Ir.hs (Op): Add binary operators And, Or, Lshift, Rshift, Arshift and Xor. Remove operator Mod. Add relational operators Ult, Ule, Ugt and Uge. * src/StdBinop.hs (binop): Implement operators And, Or, Lshift, Rshift, Arshift and Xor. Remove operator Mod. (unsigned): New helper routine. * src/StdRelop.hs (relop): Implement operators Ult, Ule, Ugt and Uge. (unsigned): New helper routine. * src/Scan.hs (scanTokKeyword): Adjust. * NEWS: Update. --- NEWS | 6 ++++++ src/Ir.hs | 46 ++++++++++++++++++++++++++++++---------------- src/Scan.hs | 17 +++++++++++------ src/StdBinop.hs | 24 ++++++++++++++++++------ src/StdRelop.hs | 10 +++++++++- 5 files changed, 74 insertions(+), 29 deletions(-)
diff --git a/NEWS b/NEWS index d251097..9b79c56 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,11 @@ New in 0.26a:
+* Binary and relational operators implementation + + All binary (arithmetic/logic) and relational operators now follow + the specification of the Tree language defined by Andrew Appel in + his ``Modern Compiler Implementation'' books. +
New in 0.26, 2014-05-06: diff --git a/src/Ir.hs b/src/Ir.hs index 2dda499..e3ee0a4 100644 --- a/src/Ir.hs +++ b/src/Ir.hs @@ -1,7 +1,7 @@ module Ir (Exp (Const, Name, Temp, Binop, Mem, Call, ESeq), Stm (Move, Sxp, Jump, CJump, Seq, Label, LabelEnd, Literal), - Op (Add, Sub, Mul, Div, Mod, And, Or), - Relop (Eq, Ne, Lt, Gt, Le, Ge)) + Op (Add, Sub, Mul, Div, And, Or, Lshift, Rshift, Arshift, Xor), + Relop (Eq, Ne, Lt, Gt, Le, Ge, Ult, Ule, Ugt, Uge)) where
data Exp a = Const a Int @@ -42,9 +42,12 @@ data Op = Add | Sub | Mul | Div - | Mod | And | Or + | Lshift + | Rshift + | Arshift + | Xor
data Relop = Eq | Ne @@ -52,20 +55,31 @@ data Relop = Eq | Gt | Le | Ge + | Ult + | Ule + | Ugt + | Uge
instance Show Op where - show Add = "add" - show Sub = "sub" - show Mul = "mul" - show Div = "div" - show Mod = "mod" - show And = "and" - show Or = "or" + show Add = "add" + show Sub = "sub" + show Mul = "mul" + show Div = "div" + show And = "and" + show Or = "or" + show Lshift = "lshift" + show Rshift = "rshift" + show Arshift = "arshift" + show Xor = "xor"
instance Show Relop where - show Eq = "eq" - show Ne = "ne" - show Lt = "lt" - show Gt = "gt" - show Le = "le" - show Ge = "ge" + show Eq = "eq" + show Ne = "ne" + show Lt = "lt" + show Gt = "gt" + show Le = "le" + show Ge = "ge" + show Ult = "ult" + show Ule = "ule" + show Ugt = "ugt" + show Uge = "uge" diff --git a/src/Scan.hs b/src/Scan.hs index 2023545..e88c19b 100644 --- a/src/Scan.hs +++ b/src/Scan.hs @@ -146,17 +146,18 @@ scanTokKeyword "name" loc = TokName loc scanTokKeyword "seq" loc = TokSeq loc scanTokKeyword "temp" loc = TokTemp loc
-scanTokKeyword "add" loc = TokOp (Add, loc) -scanTokKeyword "mul" loc = TokOp (Mul, loc) -scanTokKeyword "sub" loc = TokOp (Sub, loc) -scanTokKeyword "div" loc = TokOp (Div, loc) -scanTokKeyword "mod" loc = TokOp (Mod, loc) +scanTokKeyword "add" loc = TokOp (Add, loc) +scanTokKeyword "mul" loc = TokOp (Mul, loc) +scanTokKeyword "sub" loc = TokOp (Sub, loc) +scanTokKeyword "div" loc = TokOp (Div, loc) +scanTokKeyword "lshift" loc = TokOp (Lshift, loc) +scanTokKeyword "rshift" loc = TokOp (Rshift, loc) +scanTokKeyword "arshift" loc = TokOp (Arshift, loc)
scanTokKeyword "(+)" loc = TokOp (Add, loc) scanTokKeyword "(*)" loc = TokOp (Mul, loc) scanTokKeyword "(-)" loc = TokOp (Sub, loc) scanTokKeyword "(/)" loc = TokOp (Div, loc) -scanTokKeyword "(%)" loc = TokOp (Mod, loc)
scanTokKeyword "eq" loc = TokRelop (Eq, loc) scanTokKeyword "ne" loc = TokRelop (Ne, loc) @@ -164,6 +165,10 @@ scanTokKeyword "lt" loc = TokRelop (Lt, loc) scanTokKeyword "gt" loc = TokRelop (Gt, loc) scanTokKeyword "le" loc = TokRelop (Le, loc) scanTokKeyword "ge" loc = TokRelop (Ge, loc) +scanTokKeyword "ult" loc = TokRelop (Ult, loc) +scanTokKeyword "ule" loc = TokRelop (Ule, loc) +scanTokKeyword "ugt" loc = TokRelop (Ugt, loc) +scanTokKeyword "uge" loc = TokRelop (Uge, loc)
scanTokKeyword "(=)" loc = TokRelop (Eq, loc) scanTokKeyword "(<>)" loc = TokRelop (Ne, loc) diff --git a/src/StdBinop.hs b/src/StdBinop.hs index 673f26a..a15eb68 100644 --- a/src/StdBinop.hs +++ b/src/StdBinop.hs @@ -2,16 +2,28 @@ module StdBinop (binop) where
import Data.Int +import Data.Word +import Data.Bits
import Ir
modulo32 op a b = fromIntegral((fromIntegral a :: Int32) `op` (fromIntegral b :: Int32))
--- FIXME: Add all binary operators. +unsigned op a b = fromIntegral((fromIntegral a :: Word) `op` b) + binop :: Op -> Int -> Int -> Int -binop Add = modulo32 (+) -binop Sub = modulo32 (-) -binop Mul = modulo32 (*) -binop Div = modulo32 quot -binop Mod = modulo32 rem +binop Add = modulo32 (+) +binop Sub = modulo32 (-) +binop Mul = modulo32 (*) +binop Div = modulo32 quot +binop And = modulo32 (.&.) +binop Or = modulo32 (.|.) +-- Logical shifts. When shifting Words (unsigned integers) instead of +-- Ints (signed integers), the shifts become logical shifts (see +-- http://rosettacode.org/wiki/Bitwise_operations#Haskell). +binop Lshift = unsigned shiftL +binop Rshift = unsigned shiftR +-- Arithmetic right shift. +binop Arshift = shiftR +binop Xor = xor diff --git a/src/StdRelop.hs b/src/StdRelop.hs index bd94ea6..183fef2 100644 --- a/src/StdRelop.hs +++ b/src/StdRelop.hs @@ -1,9 +1,12 @@ module StdRelop (relop) where
+import Data.Word + import Ir
--- FIXME: Add all relational operators. +unsigned op a b = (fromIntegral a :: Word) `op` (fromIntegral b :: Word) + relop :: Relop -> Int -> Int -> Bool relop Eq = (==) relop Ne = (/=) @@ -11,3 +14,8 @@ relop Lt = (<) relop Gt = (>) relop Le = (<=) relop Ge = (>=) +-- Unsigned integer inequalities. +relop Ult = unsigned (<) +relop Ule = unsigned (<=) +relop Ugt = unsigned (>) +relop Uge = unsigned (>=)