Skip to content

Commit f292c27

Browse files
authored
Merge pull request #4 from xch-dev/compiler-redesign
Compiler redesign
2 parents f10d8a9 + 974bb38 commit f292c27

26 files changed

+889
-776
lines changed

docs/bindings.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
slug: /bindings
3+
---
4+
5+
# Bindings
6+
7+
Rue is a [purely-functional](https://en.wikipedia.org/wiki/Purely_functional_programming) programming language, and doesn't directly support mutation.
8+
9+
Practically, this means a few things:
10+
11+
1. The output of a function will remain the same every time, as long as its arguments don't change
12+
2. There is no support for mutable variables
13+
3. A function cannot change the outer scope in any way
14+
15+
However, even though _mutation_ isn't supported, you can still define `let` bindings:
16+
17+
```rue
18+
fn main(num: Int) -> Int {
19+
let squared = num * num;
20+
let doubled = squared * 2;
21+
doubled + 100
22+
}
23+
```
24+
25+
In this example, we declare two bindings to make the code more readable. These can be reused multiple times to avoid calculating the same value twice or writing duplicate code.
26+
27+
## Inline Bindings
28+
29+
You can mark a `let` binding as `inline`, which forces its value to be inserted everywhere it's referenced rather than being defined a single time and reused.
30+
31+
As an example, this will insert `num * num` multiple times, rather than computing it once up front:
32+
33+
```rue
34+
fn main(num: Int) -> Int {
35+
inline let squared = num * num;
36+
square + squared
37+
}
38+
```
39+
40+
This should be used sparingly, since it can come with either a performance hit, an increase in compiled output size, or both.
41+
42+
:::tip
43+
The compiler will automatically inline `let` bindings if they are only referenced a single time. You almost never need to explicitly mark them as `inline`.
44+
:::

docs/builtins.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
slug: /builtins
3+
---
4+
5+
# Builtins
6+
7+
There are a number of built-in functions and types. These are intrinsic to the language and are used to implement the standard library, but can and should also be used in your code.
8+
9+
## Types
10+
11+
You can click on each of these types to go to their corresponding page and learn more:
12+
13+
1. [**Atom**](/docs/type-system/atoms.md#atom)
14+
2. [**Bytes**](/docs/type-system/atoms.md#bytes)
15+
3. [**Bytes32**](/docs/type-system/atoms.md#bytes32)
16+
4. [**PublicKey**](/docs/type-system/atoms.md#publickey)
17+
5. [**Int**](/docs/type-system/atoms.md#int)
18+
6. [**Bool**](/docs/type-system/atoms.md#bool)
19+
7. [**Any**](/docs/type-system/pairs.md#any)
20+
8. [**List**](/docs/type-system/pairs.md#lists)
21+
22+
## Functions
23+
24+
### `sha256`
25+
26+
Calculates the [SHA-256](https://en.wikipedia.org/wiki/SHA-2) hash of the bytes provided. This hash is calculated at runtime.
27+
28+
For example:
29+
30+
```rue
31+
let hash = sha256("hello");
32+
```
33+
34+
### `sha256_inline`
35+
36+
The same as `sha256`, except the value will be calculated at compile time and inserted into the program. In some rare scenario, this may be an important optimization to avoid hashing the same large constant value many times. However, in most cases, you should just use the regular `sha256` function.
37+
38+
For example:
39+
40+
```rue
41+
let hash = sha256_inline("hello");
42+
```
43+
44+
### `calculate_coin_id`
45+
46+
A builtin CLVM opcode for hashing the parent coin id, puzzle hash, and amount of a coin into its coin id. See the [Security](/docs/security.md#untrusted-values) section for an explanation of why this opcode exists. Essentially, it adds runtime checks to make sure that the length of the parent coin id and puzzle hash are 32.
47+
48+
For example:
49+
50+
```rue
51+
calculate_coin_id(parent_coin_id, puzzle_hash, amount)
52+
```
53+
54+
### `substr`
55+
56+
Returns a substring of a byte value, given a range of indices.
57+
58+
For example:
59+
60+
```rue
61+
substr("hello", 1, 4)
62+
```
63+
64+
This would return `"ell"`

docs/constants.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
slug: /constants
3+
---
4+
5+
# Constants
6+
7+
Constants allow you to write a value a single time, give it a name, and then reuse it throughout your program.
8+
9+
They are similar to [Bindings](/docs/bindings.md), which the primary difference being that they are defined at the top level of the program and are order independent. They will live for and be reused for the entire lifecycle of the `main` function.
10+
11+
As a simple example, you might want to reuse a string multiple times:
12+
13+
```rue
14+
const GREET: Bytes = "Hello, ";
15+
16+
fn main(person_a: Bytes, person_b: Bytes) -> (Bytes, Bytes) {
17+
(GREET + person_a, GREET + person_b)
18+
}
19+
```
20+
21+
## Inline Constants
22+
23+
You can mark a constant as `inline`, which forces its value to be inserted everywhere it's referenced rather than being defined a single time and reused.
24+
25+
As an example, this will behave the same as if you had written the string multiple times:
26+
27+
```rue
28+
inline const GREET: Bytes = "Hello, ";
29+
30+
fn main(person_a: Bytes, person_b: Bytes) -> (Bytes, Bytes) {
31+
(GREET + person_a, GREET + person_b)
32+
}
33+
```
34+
35+
This should be used sparingly, since it can come with either a performance hit, an increase in compiled output size, or both.
36+
37+
:::tip
38+
The compiler will automatically inline constants if they are only referenced a single time. You almost never need to explicitly mark them as `inline`.
39+
:::

docs/definitions/constants.md

Lines changed: 0 additions & 48 deletions
This file was deleted.

docs/definitions/functions.md

Lines changed: 0 additions & 155 deletions
This file was deleted.

0 commit comments

Comments
 (0)