Start adding documentation to the language
This commit is contained in:
		
							parent
							
								
									5991a75d32
								
							
						
					
					
						commit
						6f5bb51e3b
					
				
							
								
								
									
										264
									
								
								documentation/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								documentation/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,264 @@ | |||||||
|  | # Reid Language | ||||||
|  | 
 | ||||||
|  | This is where the documentation for this language will go, describing the | ||||||
|  | features, syntax and standard library of the language as best as I have time and | ||||||
|  | motivation to write. | ||||||
|  | 
 | ||||||
|  | Documentation is presented in a formal grammar and an example, | ||||||
|  | syntax-highlighted with Rust, because it's close enough. | ||||||
|  | 
 | ||||||
|  | ## Syntax | ||||||
|  | 
 | ||||||
|  | Syntax for Reid is very much inspired by rust, and examples of the language can | ||||||
|  | be found in the [examples](../examples/)-folder. | ||||||
|  | 
 | ||||||
|  | In Reid **modules** (or files) on the top-level are comprised of imports, type | ||||||
|  | definitions, binop-definitions and functions. | ||||||
|  | 
 | ||||||
|  | In formal grammar | ||||||
|  | ```bnf | ||||||
|  | <module> :: (<import> | <type-definition> | <binop-definition> | <function>)* | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Table of Contents: | ||||||
|  | - [Common tokens](#common-tokens) | ||||||
|  | - [Imports](#imports) | ||||||
|  | - [Type definitions](#type-definitions) | ||||||
|  |     - [Struct types](#struct-types) | ||||||
|  | - [Binary operation Definitions](#binary-operation-definitions) | ||||||
|  | - [Function definitions](#function-definition) | ||||||
|  | - [Statement](#statement) | ||||||
|  | - [Expression](#expression) | ||||||
|  | 
 | ||||||
|  | ### Common tokens | ||||||
|  | 
 | ||||||
|  | Common token used throughout this document to express parts of grammar include: | ||||||
|  | ```bnf | ||||||
|  | <ident> :: [a-Z]([_a-Z0-9])* | ||||||
|  | 
 | ||||||
|  | <literal> :: <integer> | <real> | <char> | <string> | <bool> | ||||||
|  | <integer> :: <decimal> | <hexadecimal> | <octal> | <binary> | ||||||
|  | <real> :: [0-9]+ "." [0-9]+ | ||||||
|  | <char> :: "'" <any-character> "'" | ||||||
|  | <string> :: "\"" <any-character>* "\"" | ||||||
|  | <bool> :: "true" | "false" | ||||||
|  | 
 | ||||||
|  | // Any character (except "), or any character escaped | ||||||
|  | <any-character> :: [.] | "\" [.] | ||||||
|  | 
 | ||||||
|  | <decimal> :: [0-9]+ | ||||||
|  | <hexadecimal> :: "0x" [0-9a-f]+ | ||||||
|  | <octal> :: "0o" [0-7]+ | ||||||
|  | <binary> :: "0b" [01]+ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | <type> :: <primitive-type> | ||||||
|  |     | "[" <type> ";" <integer>] "]" | ||||||
|  |     | "*" <type> | ||||||
|  |     | "&" [ "mut" ] <type> | ||||||
|  | 
 | ||||||
|  | <primitive-type> ::  | ||||||
|  |     "char" | "bool" | | ||||||
|  |     "u8" | "u16" | "u32" | "u64" | "u128" | | ||||||
|  |     "i8" | "i16" | "i32" | "i64" | "i128" | | ||||||
|  |     "f16" | "f32" | "f32b" | "f64" | "f80" | "f128" | "f128ppc" | ||||||
|  | 
 | ||||||
|  | <binop> :: "+" | "-" | "*" | "/" | "%" | "&&" | <cmp> | ||||||
|  | <cmp> :: "<" | "<=" | "==" | "!=" | ">=" | >" | ||||||
|  | <unary> :: "+" | "-" | "!" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Imports | ||||||
|  | 
 | ||||||
|  | Imports are used to import functions and types from other modules. In formal | ||||||
|  | grammar the syntax for imports is | ||||||
|  | ```bnf | ||||||
|  | <import> :: "import" <ident> "::" <ident> ";" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | An example importing the `print`-function from `std` would be | ||||||
|  | ``` rust | ||||||
|  | import std::print; | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Type Definitions | ||||||
|  | 
 | ||||||
