Skip to content

A simple (almost)functional interpreted language made by Rust

License

Notifications You must be signed in to change notification settings

cristianoliveira/rascal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rascal Build Status

A (almost)functional interpreted language made by Rust

Features of functional languages

According with Haskel wiki the features of a functional language are:

  • Functions
  • Higher-order functions
  • Purity
  • Immutable data
  • Referential transparency
  • Lazy evaluation
  • Recursion

Use

rascal ./example.rl

Repl

rascal
>>

Install and run

git clone https://github.com/cristianoliveira/rascal.git
cd rascal
cargo build && cargo install
rascal ./example.rl

Motivation?

“If you don’t know how compilers work, then you don’t know how computers work. If you’re not 100% sure whether you know how compilers work, then you don’t know how they work.” — Steve Yegge

Structure

  • Integers: 0-9
  • Boolean: true, false
  • Imutables by default: let x = 1;
  • Mutables explicit: var x = 1;
  • Assign values: x = 0;
  • Blocks: { .. }
  • Operator: +, -, *, / and %
  • Comparison: ==,!=, >, <, and and or
  • If else: if 1==1 { .. else .. }
  • Loop: while 1==1 { .. }
  • Function: let foo = fn [x] { x + 1 }
  • Print: print (1+1)
  • Line Comments: # this is a comment

Example

First project euler challenge:

# Sum a number only whether it's multiple of 5 or 3

var sum = 0;
var number = 0;

let is_multiple = fn [x, y] { (x % y) == 0 };

while number < 10 {
  if is_multiple(number, 5) or is_multiple(number, 3) { sum = sum + number };
  number = number + 1
};

sum

Each statement requires a ; unless the last statement. Example of runnable code:

Integers expressions

let x = 20;
let y = 15;
let z = x + y;
z - 5

Result: 30

Bolean expressions

let x = 2;
let y = 1;
let z = x != y;
z == true

Result: true

If Else blocks

let x = 2;
var y = 0;

if x != 2 {
  y = 13
else
  y = 42
};

y == 42

Result: true

Loops

var y = 0;

while y < 4 {
  y = y + 1
};

y == 4

Result: true

Scope per block

var y = 0;

{
  var x = y + 1
};

x == 4

Error: "Variable x doesn't exist in this context"

Functions

let foo = fn [x] { x + 1 };

foo(10)

Result: 11

High Order Functions

let composed = fn [f] { f(10) };
let foo = fn [x] { x + 1 };

composed(foo)

Result: 11

Closures

let plus = fn[x, y] { x * y };
let teen = fn[f, b] { f(10, b) };

print(teen(plus, 5));
# prints 50

let plus_builder = fn[number] {
  let func = fn[y] { plus(number, y) }; func
};
# This quite ugly but the currently parser don't allow anonymous functions :/

let double  = plus_builder(2);
double(20)

Result: 40

Future implementations

  • Strings: support for strings
  • String comparison: support for compare strings
  • Return: return in the middle of a block
  • Stable REPL: run code without exiting for sintax errors

The Architecture

It is a simple interpreded language that walks on an AST executing the program. I would like to implement some bytecode, just for science sake, but for now this is fine. Example of an AST generated by code:

var a = 10;
var b = 1;

while b != 0 {
  if a > b {
    a = a - b;
  else
    b = b - a;
  }
};

return a

sintax

Licence

MIT