Migrate documentation to LaTeX
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,7 +1,9 @@
|
|||||||
/build/
|
/build/
|
||||||
/vendor/
|
/vendor/
|
||||||
|
|
||||||
/doc/*.html
|
*.pdf
|
||||||
/doc/*.pdf
|
*.log
|
||||||
|
*.aux
|
||||||
|
*.toc
|
||||||
|
|
||||||
a.out
|
a.out
|
||||||
|
|||||||
8
Gemfile
8
Gemfile
@@ -1,8 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
source 'https://rubygems.org'
|
|
||||||
|
|
||||||
gem 'asciidoctor', '~> 2.0'
|
|
||||||
gem 'asciidoctor-pdf', '~> 2.3'
|
|
||||||
|
|
||||||
gem "rake", "~> 13.3"
|
|
||||||
66
Gemfile.lock
66
Gemfile.lock
@@ -1,66 +0,0 @@
|
|||||||
GEM
|
|
||||||
remote: https://rubygems.org/
|
|
||||||
specs:
|
|
||||||
Ascii85 (2.0.1)
|
|
||||||
addressable (2.8.8)
|
|
||||||
public_suffix (>= 2.0.2, < 8.0)
|
|
||||||
afm (1.0.0)
|
|
||||||
asciidoctor (2.0.26)
|
|
||||||
asciidoctor-pdf (2.3.24)
|
|
||||||
asciidoctor (~> 2.0)
|
|
||||||
concurrent-ruby (~> 1.3)
|
|
||||||
matrix (~> 0.4)
|
|
||||||
prawn (~> 2.4.0)
|
|
||||||
prawn-icon (~> 3.0.0)
|
|
||||||
prawn-svg (~> 0.34.0)
|
|
||||||
prawn-table (~> 0.2.0)
|
|
||||||
prawn-templates (~> 0.1.0)
|
|
||||||
treetop (~> 1.6.0)
|
|
||||||
ttfunk (~> 1.7.0)
|
|
||||||
concurrent-ruby (1.3.5)
|
|
||||||
css_parser (1.21.1)
|
|
||||||
addressable
|
|
||||||
hashery (2.1.2)
|
|
||||||
matrix (0.4.3)
|
|
||||||
pdf-core (0.9.0)
|
|
||||||
pdf-reader (2.15.0)
|
|
||||||
Ascii85 (>= 1.0, < 3.0, != 2.0.0)
|
|
||||||
afm (>= 0.2.1, < 2)
|
|
||||||
hashery (~> 2.0)
|
|
||||||
ruby-rc4
|
|
||||||
ttfunk
|
|
||||||
polyglot (0.3.5)
|
|
||||||
prawn (2.4.0)
|
|
||||||
pdf-core (~> 0.9.0)
|
|
||||||
ttfunk (~> 1.7)
|
|
||||||
prawn-icon (3.0.0)
|
|
||||||
prawn (>= 1.1.0, < 3.0.0)
|
|
||||||
prawn-svg (0.34.2)
|
|
||||||
css_parser (~> 1.6)
|
|
||||||
matrix (~> 0.4.2)
|
|
||||||
prawn (>= 0.11.1, < 3)
|
|
||||||
rexml (~> 3.2)
|
|
||||||
prawn-table (0.2.2)
|
|
||||||
prawn (>= 1.3.0, < 3.0.0)
|
|
||||||
prawn-templates (0.1.2)
|
|
||||||
pdf-reader (~> 2.0)
|
|
||||||
prawn (~> 2.2)
|
|
||||||
public_suffix (7.0.0)
|
|
||||||
rake (13.3.1)
|
|
||||||
rexml (3.4.4)
|
|
||||||
ruby-rc4 (0.1.5)
|
|
||||||
treetop (1.6.18)
|
|
||||||
polyglot (~> 0.3)
|
|
||||||
ttfunk (1.7.0)
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
ruby
|
|
||||||
x86_64-linux
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
asciidoctor (~> 2.0)
|
|
||||||
asciidoctor-pdf (~> 2.3)
|
|
||||||
rake (~> 13.3)
|
|
||||||
|
|
||||||
BUNDLED WITH
|
|
||||||
2.6.9
|
|
||||||
10
Rakefile
10
Rakefile
@@ -4,16 +4,13 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'open3'
|
require 'open3'
|
||||||
require 'pathname'
|
|
||||||
require 'rake/clean'
|
require 'rake/clean'
|
||||||
require 'asciidoctor-pdf'
|
|
||||||
|
|
||||||
STAGES = Dir.glob('boot/stage*')
|
STAGES = Dir.glob('boot/stage*')
|
||||||
.collect { |stage| File.basename stage }
|
.collect { |stage| File.basename stage }
|
||||||
.sort { |a, b| a.delete_prefix('stage').to_i <=> b.delete_prefix('stage').to_i }
|
.sort { |a, b| a.delete_prefix('stage').to_i <=> b.delete_prefix('stage').to_i }
|
||||||
.drop(1) # First assembly stage does not count.
|
.drop(1) # First assembly stage does not count.
|
||||||
|
|
||||||
CLEAN.include 'doc/*.pdf'
|
|
||||||
CLOBBER.include 'build'
|
CLOBBER.include 'build'
|
||||||
|
|
||||||
def run(exe)
|
def run(exe)
|
||||||
@@ -49,10 +46,3 @@ task :convert do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
rule '.pdf' => '.adoc' do |t|
|
|
||||||
Asciidoctor.convert_file t.source, backend: 'pdf', safe: :safe
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Generate documentation'
|
|
||||||
task doc: 'doc/language.pdf'
|
|
||||||
|
|||||||
@@ -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" "."
|
|
||||||
```
|
|
||||||
418
doc/language.tex
Normal file
418
doc/language.tex
Normal file
@@ -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}
|
||||||
23
rakelib/doc.rake
Normal file
23
rakelib/doc.rake
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# 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 /build\/doc\/\w+.pdf/ => lambda { |t|
|
||||||
|
[
|
||||||
|
Pathname.new(t).relative_path_from('build').sub_ext('.tex').to_path,
|
||||||
|
'build/doc'
|
||||||
|
]
|
||||||
|
} do |t|
|
||||||
|
sh 'pdflatex', '--output-directory', 'build/doc', t.prerequisites.first
|
||||||
|
end
|
||||||
|
|
||||||
|
desc 'Generate documentation'
|
||||||
|
task doc: 'build/doc/language.pdf'
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
# obtain one at https://mozilla.org/MPL/2.0/.
|
# obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'pathname'
|
||||||
require 'rake/clean'
|
require 'rake/clean'
|
||||||
|
|
||||||
CLEAN.include 'build/boot', 'build/valid'
|
CLEAN.include 'build/boot', 'build/valid'
|
||||||
|
|||||||
Reference in New Issue
Block a user