Looks like it's taking quite long...

◦ Click anywhere to close

Ari Language

29 January 2021

3 min read

Table of Contents

1. What is it?

2. Scanning

3. Parsing

4. Variables and Closures

5. Array Operations

6. Built-in Functions

7. Error Reporting

8. Conclusions

What is it?

Using Rust, I attempted to create an interpreted language called Ari. Given that it's my first attempt, I resorted to a C-like grammar due to its simplicity and ubiquity.

Scanning

Scanning is the process of transforming the input program into a sequential array of tokens. Tokens are the basic blocks of the program akin to physical atoms. The block below illustrates the conversion:

+ ➡️ TokenType::Plus
; ➡️ TokenType::Semicolon
= ➡️ TokenType::Equal
== ➡️ TokenType::EqualEqual
123 ➡️ TokenType::Number
"123" ➡️ TokenType::String
someVariable ➡️ TokenType::Identifier
  • The scanner's implementation can be found at scanner.rs
  • All the tokens are defined at token.rs

Parsing

Parsing is the process of creating an abstract syntax tree (AST) from the array of tokens. Ari's AST comprises of three basic blocks:


        For simplicity, Ari uses a manually-implemented recursive descent parser. Although easier than other parser types, it is vulnerable to stack overflow if the input program's recursion is too deep. All statements and expressions are allocated on the heap memory using Rust's standard Box.

  • The AST's implementation can be found at ast.rs
  • The parser's implementation can be found at parser.rs

Variables and Closures

In order to keep track of initialized variables, Ari uses Rust's standard Hashmap to map the variables. Moreover, Ari also implements block scoping which enables variable shadowing described in the docs.


        Ari's functions are first class citizens, meaning that they can be stored in variables and passed around as arguments to other functions. Similar to Javascript, Ari implements the concept of closures where functions keep a copy of their outer scope. The docs provide some examples.

Array Operations

Ari creates and manipulates arrays using Rust's standard Vec. To parallelize array operations, Rayon is used. Array functions like map, filter, reduce are also provided.

Built-in Functions

No language would be appealing or useful if everything must be implemented from scratch. Ari provides a small set of built-in functions that I think are helpful for numbers, strings, arrays, random numbers, file operations and web stuff.

  • The standard functions are implemented at function.rs

Error Reporting

Inspired by Rust, I incorporated terminal colors and helpful error messages which highlight what and where the errors are.

Undefined variable

Undefined variable

Invalid logarithm

Invalid logarithm

Missing semicolon

Missing semicolon

Conclusions

This project was a good exposure to the intricacies of language design and also an exciting opportunity to put Rust into practice.