-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTigerAbs.hs
127 lines (115 loc) · 5.45 KB
/
TigerAbs.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
module TigerAbs where
import TigerSymbol
-- | Esto lo introducimos para derivar Typeable y Data que nos sirve
-- más adelante en el modulo [TigerQQ](TigerQQ.hs).
import Data.Generics
-- | 'Pos' representa la posición, simple de una linea y columna, o bien un rango
-- de posiciones
data Pos = Simple {line::Int, col :: Int} | Range Pos Pos
deriving (Show, Typeable, Data)
-- | 'Escapa' representa la idea si una variable /escapa/ o no... Ver en el libro
data Escapa = Escapa | NoEscapa
deriving (Show, Typeable, Data)
posToLabel :: Pos -> String
posToLabel (Simple l r) = show l ++ '.' : show r
posToLabel (Range l r) = posToLabel l ++ '.' : posToLabel r
printPos :: Pos -> String
printPos (Simple l c) = "[L:" ++ show l ++ ".C:" ++ show c ++ "]"
printPos (Range b e) = "Entre --" ++ printPos b ++ " | " ++ printPos e
-- | Representamos las variables
data Var where
-- | Nombre de variable. Por ejemplo '(a+1)', 'a' se representa con una
-- SimpleVar "a".
SimpleVar :: Symbol -> Var
-- | Representa el acceso a un campo particular de un record. Pj: a.pepe.
-- daría a la construcción de FieldVar (SimpleVar "a") "pepe"
FieldVar :: Var -> Symbol -> Var
-- | Representa el acceso a un elemento de un array. Pj: a[(3+4)]. Daría a
-- la construcción de: SubscriptVar (SimpleVar "a") (OpExp (IntExp 3) PlusOp
-- (IntExp 4))
SubscriptVar :: Var -> Exp -> Var
deriving (Show, Typeable, Data)
-- | Tipo que representa las expresiones de tiger! Todos los constructores
-- llevan la posición en la que se encuentra el texto en el código fuente que
-- dio lugar a la construcción del AST.
data Exp where
-- | Representa una variable, el resultado es otorgar el valor de la
-- variable.
VarExp :: Var -> Pos -> Exp
-- | Unit, no es posible escribir unit en el lenguaje fuente.
UnitExp :: Pos -> Exp
-- | Break
BreakExp :: Pos -> Exp
-- | Nil
NilExp :: Pos -> Exp
-- | Enteros
IntExp :: Int -> Pos -> Exp
-- | Cadenas de texto
StringExp :: String -> Pos -> Exp
-- | Llamada de una función. Ej: f (45). Daría lugar al sig árbol: CallExp
-- "f" [IntExp 45] Pos
CallExp :: Symbol -> [Exp] -> Pos -> Exp
-- | Operaciones. Ej: 3+4. (OpExp (IntExp 3) PlusOp (IntExp 4))
OpExp :: Exp -> Oper -> Exp -> Pos -> Exp
-- | Records, representa un valor de un tipo record. Pj: lista{hd=1;tail=nil}
-- nos daría un AST: RecordExp [("hd",IntExp 1),("tail",NilExp)] "lista"
-- Pos. Recuerden, nos genera un valor de tipo record.
RecordExp :: [(Symbol, Exp)] -> Symbol -> Pos -> Exp
-- | SEcuencia de expresiones, el valor debería estar dictado por la ultima.
-- Ej: 4 ; print("Holis") ; 0. Genera: SeqExp [IntExp 4 Pos,
-- CallExp "print" [StringExp "Holis"] Pos, IntExp 0 Pos] Pos
SeqExp :: [Exp] -> Pos -> Exp
-- | Asignación. Ej: a := 3. AssignExp (SimpleVar "a") (IntExp 3 Pos) Pos
AssignExp :: Var -> Exp -> Pos -> Exp
-- | Condicional. Ej: if 3 then print("pepe"). Genera: IfExp (IntExp 3 Pos)
-- (CallExp "print" ["pepe"] Pos) NONE Pos
IfExp :: Exp -> Exp -> Maybe Exp -> Pos -> Exp
-- | Bucle while.
WhileExp :: Exp -> Exp -> Pos -> Exp
-- | Bucle for.
ForExp :: Symbol -> Escapa -> Exp -> Exp -> Exp -> Pos -> Exp
-- | Expresiones tipo let. Es el único lugar donde pueden declarar nuevas
-- varibles, tipos y funciones. Ej: let var a := 3 in a end genera el árbol:
-- LetExp [VarDec "a" Nothing Nothing (IntExp 3 Pos) Pos] (SimpleVar "a")
-- Pos
LetExp :: [Dec] -> Exp -> Pos -> Exp
-- | Representa un valor de tipo Arreglo. Nos define un nuevo valor de tipo
-- arreglo. Pj: intArray [3+4] of (2*2). Nos genra el árbol: ArrayExp
-- "intArray" (OpExp (IntExp 3 Pos) PlusOp (IntExp 4 Pos)) (OpExp (IntExp 2
-- Pos) TimesOp (IntExp 2 Pos)) Pos
ArrayExp :: Symbol -> Exp -> Exp -> Pos -> Exp
deriving (Show , Typeable , Data)
-- | Declaraciones!
data Dec where
-- | Declaraciones de funciones. Recordar que vienen en pack, dado
-- que las funciones definidas en forma contigua son __mutuamente
-- recursivas__.
FunctionDec :: [(Symbol -- Nombre de la función
,[-- Argumentos
(Symbol -- Nombre del argumento
, Escapa -- Dicho argumento escapa
, Ty) -- Tipo escrito, ver [Ty]
] --
, Maybe Symbol -- Tipo de retorno, que puede no estar.
, Exp -- Body
, Pos -- Posición en el código fuente
)] -> Dec
-- | Declaración de variable. Estas vienen solas.
-- var NOMBRE : [TIPO] := VALOR_INICIAL
VarDec :: Symbol -- Nombre
-> Escapa
-> Maybe Symbol -- El tipo, es opcional.
-> Exp -- Valor Inicial
-> Pos -> Dec
-- | Declaración de tipos. Al igual que las funciones viene un paquete
-- de tipos definidos en forma contigua y por ende mutuamente recursivos.
TypeDec :: [(Symbol, Ty, Pos)] -> Dec
deriving (Show, Typeable, Data)
data Ty = NameTy Symbol | RecordTy [(Symbol, Ty)] | ArrayTy Symbol
deriving (Show, Typeable, Data)
-- | En TigerSeman deberemos saber cuando un |Ty| es un Record.
splitRecordTy :: Ty -> Either Ty Ty
splitRecordTy t@(RecordTy _) = Left t
splitRecordTy t = Right t
data Oper = PlusOp | MinusOp | TimesOp | DivideOp | EqOp | NeqOp | LtOp | LeOp | GtOp | GeOp
deriving (Show, Typeable, Data)