Skip to content

Add some code examples #226

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
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