Commit 47481e80 authored by batterseapower's avatar batterseapower

Move CoreSyn comments upwards

parent f6f18818
......@@ -141,106 +141,127 @@ These data types are the heart of the compiler
-- optimization, analysis and code generation on.
--
-- The type parameter @b@ is for the type of binders in the expression tree.
--
-- The language consists of the following elements:
--
-- * Variables
--
-- * Primitive literals
--
-- * Applications: note that the argument may be a 'Type'.
--
-- See "CoreSyn#let_app_invariant" for another invariant
--
-- * Lambda abstraction
--
-- * Recursive and non recursive @let@s. Operationally
-- this corresponds to allocating a thunk for the things
-- bound and then executing the sub-expression.
--
-- #top_level_invariant#
-- #letrec_invariant#
--
-- The right hand sides of all top-level and recursive @let@s
-- /must/ be of lifted type (see "Type#type_classification" for
-- the meaning of /lifted/ vs. /unlifted/).
--
-- #let_app_invariant#
-- The right hand side of of a non-recursive 'Let'
-- _and_ the argument of an 'App',
-- /may/ be of unlifted type, but only if the expression
-- is ok-for-speculation. This means that the let can be floated
-- around without difficulty. For example, this is OK:
--
-- > y::Int# = x +# 1#
--
-- But this is not, as it may affect termination if the
-- expression is floated out:
--
-- > y::Int# = fac 4#
--
-- In this situation you should use @case@ rather than a @let@. The function
-- 'CoreUtils.needsCaseBinding' can help you determine which to generate, or
-- alternatively use 'MkCore.mkCoreLet' rather than this constructor directly,
-- which will generate a @case@ if necessary
--
-- #type_let#
-- We allow a /non-recursive/ let to bind a type variable, thus:
--
-- > Let (NonRec tv (Type ty)) body
--
-- This can be very convenient for postponing type substitutions until
-- the next run of the simplifier.
--
-- At the moment, the rest of the compiler only deals with type-let
-- in a Let expression, rather than at top level. We may want to revist
-- this choice.
--
-- * Case split. Operationally this corresponds to evaluating
-- the scrutinee (expression examined) to weak head normal form
-- and then examining at most one level of resulting constructor (i.e. you
-- cannot do nested pattern matching directly with this).
--
-- The binder gets bound to the value of the scrutinee,
-- and the 'Type' must be that of all the case alternatives
--
-- #case_invariants#
-- This is one of the more complicated elements of the Core language,
-- and comes with a number of restrictions:
--
-- The 'DEFAULT' case alternative must be first in the list,
-- if it occurs at all.
--
-- The remaining cases are in order of increasing
-- tag (for 'DataAlts') or
-- lit (for 'LitAlts').
-- This makes finding the relevant constructor easy,
-- and makes comparison easier too.
--
-- The list of alternatives must be exhaustive. An /exhaustive/ case
-- does not necessarily mention all constructors:
--
-- @
-- data Foo = Red | Green | Blue
-- ... case x of
-- Red -> True
-- other -> f (case x of
-- Green -> ...
-- Blue -> ... ) ...
-- @
--
-- The inner case does not need a @Red@ alternative, because @x@
-- can't be @Red@ at that program point.
--
-- * Cast an expression to a particular type.
-- This is used to implement @newtype@s (a @newtype@ constructor or
-- destructor just becomes a 'Cast' in Core) and GADTs.
--
-- * Notes. These allow general information to be added to expressions
-- in the syntax tree
--
-- * A type: this should only show up at the top level of an Arg
--
-- * A coercion
data Expr b
= Var Id -- ^ Variables
| Lit Literal -- ^ Primitive literals
| App (Expr b) (Arg b) -- ^ Applications: note that the argument may be a 'Type'.
--
-- See "CoreSyn#let_app_invariant" for another invariant
| Lam b (Expr b) -- ^ Lambda abstraction
| Let (Bind b) (Expr b) -- ^ Recursive and non recursive @let@s. Operationally
-- this corresponds to allocating a thunk for the things
-- bound and then executing the sub-expression.
--
-- #top_level_invariant#
-- #letrec_invariant#
--
-- The right hand sides of all top-level and recursive @let@s
-- /must/ be of lifted type (see "Type#type_classification" for
-- the meaning of /lifted/ vs. /unlifted/).
--
-- #let_app_invariant#
-- The right hand side of of a non-recursive 'Let'
-- _and_ the argument of an 'App',
-- /may/ be of unlifted type, but only if the expression
-- is ok-for-speculation. This means that the let can be floated
-- around without difficulty. For example, this is OK:
--
-- > y::Int# = x +# 1#
--
-- But this is not, as it may affect termination if the
-- expression is floated out:
--
-- > y::Int# = fac 4#
--
-- In this situation you should use @case@ rather than a @let@. The function
-- 'CoreUtils.needsCaseBinding' can help you determine which to generate, or
-- alternatively use 'MkCore.mkCoreLet' rather than this constructor directly,
-- which will generate a @case@ if necessary
--
-- #type_let#
-- We allow a /non-recursive/ let to bind a type variable, thus:
--
-- > Let (NonRec tv (Type ty)) body
--
-- This can be very convenient for postponing type substitutions until
-- the next run of the simplifier.
--
-- At the moment, the rest of the compiler only deals with type-let
-- in a Let expression, rather than at top level. We may want to revist
-- this choice.
| Case (Expr b) b Type [Alt b] -- ^ Case split. Operationally this corresponds to evaluating
-- the scrutinee (expression examined) to weak head normal form
-- and then examining at most one level of resulting constructor (i.e. you
-- cannot do nested pattern matching directly with this).
--
-- The binder gets bound to the value of the scrutinee,
-- and the 'Type' must be that of all the case alternatives
--
-- #case_invariants#
-- This is one of the more complicated elements of the Core language,
-- and comes with a number of restrictions:
--
-- The 'DEFAULT' case alternative must be first in the list,
-- if it occurs at all.
--
-- The remaining cases are in order of increasing
-- tag (for 'DataAlts') or
-- lit (for 'LitAlts').
-- This makes finding the relevant constructor easy,
-- and makes comparison easier too.
--
-- The list of alternatives must be exhaustive. An /exhaustive/ case
-- does not necessarily mention all constructors:
--
-- @
-- data Foo = Red | Green | Blue
-- ... case x of
-- Red -> True
-- other -> f (case x of
-- Green -> ...
-- Blue -> ... ) ...
-- @
--
-- The inner case does not need a @Red@ alternative, because @x@
-- can't be @Red@ at that program point.
| Cast (Expr b) Coercion -- ^ Cast an expression to a particular type.
-- This is used to implement @newtype@s (a @newtype@ constructor or
-- destructor just becomes a 'Cast' in Core) and GADTs.
| Note Note (Expr b) -- ^ Notes. These allow general information to be
-- added to expressions in the syntax tree
| Type Type -- ^ A type: this should only show up at the top
-- level of an Arg
| Coercion Coercion -- ^ A coercion
= Var Id
| Lit Literal
| App (Expr b) (Arg b)
| Lam b (Expr b)
| Let (Bind b) (Expr b)
| Case (Expr b) b Type [Alt b]
| Cast (Expr b) Coercion
| Note Note (Expr b)
| Type Type
| Coercion Coercion
deriving (Data, Typeable)
-- | Type synonym for expressions that occur in function argument positions.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment