Skip to content

caelansar/caescript

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Caescript

CI Release License: MIT Codecov

A dialect of the Monkey programming language written in Rust, has both interpreted and compiled implementation

What’s Monkey?

Monkey has a C-like syntax, supports variable bindings, prefix and infix operators, has first-class and higher-order functions, can handle closures with ease and has integers, booleans, arrays and hashes built-in. Reading through Writing An Interpreter In Go and Writing A Compiler In Go for more details

How to use

Precompiled binaries

Archives of precompiled binaries for caescript are available for Windows, macOS and Linux

Build from source code

  • Build release
$ make install_eval
  • Build release using the Compiler implementation
$ make install
  • Running the REPL
$ caescript
  • Running the Interpreter/Compiler
$ caescript [vm/eval] examples/hello.cae

With online playground

playground

Syntax

Table of Contents

Summary

  • Integers, booleans, strings, arrays, hash maps
  • Arithmetic expressions
  • Let statements
  • First-class and higher-order functions
  • Built-in functions
  • Recursion
  • Closures

Syntax overview

An example of Fibonacci function.

let fibonacci = fn(x) {
  if (x == 0) {
    0;
  } else {
    if (x == 1) {
      1;
    } else {
      fibonacci(x - 1) + fibonacci(x - 2);
    }
  }
};

fibonacci(10);

If

It supports the general if. else exists, but else if does not exist.

if (true) {
  10;
} else {
  5;
}

For

It supports break/continue in for loop block

let sum = 0;
let i = 5;
for (i>0) {
    if (i == 4) {
        break;
    }
    sum += i;
    i -= 1;
}
sum // 5

Operators

It supports the general operations.

1 + 2 + (3 * 4) - (10 / 5);
1.0 + 2.1;
!true;
!false;
+10;
-5;
1 % 2;
true && false;
"Hello" + " " + "World";
a += 1;

Return

It returns the value immediately. No further processing will be executed.

if (true) {
  return;
}
let identity = fn(x) {
  return x;
};

identity("Monkey");

Variable bindings

Variable bindings, such as those supported by many programming languages, are implemented. Variables can be defined using the let keyword.

Format:

let <identifier> = <expression>;

Example:

let x = 0;
let y = 10;
let foobar = add(5, 5);
let alias = foobar;
let identity = fn(x) { x };

Literals

Five types of literals are implemented.

Integer

Integer represents an integer value.

Format:

[-]?[1-9][0-9]*;

Example:

10;
1234;

Float

Float represents a float value.

Format:

[-]?[1-9][0-9]*\.[1-9][0-9]*;

Example:

1.0;
12.34;

Boolean

Boolean represents a general boolean types.

Format:

true | false;

Example:

true;
false;

let truthy = !false;
let falsy = !true;

String

String represents a string. Only double quotes can be used.

Format:

"<value>";

Example:

"Monkey Programming Language";
"Hello" + " " + "World";

Array

Array represents an ordered contiguous element. Each element can contain different data types.

Format:

[<expression>, <expression>, ...];

Example:

[1, 2, 3 + 3, fn(x) { x }, add(2, 2), true];
let arr = [1, true, fn(x) { x }];

arr[0];
arr[1];
arr[2](10);
arr[1 + 1](10);

Hashes

Hash expresses data associating keys with values.

Format:

{ <expression>: <expression>, <expression>: <expression>, ... };

Example:

let hash = {
  "name": "cae",
  "age": 24,
  true: "a boolean",
  99: "an integer"
};

hash["name"];
hash["a" + "ge"];
hash[true];
hash[99];
hash[100 - 1];

Function

Function supports functions like those supported by other programming languages. Support both anonymous and named functions.

Format:

fn (<parameter one>, <parameter two>, ...) { <block statement> };
fn name(<parameter one>, <parameter two>, ...) { <block statement> };

Example:

let add = fn(x, y) {
  return x + y;
};

add(10, 20);
fn add(x, y) {
  x + y;
};

add(10, 20);

If return does not exist, it returns the result of the last evaluated expression.

let addThree = fn(x) { x + 3 };
let callTwoTimes = fn(x, f) { f(f(x)) };

callTwoTimes(3, addThree);

Passing around functions, higher-order functions and closures will also work.

Built-in Functions

puts(<arg1>, <arg2>, ...): Null

It outputs the specified value to stdout. In the case of Playground, it is output to console.

puts("Hello");
puts("World!");

len(<arg>): Integer

For String, it returns the number of characters. If it's Array, it returns the number of elements.

len("caescript");
len([0, 1, 2]);

first(<arg>): Object

Returns the element at the beginning of Array.

first([0, 1, 2]);

last(<arg>): Object

Returns the element at the last of Array.

last([0, 1, 2]);

rest(<arg>): Array

Returns a new Array with the first element removed.

rest([0, 1, 2]);

push(<arg1>, <arg2>): Array

Returns a new Array with the element specified at the end added.

push([0, 1], 2);

License

Caescript is under MIT