Skip to content
24 changes: 14 additions & 10 deletions docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@

- [The Concrete Programming Language](./intro.md)
- [Getting Started](./getting_started.md)
- [Installation](./installation.md)
- [Creating a project](./project.md)
- [Installation](./installation.md)
- [Creating a project](./project.md)
- [The Language](./language/intro.md)
- [Modules](./language/modules.md)
- [Variables](./language/variables.md)
- [Functions](./language/functions.md)
- [Structs](./language/structs.md)
- [Enums](./language/enums.md)
- [Control flow](./language/control_flow.md)
- [Modules](./language/modules.md)
- [Variables](./language/variables.md)
- [Functions](./language/functions.md)
- [Types](./language/types.md)
- [References](./languages/references.md)
- [Structs](./language/structs.md)
- [Arrays](./language/arrays.md)
- [Enums](./language/enums.md)
- [Control flow](./language/control_flow.md)
- [Extern Functions](./language/extern.md)
- [Internal Details](./internal/index.md)
- [The IR](./internal/ir.md)
- [The IR builder](./internal/builder.md)
- [The IR](./internal/ir.md)
- [The IR builder](./internal/builder.md)
19 changes: 19 additions & 0 deletions docs/book/src/language/arrays.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Arrays

The syntax for declaring fixed-sized arrays is similar to Rust’s.

```rust
let array: [u8; 5] = [13, 26, 39, 52, 65];
```

Arrays are indexed with square brackets:

```rust
let first: u8 = array[0];
```

We can also declare nested arrays:

```rust
let matrix: [[u8; 2]; 2] = [[13, 26], [39, 52]];
```
24 changes: 16 additions & 8 deletions docs/book/src/language/control_flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,44 @@ fn factorial(n: i64) -> i64 {
}
```

## For
## While

A basic for loop:
The `while` keyword allows looping.

```rust
fn sum_to(limit: i64) -> i64 {
let mut result: i64 = 0;

for (let mut n: i64 = 1; n <= limit; n = n + 1) {
let mut n: i64 = 1;
while (n <= limit) {
result = result + n;
n = n + 1;
}

return result;
}
```

## While
## For

The `for` keyword can be used as a while
The `for` keyword is used to define a C-like for loop. Its composed of three elements:

- Definition
- Condition
- Increment

```rust
fn sum_to(limit: i64) -> i64 {
let mut result: i64 = 0;

let mut n: i64 = 1;
for (n <= limit) {
for (let mut n: i64 = 1; n <= limit; n = n + 1) {
result = result + n;
n = n + 1;
}

return result;
}
```

## Match

<!-- TODO -->
94 changes: 47 additions & 47 deletions docs/book/src/language/enums.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,63 @@
# Enums

With the `enum` keyword you can define a enum:
The `enum` keyword is used to define an enumeration, also known as a sum type or tagged union. Its a type that can hold one of many possible values, of different types.

```rust
mod option {
enum Option<T> {
Some {
value: T,
},
None,
}

impl<T> Option<T> {
pub fn is_some(&self) -> bool {
match self {
Option#Some { value } => {
return true;
},
Option#None => {
return false;
}
}
}

pub fn is_none(&self) -> bool {
return !self.is_some();
}
}
enum Value {
Int {
value: i32,
},
Float {
value: f32,
},
}
```

The symbol `#` is used to instantiate a specific variant of an enum.

```rust
mod Enum {
enum A {
X {
a: i32,
},
Y {
b: i32,
}
}
let v: Value = Value#Int { value: 10 };
```

fn main() -> i32 {
let x: A = A#X {
a: 2,
};
To access the inner value of an enum, you must match over its variants:

let mut result: i32 = 0;
```rust
match v {
Value#Int { value } => {
process_int(value);
},
Value#Float { value } => {
process_float(value);
},
}
```

match x {
A#X { a } => {
result = a;
## Generics

Enums can be generic over types. This allows for building the classic `Option<T>` Rust pattern.

```rust
enum Option<T> {
Some {
value: T,
},
None,
}
```

Let's implement some common methods:

```rust
impl<T> Option<T> {
pub fn is_some(&self) -> bool {
match self {
Option#Some { value } => {
return true;
},
A#Y { b } => {
result = b;
Option#None => {
return false;
}
}

return result;
}
}
}
```
18 changes: 18 additions & 0 deletions docs/book/src/language/extern.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Extern Functions

To interoperate with external libraries, you can declare external functions using the `extern` keyword.

```rust
extern fn fopen(name: *mut u8, mode: *mut u8) -> *mut u8;
extern fn fread(ptr: *mut u8, size: u64, nitems: u64, stream: *mut u8) -> u64;
```

The following snippet reads the first 4 bytes of a file:

```rust
let name: String = "filename";
let mode: String = "r";
let file: *mut u8 = fopen(name.ptr, mode.ptr);
let data: [u8; 4] = [0, 0, 0, 0];
fread(&data as *mut u8, 1, 4, file);
```
35 changes: 23 additions & 12 deletions docs/book/src/language/functions.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
# Functions

A function can be defined the following way:
The `fn` keyword is used to declare functions.

```rust
- You must specify the type of the parameters, and the return value.

pub fn name(arg1: i32) -> i32 {
return arg1 * 2;
```rust
fn add(x: i32, y: i32) -> i32 {
return x + y;
}
```

The function is called with the classic parenthesis syntax.

```rust
let z: i32 = add(x, y);
```

- `pub`: An optional keyword to make the function public outside the module.
To make a function available outside of the module, use the `pub` modifier.

The return type can be omited.
```rust
pub fn public(x: i32) {
...
}
```

## Generics

Functions can be generic:

```rust

fn name<T>(arg: T) -> T {
// ...
fn generic<T>(arg: T) -> T {
...
}
```

We must specify the generic argument type when calling it:

// call it
let x: i32 = name::<i32>(2);

```rust
let x: i32 = generic::<i32>(2);
```
71 changes: 55 additions & 16 deletions docs/book/src/language/structs.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,79 @@
# Structs

## Type functions

Creating a struct is simple enough:
To declare a structure, use the `struct` keyword.

```rust
struct Point {
x: i32,
y: i32
y: i32,
}
```

Structs can be generic over types:
To create a new instance of a struct, you can use the _struct literal syntax_, like Rust.

```rust
struct GenericStruct<T> {
x: T,
let pos: Point = Point { x: 10, y: 20 };
```

To access a field of the struct, use the _dot notation_.

```rust
let x = pos.x; // 10
let y = pos.y; // 20
```

## Methods

To declare methods on types (structs or enums), use the `impl` keyword.

```rust
impl Point {
fn new(x: i32, y: i32) -> Point {
let new: Point = Point { x: x, y: y };
return new;
}
}
```

You can associate functions to types using `impl`:
If the method is static, it can be called with the symbol `#`.

```rust
let pos: Point = Point#new(13, 26);
```

The type’s methods can also receive references to self (either mutable or inmutable), or take ownership of it.

```rust
impl Point {
pub fn new(x: i32, y: i32) -> Point {
let point: Point = Point {
x: x,
y: y,
};
fn get_x(&self) -> i32 {
return self.x;
}

return x;
fn set_x(&mut self, x: i32) {
self.x = x;
}

pub fn add_x(&mut self, value: i32) {
self.x = self.x + value;
fn consume(self) {
...
}
}
```

The _dot notation_ is used to call these methods.

```rust
pos.set_x(39);
let x: i32 = pos.get_x(); // 39
pos.consume();
```

## Generics

Structs can be generic over types:

```rust
struct Vec2<T> {
x: T,
y: T,
}
```
Loading
Loading