Example Roost Programs

Example programs in the Roost language. Check back later for more. You should write many many more test programs as you build your compiler.

Syntax Highlighting

If you want syntax highlighting for Roost programs, treat them like Rust programs. Using the .rs extension instead of .roost will even let many editors assume the code is Rust code with no further configuration. Since Roost syntax is effectively a syntactic subset of Rust, syntax highlighting and indentation should “just work.” (But ignore any name errors, type errors, etc., if using an editor/IDE that is actually analyzing the code as Rust code. Roost semantics and types differ from Rust.)

Contents

Core Language

fib.roost

fn main(args: [String]) -> () {
    printi64(fib(parsei64(args[0], 0)));
    println("");
}

// Compute the nth number of the Fibonacci sequence
fn fib(n: i64) -> i64 {
    if (n < 2) {
        n
    } else {
        fib(n-1) + fib(n-2)
    }
}

quicksort.roost

fn partition(a: [i64], low: i64, high: i64) -> i64 {
    let pivot = a[low];
    let mut i = low;
    let mut j = high;
    while (true) { 
        while (a[i] < pivot) { i = i + 1; }
        while (a[j] > pivot) { j = j - 1; }
        if (i >= j) { return j }
        let tmp = a[i];
        a[i] = a[j]; 
        a[j] = tmp;
        i = i + 1;
        j = j - 1;
    }
    j
}

fn quicksort(a: [i64], low: i64, high: i64) -> () {
    if (low < high) {
        let mid = partition(a, low, high);
        quicksort(a, low, mid);
        quicksort(a, mid+1, high);
    }
}

fn init_array(len: i64) -> [i64] {
    let a = [0; len];
    let mut i = 0;
    while (i < a.length) {
        a[i] = random(a.length * 2);
        i = i + 1;
    }
    a
}

fn print_array(a: [i64]) -> () {
    print("Array elements: ");
    let i = 0;
    while (i < a.length) {
        printi64(a[i]);
        print(" ");
        i = i + 1;
    }
    println("");
}

fn main(args: [String]) -> () {
    if (args.length != 1) {
        println("Unspecified array length");
        exit(1);
    }

    let n = parsei64(args[0], 0);
    if (n <= 0) {
        println("Invalid array length");
        exit(1);
    }
    let a = init_array(n);
    print_array(a);
    quicksort(a, 0, n - 1);
    print_array(a);
}

sieve.roost

// Sieve of Eratosthenes

fn init_array(len: i64) -> [i64] {
    let nums = [0; len];
    let mut i = 0;
    while (i < nums.length) {
        nums[i] = i;
        i=i+1;
    }
    nums
}

fn sieve_all(nums: [i64]) -> () {
    let mut i = 2;
    while (i < nums.length) {
        sieve(nums, i);
        i=i+1; 
    }
}

fn sieve(nums: [i64], n: i64) -> () {
    let i = 2*n;
    while (i < nums.length) {
        nums[i] = 0;
        i=i+n;
    }
}

fn print_primes(nums: [i64]) -> () {
    print("Primes less than ");
    printi64(nums.length);
    print(": ");
    let mut i = 2;
    while (i < nums.length) {
        if (nums[i] != 0) {
            printi64(nums[i]);
            print(" ");
        }
        i=i+1;
    }
    println("");
}

fn main(args: [String]) -> () {
    if (args.length != 1) {
        println("Unspecified numsber.");
        return ()
    }
    println("");
    let n = parsei64(args[0], 0);
    if (n <= 0) {
        println("Invalid array length");
        return ()
    }
    let nums = init_array(n);
    sieve_all(nums);
    print_primes(nums);
}

matrix.roost

// Matrix multiplication

fn multiply(a: [[i64]], b: [[i64]], c: [[i64]]) -> () {
    let mut i = 0;
    while (i < a.length) {
        let mut j = 0;
        while (j < c[i].length) {
            c[i][j] = 0;
            let mut k = 0;
            while (k < a[i].length) {
                c[i][j] = c[i][j] + a[i][k] * b[k][j];
                k = k + 1;
            }
            j = j + 1;
        }
        i = i + 1;
    }
}

