diff options
Diffstat (limited to 'doc/language.tex')
| -rw-r--r-- | doc/language.tex | 418 |
1 files changed, 418 insertions, 0 deletions
diff --git a/doc/language.tex b/doc/language.tex new file mode 100644 index 0000000..bfa21cb --- /dev/null +++ b/doc/language.tex @@ -0,0 +1,418 @@ +\documentclass{scrreprt} + +\usepackage[T1]{fontenc} +\usepackage{tabularx} +\usepackage{booktabs} +\usepackage{listings} +\usepackage{syntax} + +\title{The programming language Elna} + +\begin{document} + +\maketitle +\tableofcontents + +\chapter{Introduction} + +Elna is a simple, imperative, low-level programming language. + +It is intendet to accompany other languages in the areas, where a high-level +language doesn't fit well. It is also supposed to be an intermediate +representation for a such high-level hypothetical programming language. + +\part{Language} + +\chapter{Expressions} + +The expression \verb|@r.field| includes 3 expressions: + +\begin{enumerate} + \item Variable expression \verb|r|. + \item Field access \verb|(r).field|. + \item Address taking \verb|@(r.field)|. +\end{enumerate} + +The expression is evaluated in the above order. The postfix expressions +like field access have higher precedence than prefix operators. + +\section{Binary expressions} + +\begin{table} +\centering +\begin{tabularx}{0.8\textwidth}{% + l + >{\centering\arraybackslash}X + >{\raggedright\arraybackslash}X +} + \textbf{Precedence} & \textbf{Operator} & \textbf{Description}\\ + \toprule + 1 & $* \quad / \quad \%$ & Multiplication, division and remainder.\\ + \midrule + 2 & $+ \quad -$ & Addition and subtraction.\\ + \midrule + 3 & $<< \quad >>$ & Left and right shifts.\\ + \midrule + 4 & $= \quad <> \quad > \quad < \quad <= \quad >=$ & Relational operators.\\ + \midrule + 5 & $or \quad xor \quad \&$ & Logical operators.\\ + \bottomrule +\end{tabularx} +\caption{Operator precedence} +\end{table} + +\section{Unary expressions} + +Unary expressions are expressions with a prefix operator followed by one +operand. + +\verb|@| (\textit{at sign}) takes the address of its operand. The operand expression should be +addressable. + +\verb|-| (\textit{minus}) negates a numeric value. + +\verb|~| (\textit{tilde}) applied on a boolean acts as logical not. Applied on a numeric – as +bitwise not. + +\chapter{Conditional statements} +\chapter{Loop statements} + +\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} + +\part{Appendix} + +\chapter{Syntax} + +\begin{grammar} +<letter> = `A' | `B' | … | `Z' | `a' | `b' | … | `z' | `\_'. + +<counting-digit> = `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9'. + +<decimal-digit> = `0' | <counting-digit>. + +<hex-digit> = <decimal-digit> | `A' | `B' | … | `F' | `a' | `b' | … | `f'. + +<binary-digit> = `0' | `1'. + +<hex-character> = `\\x' <hex-digit> <hex-digit>. + +<escaped-character> = `\\' \\ + (`n' | `a' | `b' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `?\@' | `0'). + +<printable-character> = \enspace? a printable ASCII character\space?. + +<character> = <printable-character> | <escaped-character> | <hex-digit>. + +<identifier> = <letter> \{<letter> | <decimal-digit>\}. + +<identifier-definition> = <identifier> [`*']. + +<trait-identifier> = `#' <identifier>. + +<integer-literal> = `0' | <counting-digit> \{<decimal-digit>\}. + +<word-literal> = <integer-literal> `u' + \alt{} `0' (`X' | `x') <hex-digit> \{<hex-digit>\} + \alt{} `0' (`B' | `b') <binary-digit> \{<binary-digit>\}. + +<real-literal> = <integer-literal> `.\@' <decimal-digit> \{<decimal-digit>\} + \alt{} <integer-literal>\} `e' [`+' | `-'] <decimal-digit> \{<decimal-digit>\}. + +<string-literal> = `\textquotedbl' \{<character>\} `\textquotedbl'. + +<character-literal> = `\textquotesingle' <character> `\textquotesingle'. + +<literal> = <integer-literal> | <word-literal> | <real-literal> + \alt{} <string-literal> | <character-literal> + \alt{} `true' | `false' | `nil'. + +<trait> = <trait-identifier> `(' [<types>] `)'. + +<cast> = `cast' `(' <expression> `:\@' <type> `)'. + +<procedure-call> = <designator> `(' [<expressions>] `)'. + +<relation-operator> = `=' | `<>' | `<' | `>' | `<=' | `>='. + +<multiplication-operator> = `*' | `/' | `\%'. + +<addition-operator> = `+' | `-'. + +<shift-operator> = `<<' | `>>'. + +<unary-operator> = `@' | `~' | `-'. + +<selector> = `[' <expression> `]' | `.\@' <identifier> | `^'. + +<case> = <expressions> `:\@' <optional-statements>. + +<designator> = <reference> <selector> | <identifier>. + +<reference> = <literal> + \alt{} <designator> + \alt{} <trait> + \alt{} <cast> + \alt{} <procedure-call> + \alt{} `(' <expression> `)'. + +<factor> = <unary-operator> <factor> | <reference>. + +<term> = <factor> \{<multiplication-operator> <factor>\}. + +<simple-expression> = <term> \{<addition-operator> <term>\}. + +<comparand> = <simple-expression> \{<shift-operator> <simple-expression>\}. + +<relation> = <comparand> \{<relation-operator> <comparand>\}. + +<operand> = <relation> \{`&' <relation>\}. + +<expression> = <operand> \{(`or' | `xor') <operand>\}. + +<expressions> = <expression> \{`,' <expression>\}. + +<identifier-definitions> = <identifier-definition> \{`,' <identifier-definition>\}. + +<types> = <type> \{`,' <type>\}. + +<required-statements> = <statement> \{`;' <statement>\}. + +<optional-statements> = [<required-statements>]. + +<return-declaration> = [`->' `!\@' | `->' type]. + +<field> = <identifier> `:\@' <type>. + +<array-type> = `[' <expression> `]' <type>. + +<pointer-type> = `^' <type>. + +<record-type> = `record' [`(' <identifier> `)'] [<field> \{`;' <field>\}] `end'. + +<enumeration-type> = `(' <identifier> \{`,' <identifier>\} `)'. + +<procedure-type> = `proc' `(' [<types>] `)' <return-declaration>. + +<type> = <array-type> + \alt{} <pointer-type> + \alt{} <record-type> + \alt{} <enumeration-type> + \alt{} <procedure-type> + \alt{} <identifier>. + +<assignment> = <designator> `:=' <expression>. + +<if-statement> = `if' <expression> `then' <optional-statements> \\ + \{`elsif' <expression> `then' <optional-statements>\} \\ + {[`else' <optional-statements>]} `end'. + +<while-statement> = `while' <expression> `do' <optional-statements> \\ + \{`elsif' <expression> `do' <optional-statements>\} `end'. + +<defer-statement> = `defer' <optional-statements> `end'. + +<case-statement> = `case' <expression> `of' <case> \{`|' case\} \\ + {[`else' <optional-statements>]} `end'. + +<label-declaration> = `.\@' <identifier>. + +<goto-statement> = `goto' <identifier>. + +<statement> = <assignment> | <procedure-call> | <defer-statement> + | <label-declaration> | <goto-statement> | + | <while-statement> | <if-statement> | <case-statement>. + +<statement-part> = [`begin' <required-statements> + \alt{} `return' <expression> + \alt{} `begin' <required-statements> `;' `return' <expression>]. + +<constant-declaration> = <identifier-definition> `:=' <expression>. + +<constant-part> = [`const' \{<constant-declaration> `;'\}]. + +<variable-declaration> = <identifier-definitions> `:\@' <type> \\ + {[`:=' (<expression> | `extern')]}. + +<variable-part> = [`var' \{<variable-declaration> `;'\}]. + +<type-declaration> = <identifier-definition> `=' <type>. + +<type-part> = [`type' \{<type-declaration> `;'\}]. + +<import-declaration> = <identifier> \{`.\@' <identifier>\}. + +<import-part> = [`import' \{import-declaration `;'\}]. + +<procedure-heading> = `proc' <identifier-definition> \\ + `(' [<field> \{`,' <field>\}] `)' <return-declaration>. + +<block> = <constant-part> <variable-part> <statement-part> `end'. + +<procedure-declaration> = <procedure-heading> `;' (block | `extern'). + +<declaration-sequence> = <import-part> \\ + <constant-part> <type-part> <variable-part> \\ + \{<procedure-declaration> `;'\}. + +<program> = `program' `;' <declaration-sequence> <statement-part> `end' `.\@' + \alt{} `module' `;' <declaration-sequence> `end' `.\@'. +\end{grammar} + +\end{document} |
