\part{Type system}

\begin{grammar}
<type> = <array-type>
	\alt{} <pointer-type>
	\alt{} <record-type>
	\alt{} <enumeration-type>
	\alt{} <procedure-type>
	\alt{} <identifier>.
\end{grammar}

\chapter{Primitive types}

\begin{itemize}
	\item Pointer
	\item Word
	\item Int
	\item Bool
	\item String
	\item Char
\end{itemize}

\chapter{Pointer types}

\begin{grammar}
<pointer-type> = `^' <type>.
\end{grammar}

\begin{lstlisting}[caption=Example]
program;
var
  x: Int;
  y: ^Int;
begin
  y := @x;
  y^ := 0
end.
\end{lstlisting}

\chapter{Static array}

\begin{grammar}
<array-type> = `[' <expression> `]' <type>.
\end{grammar}

\begin{lstlisting}[caption=Example]
program;
var
  array: [3]Int := [1, 2, 3];
begin
  array[1] := array[2]
end.
\end{lstlisting}

\chapter{Procedure types}

\begin{grammar}
<procedure-heading> = `proc' <identifier-definition> \\
	`(' [<field> \{`,' <field>\}] `)' <return-declaration>.

<block> = <constant-part> <variable-part> <statement-part> `end'.

<procedure-declaration> = <procedure-heading> `;' (block | `extern').

<return-declaration> = [`->' `!\@' | `->' type].

<procedure-type> = `proc' `(' [<types>] `)' <return-declaration>.
\end{grammar}

\begin{lstlisting}[caption=Example]
program;
var
  a: proc(Int) -> Int;

proc f(x: Int) -> Int;
end;

begin
  a := f;
  a(0)
end.
\end{lstlisting}

\chapter{Records}

\begin{grammar}
<field> = <identifier> `:\@' <type>.

<record-type> = `record' [`(' <identifier> `)'] [<field> \{`;' <field>\}] `end'.
\end{grammar}

\begin{lstlisting}[caption=Example]
program;
type
  T = record
    x: Int
  end;
  U = record(T)
    y: Int;
    z: Int
  end;

var
  u: U;
begin
  u := U(0, 1, 2);
  u.x := 3
end.
\end{lstlisting}

\chapter{Enumerations}

\begin{grammar}
<enumeration-type> = `(' <identifier> \{`,' <identifier>\} `)'.
\end{grammar}

\begin{lstlisting}[caption=Example]
program;
type
  E = (one, two, three);
var
  e: E;
begin
  e := E.one
end.
\end{lstlisting}

\chapter{Type operations}

\chapter{Cast}

\begin{grammar}
<cast> = `cast' `(' <expression> `:\@' <type> `)'.
\end{grammar}

The type of an object can be reinterpreted with a cast expression: \\
\verb|cast(object: Type)|.

\chapter{Traits}

\begin{grammar}
<trait-identifier> = `#' <identifier>.

<trait> = <trait-identifier> `(' [<types>] `)'.
\end{grammar}

Traits allow to query some information about the types, like their size or
field offset or alignment. Calling a trait looks like a procedure call but
traits names start with a \verb|#| and their arguments are type expressions and
not value expressions.

Supported compiler traits:

\begin{itemize}
	\item \verb|#size(T)| queries type size.
	\item \verb|#align(T)| queries type alignment.
	\item \verb|#offset(T, F)| queries the offset of the field \verb|F| in the record \verb|T|.
\end{itemize}