fn init_matrix(m: [[i64]]) -> () {
    let mut i = 0;
    while (i < m.length) {
        let mut j = 0;
        while (j < m[i].length) {
            m[i][j] = random(m.length*2);
            j = j + 1;
        }
        i = i + 1;
    }
}

fn print_matrix(m: [[i64]]) -> () {
    let mut i = 0;
    while (i < m.length) {
        let mut j = 0;
        while (j< m[i].length){
            printi64(m[i][j]);
            print(" ");
            j = j + 1;
        }
        print("\n");
        i = i + 1;
    }
    println("");
}

fn main(args: [String]) -> () {
    if (args.length != 3) {
        println("Invalid number of parameters.");
        exit(1);
    }

    let m = parsei64(args[0], 0);
    let n = parsei64(args[1], 0);
    let p = parsei64(args[2], 0);
    if(m < 1){
        println("Invalid value for parameter `m'");
        exit(1);
    }
    if(n < 1){
        println("Invalid value for parameter `n'");
        exit(1);
    }
    if(p < 1){
        println("Invalid value for parameter `p'");
        exit(1);
    }
    let a = [[0]; m];
    let b = [[0]; n];
    let c = [[0]; m];
    let mut i = 0;
    while (i < m) {
        a[i] = [0; n];
        i = i + 1;
    }
    let mut i = 0;
    while (i < n) {
        b[i] = [0; p];
        i = i + 1;
    }
    let mut i = 0;
    while (i < m) {
        c[i] = [0; p];
        i = i + 1;
    }
    init_matrix(a);
    println("Matrix A:");
    print_matrix(a);
    init_matrix(b);
    println("Matrix B:");
    print_matrix(b);
    multiply(a, b, c);
    println("Matrix C = A x B:");
    print_matrix(c);
}

calc.roost

// An interpreter for a small calculator language.

// Representation of expressions in the calculator language.
enum CalcExpr {
  // Number literals
  Num(i64),
  // Addition expressions
  Add(CalcExprPair),
  // Multiplication expressions
  Mul(CalcExprPair),
  // Negation expressions
  Neg(CalcExpr),
}

// A pair of expressions
struct CalcExprPair {
  left: CalcExpr,
  right: CalcExpr,
}

// Evaluate/interpret a calculator expression and return the result.
fn eval(expr: CalcExpr) -> i64 {
  match (expr) {
    Num(num) => num,
    Add(pair) => eval(pair.left) + eval(pair.right),
    Mul(pair) => eval(pair.left) * eval(pair.right),
    Neg(expr) => - eval(expr),
  }
}

// Pretty-print a calculator expression.
fn show(expr: CalcExpr) -> () {
  match (expr) {
    Num(num) => printi64(num),
    Add(pair) => show_pair(pair, "+"),
    Mul(pair) => show_pair(pair, "*"),
    Neg(expr) => {
      print("-");
      show(expr);
    },
  }
}
fn show_pair(pair: CalcExprPair, op: String) -> () {
  print("(");
  show(pair.left);
  print(" ");
  print(op);
  print(" ");
  show(pair.right);
  print(")");
}

fn main(args: [String]) -> () {
  let calcExpr = Add(CalcExprPair {
    left: Mul(CalcExprPair { left: Num(7), right: Num(3) }),
    right: Add(CalcExprPair {
      left: Neg(Mul(CalcExprPair {
        left: Num(2),
        right: Add(CalcExprPair { left: Num(4), right: Num(6) })
      })),
      right: Num(23)
    })
  });
  print("Evaluating calculator expression: ");
  show(calcExpr);
  println("");
  let result = eval(calcExpr);
  print("Result is: ");
  printi64(result);
  println("");
}