Add Book of Reid
This commit is contained in:
parent
1182e3688f
commit
185bd36cd9
@ -12,6 +12,12 @@ syntax-highlighted with Rust, because it's close enough.
|
|||||||
Reid has a standard library that is referred to as `std` in code. Documentation
|
Reid has a standard library that is referred to as `std` in code. Documentation
|
||||||
about importable types and functions can be found [here](./standard_library.md).
|
about importable types and functions can be found [here](./standard_library.md).
|
||||||
|
|
||||||
|
## Book
|
||||||
|
|
||||||
|
A collection of documentation and examples to get you going can be found at [the
|
||||||
|
Book of Reid](./book.md). It is recommended you read through the chapter about
|
||||||
|
Syntax first though to familiarize yourself with the basic concepts of Reid.
|
||||||
|
|
||||||
## Syntax and general information
|
## Syntax and general information
|
||||||
|
|
||||||
Syntax for Reid is very much inspired by rust, and examples of the language can
|
Syntax for Reid is very much inspired by rust, and examples of the language can
|
||||||
|
122
documentation/book.md
Normal file
122
documentation/book.md
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
# Book of Reid
|
||||||
|
|
||||||
|
Welcome to the Book of Reid, a learning resource for Reid programming language.
|
||||||
|
This is neither just documentation or a tutorial, but something in between,
|
||||||
|
trying to establish basic concepts and philosophies.
|
||||||
|
|
||||||
|
Before reading this book, it is recommended you familiarize yourself with [the
|
||||||
|
Syntax of Reid](./README.md#syntax-and-general-information). After you're
|
||||||
|
familiar with that, you can continue here.
|
||||||
|
|
||||||
|
The best way to think about Reid is to think about how a combination of Rust's
|
||||||
|
Syntax and C's closeness to hardware would manifest itself in a language. Reid
|
||||||
|
is a very grounded language with not many safety features in reality, while
|
||||||
|
still trying to have some. Reid also has error raporting vastly superior to that
|
||||||
|
of C, similar to Rust.
|
||||||
|
|
||||||
|
Reid also, similarly to Rust, has a powerful typechecker that can infer types
|
||||||
|
automatically quite well. When this does not pan out, you can often coerce types
|
||||||
|
either in literals by adding a type after it (e.g. `5u32`), similarly to rust,
|
||||||
|
or simply casting the value (e.g. `5 as u32`).
|
||||||
|
|
||||||
|
## Table of Contents:
|
||||||
|
- [Hello World](#hello-world)
|
||||||
|
- [Borrowing and Pointers](#borrowing-and-pointers)
|
||||||
|
|
||||||
|
### Hello World
|
||||||
|
|
||||||
|
A hello world in Reid looks something like this:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
import std::print;
|
||||||
|
import std::from_str;
|
||||||
|
import std::free_string;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let message = from_str("hello world");
|
||||||
|
print(message);
|
||||||
|
free_string(&message);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Let's go through this example line-by-line:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
import std::print;
|
||||||
|
import std::from_str;
|
||||||
|
import std::free_string;
|
||||||
|
```
|
||||||
|
|
||||||
|
Tthe first 3 lines are simply imports from the [Standard
|
||||||
|
Library](./standard_library.md) to functions `print`, `from_str` and
|
||||||
|
`free_string`, which are used later in this example.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn main() {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then we declare our `main`-function. The function that gets executed after
|
||||||
|
compilation is always called `main`, and it can return a value, although it does
|
||||||
|
not necessarily have to. The return code of the program ends up being the return
|
||||||
|
value of `main`, and without a return value it may be unpredictable. In this
|
||||||
|
example we don't declare a return value for `main`.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let message = from_str("hello world");
|
||||||
|
```
|
||||||
|
|
||||||
|
Then we create our printable message with `from_str` and store it in variable
|
||||||
|
`message`. While this value could be passed to `print` directly, it is necessary
|
||||||
|
to store the value first in order to free it. Let's come back to that.
|
||||||
|
|
||||||
|
|
||||||
|
```rust
|
||||||
|
print(message);
|
||||||
|
```
|
||||||
|
|
||||||
|
Here we actually print out the message we just created, very simple.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
free_string(&message);
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally we free the string. Like mentioned before, it is necessary to store the
|
||||||
|
value in a variable so that the memory allocated for the message can be free.
|
||||||
|
While freeing the memory is not strictly necessary, it is recommended,
|
||||||
|
especially if the program runs for longer than this example.
|
||||||
|
|
||||||
|
That's the Hello World of Reid! It is not a oneliner, but at least I'd say it is quite simple in the end!
|
||||||
|
|
||||||
|
### Borrowing and Pointers
|
||||||
|
|
||||||
|
In Reid, all **variables** can be borrowed, and borrows can be dereferenced.
|
||||||
|
Borrows act like pointers, except that borrows do not have the same implicit
|
||||||
|
safety-problem as pointers, because Borrows are not implicitly unsized. With
|
||||||
|
pointers, the size of the allocated memory is unknown at compile time, which
|
||||||
|
makes them unsafe in comparisons.
|
||||||
|
|
||||||
|
Note though how **variables** were bolded; You can not make borrows out of just any expressions, they must first be stored in variables. A simple example using borrows would be:
|
||||||
|
```rust
|
||||||
|
fn main() -> u32 {
|
||||||
|
// Create a value to be mutated
|
||||||
|
let mut value = [4, 3, 2];
|
||||||
|
|
||||||
|
// Pass a mutable borrow of the value
|
||||||
|
mutate(&mut value);
|
||||||
|
|
||||||
|
// Retrieve the now-mutated value
|
||||||
|
return value[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mutate(value: &mut [u32; 3]) {
|
||||||
|
// Dereference the borrow to mutate it
|
||||||
|
*value[1] = 17;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This example will always return `17`. Notice also, how a **mutable** borrow was
|
||||||
|
passed to `mutate`-function. While borrows do not always need to be mutable,
|
||||||
|
this example would not work without the `mut`-keyword. Try it out for yourself
|
||||||
|
to see why!
|
@ -1,11 +1,15 @@
|
|||||||
// Arithmetic, function calls and imports!
|
|
||||||
|
|
||||||
|
|
||||||
fn main() -> u32 {
|
fn main() -> u32 {
|
||||||
let mut value = [4, 3, 2];
|
// Create a value to be mutated
|
||||||
|
let mut value = [4, 3, 2];
|
||||||
|
|
||||||
let mut borrow = &mut value;
|
// Pass a mutable borrow of the value
|
||||||
(*borrow)[1] = 17;
|
mutate(&mut value);
|
||||||
|
|
||||||
return value[1];
|
// Retrieve the now-mutated value
|
||||||
|
return value[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mutate(value: &mut [u32; 3]) {
|
||||||
|
// Dereference the borrow to mutate it
|
||||||
|
*value[1] = 17;
|
||||||
}
|
}
|
@ -1,25 +1,9 @@
|
|||||||
import std::print;
|
import std::print;
|
||||||
import std::from_str;
|
import std::from_str;
|
||||||
import std::add_char;
|
|
||||||
import std::set_char;
|
|
||||||
import std::free_string;
|
import std::free_string;
|
||||||
import std::new_string;
|
|
||||||
import std::add_num_to_str;
|
|
||||||
import std::concat_strings;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut test = from_str("hello");
|
let message = from_str("hello world");
|
||||||
|
print(message);
|
||||||
concat_strings(&mut test, from_str(" world"));
|
free_string(&message);
|
||||||
|
|
||||||
add_char(&mut test, '!');
|
|
||||||
add_char(&mut test, '\n');
|
|
||||||
|
|
||||||
add_num_to_str(&mut test, 175);
|
|
||||||
|
|
||||||
print(test);
|
|
||||||
|
|
||||||
free_string(&test);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
25
examples/hello_world_harder.reid
Normal file
25
examples/hello_world_harder.reid
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import std::print;
|
||||||
|
import std::from_str;
|
||||||
|
import std::add_char;
|
||||||
|
import std::set_char;
|
||||||
|
import std::free_string;
|
||||||
|
import std::new_string;
|
||||||
|
import std::add_num_to_str;
|
||||||
|
import std::concat_strings;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut test = from_str("hello");
|
||||||
|
|
||||||
|
concat_strings(&mut test, from_str(" world"));
|
||||||
|
|
||||||
|
add_char(&mut test, '!');
|
||||||
|
add_char(&mut test, '\n');
|
||||||
|
|
||||||
|
add_num_to_str(&mut test, 175);
|
||||||
|
|
||||||
|
print(test);
|
||||||
|
|
||||||
|
free_string(&test);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
@ -101,6 +101,10 @@ fn hello_world_compiles_well() {
|
|||||||
test(include_str!("../../examples/hello_world.reid"), "test", None);
|
test(include_str!("../../examples/hello_world.reid"), "test", None);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
fn hello_world_harder_compiles_well() {
|
||||||
|
test(include_str!("../../examples/hello_world_harder.reid"), "test", None);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
fn mutable_compiles_well() {
|
fn mutable_compiles_well() {
|
||||||
test(include_str!("../../examples/mutable.reid"), "test", Some(21));
|
test(include_str!("../../examples/mutable.reid"), "test", Some(21));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user