module TigerTips where

import           TigerErrores
import           TigerSymbol
import TigerUnique

data RWO = RW | RO
    deriving (Show,Eq)

  # Libro : /Bindings for the Tiger Compiler/ [ 5.2 ]

  |    en memoria en la que va a estar el campo
-- de un record
  Es decir , el offset en palabras del puntero a la /primer posición/.
type Posicion = Int

  | '  ' es la representación interna de los tipos ,
  son   que maneja   . En código
  fuente ' int ' es representado originalmente por ' TInt ' de
  forma interna   .
data Tipo = TUnit
          -- ^ Tipo Unit
          | TString
  ^  
          | TNil
  ^   . Es un poco especial
          | TInt RWO
  ^   , aunque hay dos de estos .  ' RWO '
          | TArray Tipo Unique
  ^ Tipo de los arreglos ( de otro tipo ) que necesita de un
  identificador /único/.
          | TRecord [(Symbol, Tipo, Posicion)] Unique
  ^ Tipo de los records , similar a los arreglos pero con campos
          -- con nombre.
  | Referencia a un record y a un Tipo .
  Estos elementos son  en el proceso de detección de ciclos ,
          -- pero no deberían verse una vez realizada la detección.
          | RefRecord Symbol | TTipo Symbol
    deriving (Show,Eq)

  | Internamente capaz que    esta construcción .
         para   construcción
  que se comporta   constructor     ' 
  es un simple sinónimo a ' TInt RW ' .
pattern TBool :: Tipo
pattern TBool <- (TInt RW)
  where TBool = TInt RW

  TODO : Para los estudiantes avanzados ,    otro tipo que
  fuerce   .     otro tipo que nos los tenga , y
  hacer        TipoConRef - > TipoSinRef ' .

  | Hay ciertos tipos que semánticamente son  , 
  una función que nos indica    .
equivTipo :: Tipo -> Tipo -> Bool -- optimizar?
equivTipo TRecord{} TNil                = True
equivTipo TNil TRecord{}                = True
equivTipo (TRecord _ u1) (TRecord _ u2) = u1 == u2
equivTipo (TArray _ u1) (TArray _ u2)   = u1 == u2
equivTipo (TInt _) (TInt _)             = True
  TTipo es una referencia a otro tipo , no 
  encontrarnos ninguno de estos tipos .
equivTipo (TTipo _) _                   = error "Referencia a un tipo.[1]"
equivTipo _ (TTipo _)                   = error "Referencia a un tipo.[2]"
equivTipo a b                           = a == b -- Eq

  | Función /linda/ para mostrar     .
errorTipos :: Demon w => Tipo -> Tipo -> w a
errorTipos t1 t2 = derror $ pack $ "Error de tipos."
  Notar que acá se van a mostrar de forma re crota .
                   ++ " Tipo *" ++ show t1
                   ++ "* es distinto a *"
                   ++ show t2 ++ "*."

 de un record
 ^ Tipo Unit
 con nombre.
 pero no deberían verse una vez realizada la detección.
 optimizar?
 Eq
module TigerTips where

import           TigerErrores
import           TigerSymbol
import TigerUnique

data RWO = RW | RO
    deriving (Show,Eq)

  # Libro : /Bindings for the Tiger Compiler/ [ 5.2 ]

  |    en memoria en la que va a estar el campo
  Es decir , el offset en palabras del puntero a la /primer posición/.
type Posicion = Int

  | '  ' es la representación interna de los tipos ,
  son   que maneja   . En código
  fuente ' int ' es representado originalmente por ' TInt ' de
  forma interna   .
data Tipo = TUnit
          | TString
  ^  
          | TNil
  ^   . Es un poco especial
          | TInt RWO
  ^   , aunque hay dos de estos .  ' RWO '
          | TArray Tipo Unique
  ^ Tipo de los arreglos ( de otro tipo ) que necesita de un
  identificador /único/.
          | TRecord [(Symbol, Tipo, Posicion)] Unique
  ^ Tipo de los records , similar a los arreglos pero con campos
  | Referencia a un record y a un Tipo .
  Estos elementos son  en el proceso de detección de ciclos ,
          | RefRecord Symbol | TTipo Symbol
    deriving (Show,Eq)

  | Internamente capaz que    esta construcción .
         para   construcción
  que se comporta   constructor     ' 
  es un simple sinónimo a ' TInt RW ' .
pattern TBool :: Tipo
pattern TBool <- (TInt RW)
  where TBool = TInt RW

  TODO : Para los estudiantes avanzados ,    otro tipo que
  fuerce   .     otro tipo que nos los tenga , y
  hacer        TipoConRef - > TipoSinRef ' .

  | Hay ciertos tipos que semánticamente son  , 
  una función que nos indica    .
equivTipo TRecord{} TNil                = True
equivTipo TNil TRecord{}                = True
equivTipo (TRecord _ u1) (TRecord _ u2) = u1 == u2
equivTipo (TArray _ u1) (TArray _ u2)   = u1 == u2
equivTipo (TInt _) (TInt _)             = True
  TTipo es una referencia a otro tipo , no 
  encontrarnos ninguno de estos tipos .
equivTipo (TTipo _) _                   = error "Referencia a un tipo.[1]"
equivTipo _ (TTipo _)                   = error "Referencia a un tipo.[2]"

  | Función /linda/ para mostrar     .
errorTipos :: Demon w => Tipo -> Tipo -> w a
errorTipos t1 t2 = derror $ pack $ "Error de tipos."
  Notar que acá se van a mostrar de forma re crota .
                   ++ " Tipo *" ++ show t1
                   ++ "* es distinto a *"
                   ++ show t2 ++ "*."
