Files
@ b06a29504c82
Branch filter:
Location: CSY/reowolf/docs/spec/definitions.md - annotation
b06a29504c82
7.6 KiB
text/markdown
more documentation of language validation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df b06a29504c82 b06a29504c82 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df 8e4c0fc8b4df | # Declarations
A module is a text stream that is convertable into a token stream. This token stream may contain declarations. At the top level of the module we expect three types of declarations: pragmas, imports, type definitions and procedure definitions. We'll specify each of these in this file in terms of the tokens (where appropriate).
## Types and Identifiers
Throughout the various declarations we will use the following building blocks. Some of these are exactly equal to one another, their meaning will arise from the context in which they're used.
```
Ident = KwIdent
Path = KwIdent "::"
TypeName = KwIdent
TypeRef = Path* KwIdent ("<" (Type ",")* Type? ">")?
ModuleName = (KwIdent ".")* KwIdent
```
So a type's name is a single identifier (which may be defined with polymorphic variables). But the reference to a type may exist in some other module, so we can have a path prefix to it (e.g. `other_module::type_name`). The optionally postfixed bit with the angular brackets is the specification of the polymorphic arguments (e.g. `other_module::some_type<u32, yet_another_module::another_type<s32>>`). The pattern `(Thing ",")* Thing?` appears quite often, and is a comma-separated list of `Thing`s which may have a trailing comma.
## Pragmas
Only two types of pragmas are currently supported: one to specify the module's name and one to specify the module's version:
```
PragmaName = "#module" ModuleName RawNL
PragmaVersion = "#version" TkInt RawNL
DeclPragma = PragmaName | PragmaVersion
```
Note that the pragma's are terminated by a newline. Hence we can have a module name defined like `#module some_name` or `#module some.dot.separated.name`, and a version is simply `#version 123` or even `#version 0x00_01_00_A2`.
## Imports
An import statement is followed by a module name and optionally a combination of aliases, specific symbols to import or a wildcard. These are specified as:
```
ImportModule = KwImport ModuleName (KwAs Ident)? ";"
ImportWildcard = KwImport ModuleName "::" "*" ";"
ImportedSymbol = TypeName (KwAs Ident)?
ImportOneSymbol = KwImport ModuleName "::" ImportedSymbol ";"
ImportMultipleSymbols = KwImport ModuleName "::" "{"
(ImportedSymbol ",")* ImportedSymbol?
"}" ";"
DeclImport = ImportModule | ImportWildcard | ImportSymbols
```
The `ImportModule` is the import of a particular name where one may optionally specify an alias (e.g. `import some_module;` or `import some_module as some_alias;`). Whenever there is a dot-separated module name, we take the last section as its alias. So if module `Foo.Foozle.Wozzle` contains a type `Bar`, then if we `import Foo.Foozle.Wozzle;`, then we refer to `Bar` as `Wozzle::Bar` (**note**: this is an initial implementation without much thought about its practical use, default alias rule may change in the future).
The `ImportWildcard` is the import of all *defined* symbols (i.e. not the symbols the imported module imports itself) within the module, such that we can refer to them directly. Taking the above example, if we write `import Foo.Foozle.Wozzle::*;`, then we may directly refer to `Bar` in the importing module.
Finally, one may also import particular symbols from a module. One may import a single symbol with an optional alias with `import SomeModule::Symbol;` or `import SomeModule::Symbol as Alias;`. Or one may import multiple symbols using `import SomeModule::{One as AnAlias, Two, Three as AnotherAlias};`.
## Enum Type Definitions
An enum acts much like a C enumeration. It is a collection of type-safe identifiers associated with an integer. It is defined as:
```
PolyVars = "<" (Ident ",")* Ident ">"
EnumVariantDef = Ident ("=" TkInt)?
DeclEnum = KwEnum Ident PolyVars? "{"
(EnumVariantDef ",")* EnumVariantDef?
"}"
```
Hence we may write a non-polymorphic enumeration as:
```
enum FileStatus {
Ok = 0,
DoesNotExist,
NotPermitted,
FailedReading = 0xFF,
}
```
And a polymorphic enumeration as:
```
enum Handle<T> {
Present,
NotPresent
}
```
We'll mention in passing that polymorphic variables to enum types can never exist in the body of the enum type. But they're allowed for now as they might be used in a useful way within struct or procedure declarations. **note**: this decision might change in the future.
## Union Type Definitions
A union in PDL is a tagged union. The tag itself cannot be decided by the programmer. A union variant may act like an enum variant in that it only specifies variants. A union differs from an enum in that it may contain an arbitrary number of embedded types. A union definition is specified as:
```
UnionVariantDef = Ident ("(" (TypeRef ",")* TypeRef? ")")?
DeclUnion = KwUnion Ident PolyVars? "{"
(UnionVariantDef ",")* UnionVariantDef?
"}"
```
Hence we may write a non-polymorphic union as:
```
union IntegerAndBool {
UnsignedSmall(u8, bool),
UnsignedLarge(u64, bool),
SignedSmall(s8, bool),
SignedLarge(s64, bool),
VeryLarge(some_module::BigIntType, bool)
}
```
And some classic examples of polymorphic unions are:
```
union Option<T> {
Some(T),
None
}
union Result<T, E> {
Ok(T),
Error(E)
}
```
## Struct Type Definitions
A struct type is a collection of named fields with a particular type. It is rather similar to structs/records in many other languages. A struct definition is specified as:
```
StructFieldDef = TypeRef Ident
DeclStruct = KwStruct Ident PolyVars? "{"
(StructFieldDef ",")* StructFieldDef?
"}"
```
Hence we may write a non-polymorphic struct as:
```
struct Integer3D {
u32 x,
u32 y,
u32 z,
}
// Or alternatively:
struct Integer3D { u32 x, u32 y, u32 z }
```
And two possible polymorphic structs as:
```
struct Point3D<T> { T x, T y, T z }
struct Pair<L, R> {
L left,
R right,
}
```
## Function Definition
A function is a callable subprocedure. It is defined as:
```
FuncArgDef = TypeRef Ident
FuncRetDef = TypeRef
DeclFunc = KwFunc Ident PolyVars? "("
(FuncArgDef ",")* FuncArgDef?
")" "->" FuncRetDef
StmtBlock
```
Hence we can have polymorphic and non-polymorphic functions with zero or multiple arguments with one return type (**note**: The language will likely feature multiple return types in one form or the other in the future). The `StmtBlock` will be introduced in the section on statements.
Two examples of functions:
```
func PickAnInt(u32 left, u32 right, bool choose_left) -> u32 {
if (choose_left) {
return left;
} else {
return right;
}
}
func PickASide<T>(Pair<T, T> pair, bool choose_left) -> T {
if (choose_left) {
return pair.left;
} else {
return pair.right;
}
}
```
## Component Definition
A component definition is the definition of a Reo connector. Currently there are two variants. The meaning of these variants will be introduced in a later section. A component is defined much in the same way as a function, except that it doesn't have a return type. Is is defined as:
```
CompVariant = KwPrim | KwComp
DeclComp = CompVariant Ident PolyVars? "("
(FuncArgDef ",")* FuncArgDef?
")"
StmtBlock
```
We'll delay examples of components until we've introduced the concept of connectors in this document.
**note**: It might be that the distinction between primitive and composite connectors (and the restrictions they place on the available language features inside each of them) will be removed in the future.
## Combining all Declarations
A module is the combination of any of the above declarations. So we may specify the possible contents of a module as:
```
Module = (
DeclPragma |
DeclImport |
DeclEnum |
DeclUnion |
DeclStruct |
DeclFunc |
DeclComp
)*
```
|