% $Id: IL.lhs,v 1.18 2003/10/28 05:43:38 wlux Exp $
%
% Copyright (c) 1999-2003 Wolfgang Lux
% See LICENSE for the full license.
%
% Modified by Martin Engelke (men@informatik.uni-kiel.de)
%
\nwfilename{IL.lhs}
\section{The intermediate language}
The module \texttt{IL} defines the intermediate language which will be
compiled into abstract machine code. The intermediate language removes
a lot of syntactic sugar from the Curry source language. Top-level
declarations are restricted to data type and function definitions. A
newtype definition serves mainly as a hint to the backend that it must
provide an auxiliary function for partial applications of the
constructor. \textbf{Newtype constructors must not occur in patterns
and may be used in expressions only as partial applications.}
Type declarations use a de-Bruijn indexing scheme (starting at 0) for
type variables. In the type of a function, all type variables are
numbered in the order of their occurence from left to right, i.e., a
type \texttt{(Int -> b) -> (a,b) -> c -> (a,c)} is translated into the
type (using integer numbers to denote the type variables)
\texttt{(Int -> 0) -> (1,0) -> 2 -> (1,2)}.
Pattern matching in an equation is handled via flexible and rigid
\texttt{Case} expressions. Overlapping rules are translated with the
help of \texttt{Or} expressions. The intermediate language has three
kinds of binding expressions, \texttt{Exist} expressions introduce a
new logical variable, \texttt{Let} expression support a single
non-recursive variable binding, and \texttt{Letrec} expressions
introduce multiple variables with recursive initializer expressions.
The intermediate language explicitly distinguishes (local) variables
and (global) functions in expressions.
\em{Note:} this modified version uses haskell type \texttt{Integer}
instead of \texttt{Int} for representing integer values. This provides
an unlimited range of integer constants in Curry programs.
\begin{verbatim}
> module IL where
> import Ident
> import Position (SrcRef(..))
> data Module = Module ModuleIdent [ModuleIdent] [Decl] deriving (Eq,Show)
> data Decl =
> DataDecl QualIdent Int [ConstrDecl [Type]]
> | NewtypeDecl QualIdent Int (ConstrDecl Type)
> | FunctionDecl QualIdent [Ident] Type Expression
> | ExternalDecl QualIdent CallConv String Type
> deriving (Eq,Show)
> data ConstrDecl a = ConstrDecl QualIdent a deriving (Eq,Show)
> data CallConv = Primitive | CCall deriving (Eq,Show)
> data Type =
> TypeConstructor QualIdent [Type]
> | TypeVariable Int
> | TypeArrow Type Type
> deriving (Eq,Show)
> data Literal = Char SrcRef Char | Int SrcRef Integer | Float SrcRef Double deriving (Eq,Show)
> data ConstrTerm =
> -- literal patterns
> LiteralPattern Literal
> -- constructors
> | ConstructorPattern QualIdent [Ident]
> -- default
> | VariablePattern Ident
> deriving (Eq,Show)
> data Expression =
> -- literal constants
> Literal Literal
> -- variables, functions, constructors
> | Variable Ident | Function QualIdent Int | Constructor QualIdent Int
> -- applications
> | Apply Expression Expression
> -- case expressions
> | Case SrcRef Eval Expression [Alt]
> -- non-determinisismic or
> | Or Expression Expression
> -- binding forms
> | Exist Ident Expression
> | Let Binding Expression
> | Letrec [Binding] Expression
> deriving (Eq,Show)
> data Eval = Rigid | Flex deriving (Eq,Show)
> data Alt = Alt ConstrTerm Expression deriving (Eq,Show)
> data Binding = Binding Ident Expression deriving (Eq,Show)
\end{verbatim}
> instance SrcRefOf ConstrTerm where
> srcRefOf (LiteralPattern l) = srcRefOf l
> srcRefOf (ConstructorPattern i _) = srcRefOf i
> srcRefOf (VariablePattern i) = srcRefOf i
> instance SrcRefOf Literal where
> srcRefOf (Char s _) = s
> srcRefOf (Int s _) = s
> srcRefOf (Float s _) = s