então essa pergunta pode parecer muito novata, mas já estou lendo o livro "Advanced Compiler Design and Implementation" de Steven Muchnick e no primeiro capítulo de otimização ele fala sobre dobramento constante.
a primeira tentativa foi algo como abaixo, mas foi quase impossível de implementar considerando que precisava de typeclasses Integral
e Bits
.
data Value
= BoolV Bool
| IntegerV Integer
| FloatV Double
| StringV String
deriving (Show, Eq)
data Expression
= Const Value
| Temp Label
| List [Expression]
| Call Label [Expression]
| BinOp Operator Expression Expression
deriving (Show, Eq)
rerunOverIR :: Expression -> Expression
rerunOverIR = \case
Const constant -> Const constant
Temp temporary -> Temp temporary
List list -> List list
Call label args -> Call label (map rerunOverIR args)
BinOp operator lhs rhs ->
case operator of
Addition -> folder (+)
Subtraction -> folder (-)
Multiplication -> folder (*)
Modulo -> folder mod
Division -> folder div
BitwiseAnd -> folder (.&.)
BitwiseOr -> folder (.|.)
BitwiseXor -> folder xor
ShiftRight -> folder shiftR
ShiftLeft -> folder shiftL
Equal -> folder (==)
NotEqual -> folder (/=)
Greater -> folder (>)
GreaterEqual -> folder (>=)
Less -> folder (<)
LessEqual -> folder (<=)
LogicalAnd -> folder (&&)
LogicalOr -> folder (||)
_ -> error $ "this operator doesn't exist " ++ show operator
where
folder op =
case lhs of
Const c1 -> case rhs of
Const c2 -> Const $ op c1 c2
expr -> rerunOverIR $ BinOp operator (Const c1) (rerunOverIR expr)
e1 -> case rhs of
Const c2 -> rerunOverIR $ BinOp operator (rerunOverIR e1) (Const c2)
e2 -> rerunOverIR $ BinOp operator (rerunOverIR e1) (rerunOverIR e2)
então tentei desta vez mudar as expressões para abaixo, mas é ainda pior.
data Expression
= Bool Bool
| Integer Integer
| Float Double
| String String
| Temp Label
| List [Expression]
| Call Label [Expression]
| BinOp Operator Expression Expression
deriving (Show, Eq)
então minha pergunta é: como os compiladores ou intérpretes escritos em Haskell lidam adequadamente com o dobramento constante no estágio final? Tenho quase certeza de que estou no caminho errado...
Parece que você certamente deveria ser capaz de fazer isso fazendo, por exemplo,
Você está no caminho certo, mas terá que fazer o trabalho detalhado do caso para combinar quais operações binárias se aplicam a quais tipos constantes, presumivelmente para cada classe de tipo distinta em Haskell que suporta as operações necessárias.