|  | Type definitions are used to define new types. Currently this only supports | ||||||
|  | struct-types. In formal grammar: | ||||||
|  | ```bnf | ||||||
|  | <type-definition> :: <struct-definition> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | #### Struct types | ||||||
|  | 
 | ||||||
|  | Struct (or Structure) types are aggregate types containing other types within | ||||||
|  | struct fields. In formal grammar: | ||||||
|  | ```bnf | ||||||
|  | <struct-definition> :: "struct" <ident> "{" [ <field-def> ( "," <field-def> )* [ "," ] ] "}" | ||||||
|  | <field-def> :: <ident> ":" <type> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | An example of a struct `Test` containing two fields `first` and `second` of | ||||||
|  | integer types. | ||||||
|  | ```rust | ||||||
|  | struct Test { | ||||||
|  |     first: u32, | ||||||
|  |     second: u64, | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Binary Operation Definitions | ||||||
|  | 
 | ||||||
|  | Reid has a feature where custom binary operations can be defined with a | ||||||
|  | specialized syntas. Only pre-defined operators are allowed however. In formal | ||||||
|  | grammar: | ||||||
|  | 
 | ||||||
|  | ```bnf | ||||||
|  | <binop-definition>: "impl" "binop" <param> <binop> <param> "-> " <type> <block> | ||||||
|  | <param> :: "(" <ident> ":" <type> ")" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | (Block-syntax is defined formally with functions) | ||||||
|  | 
 | ||||||
|  | An example of a custom binary operator `+` between type `u16` and `u32` could be: | ||||||
|  | ```rust | ||||||
|  | impl binop (lhs: u16) + (rhs: u32) -> u32 { | ||||||
|  |     return (lhs as u32) + rhs; | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Function Definition | ||||||
|  | 
 | ||||||
|  | Rust syntax for defining functions is similar to rust. There are two types of functions: | ||||||
|  | 1. `extern` functions which are defined in another module, used to define functions from outside modules such as `libc`. | ||||||
|  | 2. `local` functions which are defined locally in the module in Reid. Their | ||||||
|  |    definition is contained within a `block` which contains a list of | ||||||
|  |    `statement`s. | ||||||
|  | 
 | ||||||
|  | In formal grammar: | ||||||
|  | ```bnf | ||||||
|  | <function-definition> :: <extern-function> | <local-function> | ||||||
|  | <extern-function> :: "extern" "fn" <signature> ";" | ||||||
|  | <local-function> :: [ "pub" ] "fn" <signature> <block> | ||||||
|  | 
 | ||||||
