diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-02-15 04:35:24 +0100 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-02-15 04:35:24 +0100 |
| commit | 580bd7e8579f1de36d151249500de6601e43f4a1 (patch) | |
| tree | e69d02bb786488aaf5cc6ba6671aa449f02223be | |
| parent | 5959fbb5524bbeb05a96eb15aba59e961a3efcb7 (diff) | |
| download | elna-580bd7e8579f1de36d151249500de6601e43f4a1.tar.gz | |
Add documentation
| -rw-r--r-- | doc/appendix.tex | 179 | ||||
| -rw-r--r-- | doc/credits.bib | 5 | ||||
| -rw-r--r-- | doc/language.tex | 339 | ||||
| -rw-r--r-- | doc/report.tex | 46 | ||||
| -rw-r--r-- | doc/type-system.tex | 126 | ||||
| -rw-r--r-- | rakelib/doc.rake | 32 |
6 files changed, 727 insertions, 0 deletions
diff --git a/doc/appendix.tex b/doc/appendix.tex new file mode 100644 index 0000000..0777d55 --- /dev/null +++ b/doc/appendix.tex @@ -0,0 +1,179 @@ +\part{Appendix} +\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} diff --git a/doc/credits.bib b/doc/credits.bib new file mode 100644 index 0000000..0af1709 --- /dev/null +++ b/doc/credits.bib @@ -0,0 +1,5 @@ +@book{oberon, + author = "Niklaus Wirth", + title = "The Programming Language Oberon", + year = 2016 +} diff --git a/doc/language.tex b/doc/language.tex new file mode 100644 index 0000000..9112127 --- /dev/null +++ b/doc/language.tex @@ -0,0 +1,339 @@ +\part{Language} + +An Elna program consists of one or more source files, called \textbf{modules}. + +Each module can declare \textbf{types}, \textbf{global variables} and +\textbf{procedures}, used by this module or exported to be used by other +modules. + +Each procedure can get some input and produce an output as a result of +executing a \textbf{statement block}, a list, where each \textbf{statement} +is executed in the order it appears in the block. + +Statement components are other statement blocks and \textbf{expressions}, +where a statement has control over the evaluation of its components. +Statements can also modify the state of the procedure or the program by +mutating variables. + +\chapter{Expressions} + +Expressions are constructs denoting rules of computation whereby constants and current values of +variables are combined to derive other values by the application of operators and function +procedures. Expressions consist of operands and operators. Parentheses may be used to express +specific associations of operators and operands. + +\section{Literal constants} + +\begin{grammar} +<literal> = <integer-literal> | <word-literal> | <real-literal> + \alt{} <string-literal> | <character-literal> + \alt{} `true' | `false' | `nil'. +\end{grammar} + +Literal constants are + +\begin{itemize} + \item signed and unsigned integers, + \item real numbers, + \item booleans, + \item characters, + \item strings, + \item and enumerations. +\end{itemize} + +\section{Call expressions} + +\subsection*{Procedure call} + +\begin{grammar} +<procedure-call> = <designator> `(' [<expressions>] `)'. +\end{grammar} + +If the designator object is a procedure followed by a (possibly empty) parameter list, +the designator implies an activation of the procedure and stands for the value resulting +from its execution. The (types of the) actual parameters must correspond to the formal +parameters as specified in the procedure's declaration. + +\subsection*{Type 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)|. + +\subsection*{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 +trait 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} + +\section{Object designators} + +\begin{grammar} +<selector> = `[' <expression> `]' | `.\@' <identifier> | `^'. + +<designator> = <reference> <selector> | <identifier>. + +<reference> = <literal> + \alt{} <designator> + \alt{} <trait> + \alt{} <cast> + \alt{} <procedure-call> + \alt{} `(' <expression> `)'. +\end{grammar} + +With the exception of literal constants and call expressions, operands are denoted by +\textit{designators}. A designator consists of an identifier referring to the constant, +variable, or procedure to be designated. This identifier or any other expression may be +followed by selectors, if the designated object is an element of a structure. + +Designators are addressable, meaning that it is possible to get the address of the +designated object or assign a value to it (if the designated object is mutable). + +\subsection*{Subscript selector} + +If \verb|A| designates an array or a string, then \verb|A[E]| denotes that element of +\verb|A| whose index is the current value of the expression \verb|E|. The type of +\verb|E| must be of type \verb|Word| or \verb|Int|. The first element has index 1, +the second 2 and so on. + +\subsection*{Dereference selector} + +If \verb|P| designates a pointer, \verb|P^| denotes the object which is +referenced by \verb|P|. + +\subsection*{Field selector} + +If \verb|R| designates a record, then \verb|R.f| denotes the field \verb|f| of +\verb|R|. + +\subsection*{Variable designator} + +If the designated object is a variable, then the designator refers to the +variable's current value. + +If the designated object is a procedure, a designator without parameter list +refers to the address of the procedure. Procedure designators designate +immutable objects. + +\subsection*{Selector evaluation order} + +Selectors are evaluated from left to right. + +For example the expression \verb|r^.field| includes 3 designators: + +\begin{enumerate} + \item Variable designator \verb|r|. + \item \verb|r^| dereferences the pointer \verb|r| and refers + to the object at the address in \verb|r|. + \item \verb|r^.field| accesses the field \verb|field| in that object. +\end{enumerate} + +\section{Unary expressions} + +\begin{grammar} +<unary-operator> = `@' | `~' | `-'. + +<factor> = <unary-operator> <factor> | <reference>. +\end{grammar} + +Unary expressions are expressions with a prefix operator followed by one +operand. Unary operators in table~\ref{table:unary} associate from right +to left. + +$@$ takes the address of its operand. The operand expression should be +addressable. + +$\sim$ applied on a boolean acts as logical not. Applied on an integer --- as +bitwise not. + +\begin{table}[ht] +\centering +\begin{tabularx}{0.7\textwidth}{% + r + l + >{\centering\arraybackslash}X +} + \textbf{Symbol} & \textbf{Symbol name} & \textbf{Description} \\ + \toprule + $@$ & \textit{at sign} & Address \\ + \midrule + $-$ & \textit{minus} & Sign inversion \\ + \midrule + $+$ & \textit{plus} & Identity operation \\ + \midrule + $\sim$ & \textit{tilde} & Negation \\ + \bottomrule +\end{tabularx} +\caption{Unary operators}\label{table:unary} +\end{table} + +\section{Binary expressions} + +\begin{grammar} +<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>\}. +\end{grammar} + +The syntax of expressions distinguishes between several classes of +operators with different precedences (binding strengths). Operators of +the same precedence associate from left to right. For example, $x - y - z$ +stands for $(x - y) - z$. + +The available operators are listed in the table~\ref{table:binary}. +In some instances, several different operations are designated by +the same operator symbol. In these cases, the actual operation is +identified by the type of the operands. + +\begin{table}[ht] +\centering +\begin{tabularx}{\textwidth}{% + c + >{\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 & $\&$ & Logical conjuction. \\ + \midrule + 6 & $or \quad xor \quad$ & Logical disjunction operators. \\ + \bottomrule +\end{tabularx} +\caption{Operator precedence}\label{table:binary} +\end{table} + +\subsection*{Logical and bitwise operators} + +Meaning of the operators in table~\ref{table:logical} depends on the +operand type: + +Applied on booleans they act as logical operators. + +Applied on integers they perform the corresponding logical operation +bitwise, on each pair of bits of their operands. + +$or$ and $\&$ are short-circuiting, if the evaluation of the left +side of the operation is enough to determine the final result, +the right side should not be evaluated. + +\begin{table}[ht] +\centering +\begin{tabularx}{\textwidth}{% + r + l + >{\centering\arraybackslash}X + >{\centering\arraybackslash}X +} + \textbf{Symbol} & \textbf{Description} & + \textbf{$p \cdot q$ with $\cdot$ as logical operator stands for} & + \textbf{As bitwise operator} \\ + \toprule + $or$ & Inclusive disjunction & If $p$ then $true$, else $q$ & Bitwise or \\ + \midrule + $xor$ & Exclusive disjunction & If $p$ then not $q$, else $q$ & Bitwise xor \\ + \midrule + $\&$ & Conjuction & If $p$ then $q$, else $false$ & Bitwise and \\ + \bottomrule +\end{tabularx} +\caption{Logical operators}\label{table:logical} +\end{table} + +\subsection*{Arithmetic operators} + +Operators in table~\ref{table:arithmetic} apply to operands of numeric +types. Both operands must be of the same type, which is also the type of +the result. + +Let $q = x / y$, and $r = x \% y$. Then quotient $q$ and remainder $r$ are +defined by the equation + +\[ +x = q * y + r \mid 0 \leq r < y +\] + +Division on integer operands performs integer division. + +\begin{table}[ht] +\centering +\begin{tabular}{r l} + \textbf{Symbol} & \textbf{Result} \\ + \toprule + $+$ & Sum \\ + \midrule + $-$ & Difference \\ + \midrule + $*$ & Product \\ + \midrule + $/$ & Quotient \\ + \midrule + $\%$ & Modulus \\ + \bottomrule +\end{tabular} +\caption{Arithmetic operators}\label{table:arithmetic} +\end{table} + +\subsection*{Relations} + +Relations in table~\ref{table:relation} are boolean. The ordering +relations $<$, $<=$, $>$, $>=$ apply to the numeric types. The +relations $=$ and $<>$ apply to all types. + +\begin{table}[ht] +\centering +\begin{tabular}{r l} + \textbf{Symbol} & \textbf{Result} \\ + \toprule + $=$ & Equal \\ + \midrule + $<>$ & Unequal \\ + \midrule + $<$ & Less \\ + \midrule + $<=$ & Less or equal \\ + \midrule + $>$ & Greater \\ + \midrule + $>=$ & Greater or equal \\ + \bottomrule +\end{tabular} +\caption{Relational operators}\label{table:relation} +\end{table} + +\chapter{Statements} + +\section{Conditional statements} +\section{Loop statements} diff --git a/doc/report.tex b/doc/report.tex new file mode 100644 index 0000000..e3ed640 --- /dev/null +++ b/doc/report.tex @@ -0,0 +1,46 @@ +\documentclass{scrreprt} + +\usepackage[T1]{fontenc} +\usepackage{tabularx} +\usepackage{booktabs} +\usepackage{listings} +\usepackage{syntax} +\usepackage[backend=biber,style=verbose-ibid,dashed=false]{biblatex} + +% Do not start chapter on a new page. +\RedeclareSectionCommand[ + style=section, + indent=0pt +]{chapter} + +\bibliography{credits} + +\title{The programming language Elna} +\author{Eugen Wissner} + +\begin{document} + +\maketitle +\tableofcontents + +\addchap{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. + +\addchap{Credits} + +Since Elna syntactically resembles Oberon larger parts of this specification +are derived from the Oberon report\footnote{\cite[]{oberon}}. + +\include{language} +\include{type-system} +\include{appendix} + +% \addcontentsline{toc}{chapter}{References} +\printbibliography[heading=bibintoc, title=References]{} + +\end{document} diff --git a/doc/type-system.tex b/doc/type-system.tex new file mode 100644 index 0000000..3ae8a30 --- /dev/null +++ b/doc/type-system.tex @@ -0,0 +1,126 @@ +\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} diff --git a/rakelib/doc.rake b/rakelib/doc.rake new file mode 100644 index 0000000..54f5d35 --- /dev/null +++ b/rakelib/doc.rake @@ -0,0 +1,32 @@ +# This Source Code Form is subject to the terms of the Mozilla Public License, +# v. 2.0. If a copy of the MPL was not distributed with this file, You can +# obtain one at https://mozilla.org/MPL/2.0/. +# frozen_string_literal: true + +require 'pathname' +require 'rake/clean' + +CLEAN.include 'build/doc' +directory 'build/doc' + +rule '.bbl' => '.bcf' do |t| + task_target = Pathname.new t.name + chdir = 'doc' + output_directory = task_target.dirname.relative_path_from(chdir).to_path + source = task_target.basename('.bbl').to_path + + sh 'biber', '-output-directory', output_directory, source, chdir: +end + +namespace :doc do + task :tex do + sh 'pdflatex', '-output-directory', '../build/doc', 'report', chdir: 'doc' + end +end + +desc 'Generate documentation' +task doc: 'doc:tex' do + Rake::Task['build/doc/report.bbl'].invoke + Rake::Task['doc:tex'].reenable + Rake::Task['doc:tex'].invoke +end |
