diff --git a/documentation/README.md b/documentation/README.md new file mode 100644 index 0000000..a8a7c00 --- /dev/null +++ b/documentation/README.md @@ -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 + :: ( | | | )* +``` + +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 + :: [a-Z]([_a-Z0-9])* + + :: | | | | + :: | | | + :: [0-9]+ "." [0-9]+ + :: "'" "'" + :: "\"" * "\"" + :: "true" | "false" + +// Any character (except "), or any character escaped + :: [.] | "\" [.] + + :: [0-9]+ + :: "0x" [0-9a-f]+ + :: "0o" [0-7]+ + :: "0b" [01]+ + + + :: + | "[" ";" ] "]" + | "*" + | "&" [ "mut" ] + + :: + "char" | "bool" | + "u8" | "u16" | "u32" | "u64" | "u128" | + "i8" | "i16" | "i32" | "i64" | "i128" | + "f16" | "f32" | "f32b" | "f64" | "f80" | "f128" | "f128ppc" + + :: "+" | "-" | "*" | "/" | "%" | "&&" | + :: "<" | "<=" | "==" | "!=" | ">=" | >" + :: "+" | "-" | "!" +``` + +### Imports + +Imports are used to import functions and types from other modules. In formal +grammar the syntax for imports is +```bnf + :: "import" "::" ";" +``` + +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 + :: +``` + +#### Struct types + +Struct (or Structure) types are aggregate types containing other types within +struct fields. In formal grammar: +```bnf + :: "struct" "{" [ ( "," )* [ "," ] ] "}" + :: ":" +``` + +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 +: "impl" "binop" "-> " + :: "(" ":" ")" +``` + +(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 + :: | + :: "extern" "fn" ";" + :: [ "pub" ] "fn" + + :: "(" [ ] ")" [ "->" ] + ( "," )* + :: ":" + :: "{" * "}" +``` + +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 + :: | | | | | + :: "let" [ "mut" ] "=" ";" + :: "=" ";" + :: ";" + :: "for" "in" ".." + :: "while" + :: ( "return" ";" ) | +``` + +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 + :: + | | + | | + | | + | | + | | + | | + | | + ( "(" ")" ) + + :: + :: "&" [ "mut" ] + :: "*" + :: "[" * "]" + :: "{" [ ( "," )* [ "," ] ] + :: ":" + :: "[" "]" + :: "." + :: + :: + :: "(" [ ( "," )* ] ")" + :: "if" [ "else" ] + :: "as" +``` + +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 +``` \ No newline at end of file