packages feed

curry-frontend-0.1: src/IL.lhs

% $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