|  | <signature> :: <ident> "(" [ <params> ] ")" [ "->" <type> ] | ||||||
|  | <params> <param> ( "," <param> )* | ||||||
|  | <param> :: <ident> ":" <type> | ||||||
|  | <block> :: "{" <statement>* "}" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | An example of a simple `extern` and `local` function definition would be: | ||||||
|  | ```rust | ||||||
|  | extern fn puts(message: *char) -> i32; | ||||||
|  | 
 | ||||||
|  | fn main() -> u8 { | ||||||
|  |     return 7; | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Statement | ||||||
|  | 
 | ||||||
|  | Statements in Reid is how you tell the program to do anything. Currently supported statements include: | ||||||
|  | - Let-statement to declare new variables | ||||||
|  |   - Let-statements declare immutable variables by-default, but can declare | ||||||
|  |     mutable variables with the `mut` keyword similar to Rust. | ||||||
|  | - Set-statement to re-set previously declared (mutable) variables to new values. | ||||||
|  | - Statements can also be simply expressions without intent to store the result. | ||||||
|  | - Return-statements to return values out of blocks or functions. | ||||||
|  | - For-loops to loop over a certain range of numbers | ||||||
|  | - While-loops to loop until a certain condition is no longer met. | ||||||
|  | 
 | ||||||
|  | In formal grammar: | ||||||
|  | ```bnf | ||||||
|  | <statement> :: <let> | <set> | <return> | <for> | <while> | <expr-statement> | ||||||
|  | <let> :: "let" [ "mut" ] <ident> "=" <expression> ";" | ||||||
|  | <set> :: <ident> "=" <expression> ";" | ||||||
|  | <expr-statement> :: <expression> ";" | ||||||
|  | <for> :: "for" <ident> "in" <expression> ".." <expression> <block> | ||||||
|  | <while> :: "while" <expression> <block> | ||||||
|  | <return> :: ( "return" <expression> ";" ) | <expression> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | An example of each statement type would be: | ||||||
|  | ```rust | ||||||
|  | let mut value = 5; | ||||||
|  | value = 6; | ||||||
|  | for i in 0..5 { } | ||||||
|  | while value < 5 { } | ||||||
|  | 
 | ||||||
|  | // "hard" return | ||||||
|  | return value;  | ||||||
|  | 
 | ||||||
|  | // "soft" return | ||||||
|  | value | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Expression | ||||||
|  | 
 | ||||||
|  | Expressions in Reid are anything that can return a value, such as function | ||||||
|  | calls, literals, or if-expressions. Types of supported expressions include: | ||||||
|  | - **Variable name reference**, to reference a value in a variable | ||||||
|  | - **Borrow**, which works similar to Rust but with a little less safety. In simple | ||||||
|  |   terms it creates a safer pointer-type than a regular pointer. | ||||||
|  | - **Deref**, which extracts the value out of a borrow. | ||||||
|  | - **Literal**, which is just some direct value, such as a number. | ||||||
|  | - **Array-value**, to declare a new array with a static length | ||||||
|  | - **Struct-value**, to declare a new value for a struct that has been defined | ||||||
|  |   earlier. | ||||||
|  | - Shorter way to declare arrays with a single initialized value. | ||||||
|  | - **Indexing** into an array-value | ||||||
|  | - **Accessing a field** in a struct-value | ||||||
|  | - **Binary operations** (such as add/sub/mult) | ||||||
|  | - **Unary operations** (such as !value or -value) | ||||||
|  | - **Function calls**, to invoke a predefined function with given parameters | ||||||
|  | - **Block-expressions**, which can return a value to the higher-level expression | ||||||
|  |   if they have a statement with a soft-return. Otherwise they return void. | ||||||
|  | - **If-expressions**, which can execute one of two expressions depending on the | ||||||
|  |   given condition. | ||||||
|  | - **Casts** to explicitly cast a value to another type. | ||||||
|  | 
 | ||||||
|  | Expressions can also always be surrounded by (paranthesis). | ||||||
|  | 
 | ||||||
|  | In formal grammar: | ||||||
|  | ```bnf | ||||||
|  | <expression> :: | ||||||
|  |     <variable> | <borrow> | | ||||||
|  |     <deref> | <literal> | | ||||||
|  |     <array> | <struct> | | ||||||
|  |     <indexing> | <accessing> | | ||||||
|  |     <binary-exp> | <unary-exp> | | ||||||
|  |     <function-call> | <block> | | ||||||
|  |     <if-expr> | <cast> | | ||||||
|  |     ( "(" <expression> ")" ) | ||||||
|  | 
 | ||||||
|  | <variable> :: <ident> | ||||||
|  | <borrow> :: "&" [ "mut" ] <ident> | ||||||
|  | <deref> :: "*" <ident> | ||||||
|  | <array> :: "[" <expression>* "]" | ||||||
|  | <struct> :: <ident> "{" [ <field> ( "," <field> )* [ "," ] ] | ||||||
|  | <field> :: <ident> ":" <expression> | ||||||
|  | <indexing> :: <expression> "[" <integer> "]" | ||||||
|  | <accessing> :: <expression> "." <ident> | ||||||
|  | <binary-exp> :: <expression> <binop> <expression> | ||||||
|  | <unary-exp> :: <unary> <expression> | ||||||
|  | <function-call> :: <expression> "(" [ <expression> ( "," <expression> )* ] ")" | ||||||
|  | <if-expr> :: "if" <expression> <expression> [ "else" <expression> ] | ||||||
|  | <cast> :: <expression> "as" <type> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | An example of each expression in-order is: | ||||||
|  | ```rust | ||||||
|  | varname // Variable | ||||||
|  | &varname // Borrow | ||||||
|  | *borrowed_varname // Deref | ||||||
|  | [ varname, 5, 7 ] // Array | ||||||
|  | Test { first: 4, second: 15 } // Struct | ||||||
|  | array[0] // Indexing | ||||||
|  | test.first // Accessing | ||||||
|  | 7 + value // Binop | ||||||
|  | !bool_value // Unary | ||||||
|  | func(value, 14) // Function call | ||||||
|  | if varname {} else {} // If-expression | ||||||
|  | value as u32 // cast | ||||||
|  | (value + 2) // Binop within parenthesis | ||||||
|  | ``` | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user