From cc8f8153379c1ca071418d32e7e98129c9f6d5bb Mon Sep 17 00:00:00 2001
From: Eugen Wissner <belka@caraus.de>
Date: Thu, 4 Dec 2025 18:57:51 +0100
Subject: Describe the type system

---
 doc/language.adoc | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 297 insertions(+)

(limited to 'doc/language.adoc')

diff --git a/doc/language.adoc b/doc/language.adoc
index 53b42e4..e6c5e7b 100644
--- a/doc/language.adoc
+++ b/doc/language.adoc
@@ -8,3 +8,300 @@ 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" "."
+```
-- 
cgit v1.2.3

