diff options
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/language.adoc | 307 | ||||
| -rw-r--r-- | doc/language.tex | 418 |
2 files changed, 418 insertions, 307 deletions
diff --git a/doc/language.adoc b/doc/language.adoc deleted file mode 100644 index e6c5e7b..0000000 --- a/doc/language.adoc +++ /dev/null @@ -1,307 +0,0 @@ -= The programming language Elna -:toc: - -== 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. - -== Expressions - -The expression `@r.field` includes 3 expressions: - -1. Variable expression `r`. -2. Field access `(r).field`. -3. Address taking `@(r.field)`. - -The expression is evaluated in the above order. The postfix expressions -like field access have higher precedence than prefix operators. - -=== Binary expressions - -.Operator precedence -|=== -|Precedence |Operator |Description - -|1 |* / % |Multiplication, division and remainder. -|2 |+ - |Addition and subtraction. -|3 |<< >> |Left and right shifts. -|4 |= <> > < <= >=| Relational operators. -|5 |or xor &| Logical operators. -|=== - -=== Unary expressions - -Unary expressions are expressions with a prefix operator followed by one -operand. - -`@` (*at sign*) takes the address of its operand. The operand expression should be -addressable. - -`-` (*minus*) negates a numeric value. - -`~` (*tilde*) applied on a boolean acts as logical not. Applied on a numeric – as -bitwise not. - -== Conditional statements - -== Loop statements - -== Type system - -``` -type = array-type | pointer-type | record-type | enumeration-type - | procedure-type | identifier. -``` - -=== Primitive types - -* Pointer -* Word -* Int -* Bool -* String -* Char - -=== Pointer types - -``` -pointer-type = "^" type. -``` - -Example: -``` -program; -var - x: Int; - y: ^Int; -begin - y := @x; - y^ := 0 -end. -``` - -=== Static array - -``` -array-type = "[" expression "]" type. -``` - -Example: -``` -program; -var - array: [3]Int := [1, 2, 3]; -begin - array[1] := array[2] -end. -``` - -=== Procedure types - -``` -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. -``` - -Example: -``` -program; -var - a: proc(Int) -> Int; - -proc f(x: Int) -> Int; -end; - -begin - a := f; - a(0) -end. -``` - -=== Records - -``` -field = identifier ":" type. -record-type = "record" ["(" identifier ")"] [field {";" field}] "end". -``` - -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. -``` - -=== Enumerations - -``` -enumeration-type = "(" identifier {"," identifier} ")". -``` - -Example: -``` -program; -type - E = (one, two, three); -var - e: E; -begin - e := E.one -end. -``` - -=== Type operations - -=== Cast - -``` -cast = "cast" "(" expression ":" type ")". -``` - -The type of an object can be reinterpreted with a cast expression: -`cast(object: Type)`. - -=== Traits - -``` -trait-identifier = "#" identifier. -trait = trait-identifier "(" [types] ")". -``` - -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 `#` and their arguments are type expressions and -not value expressions. - -Supported compiler traits: - -- `#size(T)` queries type size. -- `#align(T)` queries type alignment. -- `#offset(T, F)` queries the offset of the field `F` in the record `T`. - -== Appendix - -=== Syntax - -``` -letter = "A" | "B" | … | "Z" | "a" | "b" | … | "z" | "_". -digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9". -character = ? a printable character ?. -hex-digit = digit | "A" | "B" | … | "F" | "a" | "b" | … | "f". -binary-digit = "0" | "1". - -identifier = letter {letter | digit}. -identifier-definition = identifier ["*"]. -trait-identifier = "#" identifier. - -integer-literal = digit {digit}. -word-literal = integer-literal "u" - | "0" ("X" | "x") hex-digit {hex-digit} - | "0" ("B" | "b") binary-digit {binary-digit}. -real-literal = digit {digit} "." digit {digit}. -string-literal = """ {character} """. -character-literal = "'" {character} "'". - -literal = integer-literal | word-literal | real-literal - | string-literal | character-literal - | "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 | designator | trait | cast | procedure-call - | "(" 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 | pointer-type | record-type | enumeration-type - | procedure-type | 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 | "return" expression - | "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_declarations ";"}]. - -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" "." - | "module" ";" declaration-sequence "end" "." -``` 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} |
