{-# OPTIONS --safe --sized-types #-}

module Generic.Examples.Printing where

open import Data.Bool
open import Data.Product
open import Data.List.Base using (_∷_; [])
open import Data.String
open import Function
open import Relation.Binary.PropositionalEquality

open import Data.Var
open import Data.Environment
open import StateOfTheArt.ACMM using (module Printer); open Printer
open import Generic.Syntax
open import Generic.Semantics.Printing

-- UTLC
open import Generic.Syntax.UTLC


printUTLC : Display UTLC
printUTLC = λ where
  (`app' f t)       f ++ " (" ++ t ++ ")"
  (`lam' (x , b))   "λ" ++ getW (lookup x z) ++ ". " ++ b


open import Agda.Builtin.Equality


_ : print printUTLC id^U  "λa. a"
_ = refl

_ : let tm : Tm UTLC _ _ (_  _  [])
        tm = `app (`var z) (`lam (`var (s (s z))))
    in print printUTLC tm  "b (λc. a)"
_ = refl


open import Generic.Examples.HuttonsRazor

open import Data.Nat.Show as Nat

printHR : Display HuttRaz
printHR = λ where
  (true , n , _)       Nat.show n
  (false , m , n , _)  m ++ " + " ++ n

_ : let expr : TM HuttRaz _ ;expr = ((lit 2 [+] lit 6) [+] lit 0)
    in print printHR expr  "2 + 6 + 0"
_ = refl

open import Generic.Examples.SystemF as SystemF

printSF : Display system-F
printSF  = case   { (σ , τ , _)     σ ++ " → " ++ τ })
         $ case   { ((x , b) , _)   "∀" ++ getW (lookup x z) ++ ". " ++ b })
         $ case   { (f , t , _)     f ++ "(" ++ t ++ ")" })
         $ case   { ((x , b) , _)   "λ" ++ getW (lookup x z) ++ ". " ++ b })
         $ case   { (f , T , _)     f ++ "(" ++ T ++ ")" })
                       { ((x , b) , _)   "Λ" ++ getW (lookup x z) ++ ". " ++ b })

_ : print printSF SystemF.`id  "Λa. λb. b"
_ = refl