packages feed

lol-typing-1.20160822: Language/LOL/Typing/Collect/Grammar.ag

-- vim: syntax=haskell
optpragmas {
{-# LANGUAGE OverloadedStrings #-}
}
module {Language.LOL.Typing.Collect.Grammar} {} {
import Data.Function (($))
import Data.Maybe (Maybe(..), maybe)
import Data.Monoid (Monoid(..), (<>))
import Data.Sequence (Seq, (|>), (<|), (><))
import qualified Data.Sequence as Seq
import Prelude (Num(..))

import Language.LOL.Typing.Collect.Constraint
import Language.LOL.Typing.Type
import Language.LOL.Typing.Expr
import Language.LOL.Typing.Lib.Data.Default (Default(..))
import qualified Language.LOL.Typing.Lib.Data.Text.Buildable as Build
}

include "../Expr/Grammar.ag"

attr Expr
	-- | top-down
	inh polytys :: Collect_Context
	-- | bottom-up
	syn monovar :: Monovar
	syn constraints :: {Seq Collect_Constraint}
	syn errors use {<>} {[]} :: {[Collect_Error_Grammar]}
	-- | both
	chn freshvar :: Freshvar
attr Decl
	-- | top-down
	inh polytys :: Collect_Context
	-- | bottom-up
	syn polyvar :: Polyvar
	syn constraints :: {Seq Collect_Constraint}
	syn errors use {<>} {[]} :: {[Collect_Error_Grammar]}
	-- | both
	chn freshvar :: Freshvar

sem Expr
 | Annot
	lhs.constraints = @body.constraints |>
	                  ((@sig `generalized_by` @body.monovar) @lhs.polytys $
	                   Collect_Info_Grammar_Expr $ "Annot " <> Build.text
	                    (def::Quantification_Build_Options, @sig))
 | Var
	lhs.monovar     = @loc.monovar
	loc.monovar     = @lhs.freshvar
	lhs.freshvar    = @lhs.freshvar + 1
	loc.polyty      = context_lookup @name @lhs.polytys
	-- loc.term        = TeTy_Var_Unknown @name @loc.monovar
	lhs.constraints = case @loc.polyty of
	                   Nothing -> mempty
	                   Just p -> Seq.singleton $
	                              p `instantiates_to` @loc.monovar $
	                               Collect_Info_Grammar_Expr $ "Var " <> @name
	lhs.errors = case @loc.polyty of
	              Nothing -> [Collect_Error_Grammar_Variable_not_in_scope @name]
	              Just _  -> []
 | Abst
	lhs.monovar     = @loc.monovar
	loc.monovar     = @lhs.freshvar
	loc.arg_monovar = @lhs.freshvar + 1
	body.freshvar   = @lhs.freshvar + 2
	body.polytys    = (@name `context_insert` Monotype_Var @loc.arg_monovar) @lhs.polytys
	lhs.constraints = (@loc.monovar `unifies_with`
	                    (Monotype_Var @loc.arg_monovar .->. Monotype_Var @body.monovar) $
	                    Collect_Info_Grammar_Expr $ "Abst(body) " <> @name) <|
	                  maybe mempty (\sig -> Seq.singleton ((sig `unifies_with` @loc.arg_monovar) $
	                   Collect_Info_Grammar_Expr $ "Abst(sig) " <> Build.text sig)) @sig ><
	                  @body.constraints
 | App
	lhs.monovar     = @loc.monovar
	loc.monovar     = @lhs.freshvar
	abst.freshvar   = @lhs.freshvar + 1
	abst.polytys    = @lhs.polytys
	arg.polytys     = @lhs.polytys
	lhs.constraints = @abst.constraints <>
	                  @arg.constraints |>
	                  (@abst.monovar `unifies_with`
	                    (Monotype_Var @arg.monovar .->. Monotype_Var @loc.monovar) $
	                    Collect_Info_Grammar_Expr $ "App")
 | Let
	lhs.monovar      = @loc.monovar
	loc.monovar      = @lhs.freshvar
	loc.decl_polyvar = @lhs.freshvar + 1
	decl.freshvar    = @lhs.freshvar + 2
	decl.polytys     = @lhs.polytys
	body.polytys     = (@name `context_insert` @loc.decl_polyvar) @lhs.polytys
	lhs.constraints  = let info x = Collect_Info_Grammar_Expr $ "Let" <> "(" <> x <> ") " <> @name in
	                   @decl.constraints ><
	                   (@loc.decl_polyvar `generalizes_from` @decl.monovar)
	                    @lhs.polytys (info "decl") <|
	                   maybe mempty (\sig -> Seq.singleton
	                    ((sig `generalized_by` @decl.monovar) @lhs.polytys $
	                    Collect_Info_Grammar_Expr $ "Let(sig) " <>
	                    Build.text (def::Quantification_Build_Options, sig))) @sig ><
	                   (@loc.monovar `unifies_with` @body.monovar) (info "body") <|
	                   @body.constraints
 | Where
	lhs.monovar      = @loc.monovar
	loc.monovar      = @lhs.freshvar
	loc.decl_polyvar = @lhs.freshvar + 1
	body.freshvar    = @lhs.freshvar + 2
	decl.polytys     = @lhs.polytys
	body.polytys     = (@name `context_insert` @loc.decl_polyvar) @lhs.polytys
	lhs.constraints  = let info = Collect_Info_Grammar_Expr $ "Where " <> @name in
	                   @decl.constraints ><
	                   (@loc.decl_polyvar `generalizes_from` @decl.monovar) @lhs.polytys info <|
	                   maybe mempty (\sig -> Seq.singleton ((sig `generalized_by` @decl.monovar) @lhs.polytys $
	                    Collect_Info_Grammar_Expr $ "Where(sig) " <> Build.text
	                     (def::Quantification_Build_Options, sig))) @sig ><
	                   (@loc.monovar `unifies_with` @body.monovar) info <|
	                   @body.constraints

sem Decl
 | Let
	-- loc.monovar      = Monotype_Var @lhs.freshvar
	loc.decl_polyvar = @lhs.freshvar
	decl.freshvar    = @lhs.freshvar + 1
	decl.polytys     = @lhs.polytys
	lhs.polyvar      = @loc.decl_polyvar
	lhs.constraints  = let info x = Collect_Info_Grammar_Expr $ "Let" <> "(" <> x <> ") " <> @name in
	                   @decl.constraints ><
	                   (@loc.decl_polyvar `generalizes_from` @decl.monovar) @lhs.polytys (info "decl") <|
	                   maybe mempty (\sig -> Seq.singleton ((sig `generalized_by` @decl.monovar) @lhs.polytys $
	                    Collect_Info_Grammar_Expr $ "Let(sig) " <> Build.text
	                     (def::Quantification_Build_Options, sig))) @sig