Migrate documentation to LaTeX
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,7 +1,9 @@
|
||||
/build/
|
||||
/vendor/
|
||||
|
||||
/doc/*.html
|
||||
/doc/*.pdf
|
||||
*.pdf
|
||||
*.log
|
||||
*.aux
|
||||
*.toc
|
||||
|
||||
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
|
||||
|
||||
require 'open3'
|
||||
require 'pathname'
|
||||
require 'rake/clean'
|
||||
require 'asciidoctor-pdf'
|
||||
|
||||
STAGES = Dir.glob('boot/stage*')
|
||||
.collect { |stage| File.basename stage }
|
||||
.sort { |a, b| a.delete_prefix('stage').to_i <=> b.delete_prefix('stage').to_i }
|
||||
.drop(1) # First assembly stage does not count.
|
||||
|
||||
CLEAN.include 'doc/*.pdf'
|
||||
CLOBBER.include 'build'
|
||||
|
||||
def run(exe)
|
||||
@@ -49,10 +46,3 @@ task :convert do
|
||||
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/.
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'pathname'
|
||||
require 'rake/clean'
|
||||
|
||||
CLEAN.include 'build/boot', 'build/valid'
|
||||
|
||||
Reference in New Issue
Block a user