Skip to content

Commit

Permalink
docs: Add a README with code examples
Browse files Browse the repository at this point in the history
  • Loading branch information
Sword-Smith committed Aug 24, 2024
1 parent 0c1c675 commit eefc5df
Showing 1 changed file with 123 additions and 0 deletions.
123 changes: 123 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# tasm-lang

[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![GitHub CI](https://github.com/TritonVM/tasm-lang/actions/workflows/main.yml/badge.svg)](https://github.com/TritonVM/tasm-lang/actions)

A compiler from a subset of Rust to [Triton VM assembly](https://github.com/TritonVM/triton-vm).

## Restrictions
This compiler only handles a small part of the Rust language. There is for example no `for` loops,
and function definitions may only contain *one* `return` keyword
- There are no `for` loops, use `while` instead
- All functions must end with the `return` keyword and functions may only contain *one* `return`
statement
- All declarations must use explicit types.

And more ...

## Examples

### Simple arithmetic with `u32` numbers
Solution to [Project Euler Problem 1](https://projecteuler.net/problem=1)
<p>If we list all the natural numbers below $10$ that are multiples of $3$ or $5$, we get $3, 5, 6$ and $9$. The sum of these multiples is $23$.</p>
<p>Find the sum of all the multiples of $3$ or $5$ below $1000$.</p>

```rust
fn main() {
let mut i: u32 = 1;
let mut acc: u32 = 0;

while i < 1000 {
if i % 3 == 0 || i % 5 == 0 {
acc += i;
}

i += 1;
}

tasm::tasmlib_io_write_to_stdout___u32(acc);

return;
}
```

Notice that the result is printed to std-out through helper functions from the [`tasm-lib`](https://github.com/TritonVM/tasm-lib) library.
Also notice that the above code is valid Rust code that will run on both Triton VM and your host-machine, provided that the host-machine
implementation of `tasmlib_io_write_to_stdout___u32` is available.

### Simple use of lists, a naive implementation of Sieve of Eratosthenes
Solution to [Project Euler Problem 7](https://projecteuler.net/problem=7)
<p>By listing the first six prime numbers: $2, 3, 5, 7, 11$, and $13$, we can see that the $6$th prime is $13$.</p>
<p>What is the $10\,001$st prime number?</p>

```rust
fn main() {
// Execute with `10001` in standard input to find the 10,001th prime

let index_of_prime_to_find: u32 = tasm::tasmlib_io_read_stdin___u32();
let log2_of_desired_index: u32 = index_of_prime_to_find.ilog2();
let sieve_size: u32 = index_of_prime_to_find * log2_of_desired_index;
let mut primes: Vec<bool> = Vec::<bool>::default();

// 0 and 1 are not primes
primes.push(false);
primes.push(false);

// Initialize all cells to `true`
let mut tmp_vec_initializer: u32 = 2;
while tmp_vec_initializer < sieve_size {
primes.push(true);
tmp_vec_initializer += 1;
}

let mut num_primes_found: u32 = 1;
let mut prime_candidate: u32 = 3;
let mut last_prime_found: u32 = prime_candidate;
while num_primes_found < index_of_prime_to_find {
if primes[prime_candidate as usize] {
num_primes_found += 1;
last_prime_found = prime_candidate;
let mut multiples_of_found_prime: u32 = 2 * prime_candidate;
while multiples_of_found_prime < sieve_size {
primes[multiples_of_found_prime as usize] = false;
multiples_of_found_prime += prime_candidate;
}
}
prime_candidate += 2;
}

tasm::tasmlib_io_write_to_stdout___u32(last_prime_found);

return;
}
```

### Basic object-oriented programming style

Notice that there is full support for types native to Triton VM like `BFieldElement`, `XFieldElement`, and `Digest`.
And support for an object-oriented programming style and the initialization of memory at program execution start. In this
example, the program must be initialized with an encoded structure `TestStructure` at position `0` in memory.

```rust
#[derive(TasmObject, BFieldCodec)]
struct TestStruct {
a: BFieldElement,
b: BFieldElement,
}

impl TestStruct {
fn ab_sum(&self) -> BFieldElement {
return self.a + self.b;
}
}

fn main() {
let test_struct: Box<TestStruct> =
TestStruct::decode(&tasm::load_from_memory(BFieldElement::new(0))).unwrap();
let other_value: u64 = 2023;
tasm::tasmlib_io_write_to_stdout___bfe(test_struct.ab_sum());
return;
}
```

For many more code examples, see [programs](./src/tests_and_benchmarks/ozk/programs).

0 comments on commit eefc5df

Please sign in to comment.