From 580bd7e8579f1de36d151249500de6601e43f4a1 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 15 Feb 2026 04:35:24 +0100 Subject: [PATCH] Add documentation --- doc/appendix.tex | 179 +++++++++++++++++++++++ doc/credits.bib | 5 + doc/language.tex | 339 ++++++++++++++++++++++++++++++++++++++++++++ doc/report.tex | 46 ++++++ doc/type-system.tex | 126 ++++++++++++++++ rakelib/doc.rake | 32 +++++ 6 files changed, 727 insertions(+) create mode 100644 doc/appendix.tex create mode 100644 doc/credits.bib create mode 100644 doc/language.tex create mode 100644 doc/report.tex create mode 100644 doc/type-system.tex create mode 100644 rakelib/doc.rake 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} + = `A' | `B' | … | `Z' | `a' | `b' | … | `z' | `\_'. + + = `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9'. + + = `0' | . + + = | `A' | `B' | … | `F' | `a' | `b' | … | `f'. + + = `0' | `1'. + + = `\\x' . + + = `\\' \\ + (`n' | `a' | `b' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `?\@' | `0'). + + = \enspace? a printable ASCII character\space?. + + = | | . + + = \{ | \}. + + = [`*']. + + = `#' . + + = `0' | \{\}. + + = `u' + \alt{} `0' (`X' | `x') \{\} + \alt{} `0' (`B' | `b') \{\}. + + = `.\@' \{\} + \alt{} \} `e' [`+' | `-'] \{\}. + + = `\textquotedbl' \{\} `\textquotedbl'. + + = `\textquotesingle' `\textquotesingle'. + + = | | + \alt{} | + \alt{} `true' | `false' | `nil'. + + = `(' [] `)'. + + = `cast' `(' `:\@' `)'. + + = `(' [] `)'. + + = `=' | `<>' | `<' | `>' | `<=' | `>='. + + = `*' | `/' | `\%'. + + = `+' | `-'. + + = `<<' | `>>'. + + = `@' | `~' | `-'. + + = `[' `]' | `.\@' | `^'. + + = `:\@' . + + = | . + + = + \alt{} + \alt{} + \alt{} + \alt{} + \alt{} `(' `)'. + + = | . + + = \{ \}. + + = \{ \}. + + = \{ \}. + + = \{ \}. + + = \{`&' \}. + + = \{(`or' | `xor') \}. + + = \{`,' \}. + + = \{`,' \}. + + = \{`,' \}. + + = \{`;' \}. + + = []. + + = [`->' `!\@' | `->' type]. + + = `:\@' . + + = `[' `]' . + + = `^' . + + = `record' [`(' `)'] [ \{`;' \}] `end'. + + = `(' \{`,' \} `)'. + + = `proc' `(' [] `)' . + + = + \alt{} + \alt{} + \alt{} + \alt{} + \alt{} . + + = `:=' . + + = `if' `then' \\ + \{`elsif' `then' \} \\ + {[`else' ]} `end'. + + = `while' `do' \\ + \{`elsif' `do' \} `end'. + + = `defer' `end'. + + = `case' `of' \{`|' case\} \\ + {[`else' ]} `end'. + + = `.\@' . + + = `goto' . + + = | | + | | | + | | | . + + = [`begin' + \alt{} `return' + \alt{} `begin' `;' `return' ]. + + = `:=' . + + = [`const' \{ `;'\}]. + + = `:\@' \\ + {[`:=' ( | `extern')]}. + + = [`var' \{ `;'\}]. + + = `=' . + + = [`type' \{ `;'\}]. + + = \{`.\@' \}. + + = [`import' \{import-declaration `;'\}]. + + = `proc' \\ + `(' [ \{`,' \}] `)' . + + = `end'. + + = `;' (block | `extern'). + + = \\ + \\ + \{ `;'\}. + + = `program' `;' `end' `.\@' + \alt{} `module' `;' `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} + = | | + \alt{} | + \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} + = `(' [] `)'. +\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' `(' `:\@' `)'. +\end{grammar} + +The type of an object can be reinterpreted with a cast expression: \\ +\verb|cast(object: Type)|. + +\subsection*{Traits} + +\begin{grammar} + = `#' . + + = `(' [] `)'. +\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} + = `[' `]' | `.\@' | `^'. + + = | . + + = + \alt{} + \alt{} + \alt{} + \alt{} + \alt{} `(' `)'. +\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} + = `@' | `~' | `-'. + + = | . +\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} + = \{ \}. + + = \{ \}. + + = \{ \}. + + = \{ \}. + + = \{`&' \}. + + = \{(`or' | `xor') \}. +\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} + = + \alt{} + \alt{} + \alt{} + \alt{} + \alt{} . +\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} + = `^' . +\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} + = `[' `]' . +\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} + = `proc' \\ + `(' [ \{`,' \}] `)' . + + = `end'. + + = `;' (block | `extern'). + + = [`->' `!\@' | `->' type]. + + = `proc' `(' [] `)' . +\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} + = `:\@' . + + = `record' [`(' `)'] [ \{`;' \}] `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} + = `(' \{`,' \} `)'. +\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