Giter Club home page Giter Club logo

slang-v2's Introduction

slang

Slang is a treewalk scripting language interpreter from loosely following https://craftinginterpreters.com/. I've also used https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html to write the parser.

Since this is a treewalk interpreter and I'm planning on writing a bytecode interpreter version, I put absolutely no effort into optimization and it's quite slow. The project euler tests are translated from https://github.com/asterane/project-euler since Slang is basically C with less features. Throughout the Readme, Rust syntax highlighting is used because it's close enough.

In the REPL, add '~' at the end of the input. This is the easiest way I could think of to make it work with multiline.

There's also a proof of concept bytecode compiler on the bytecode branch which compiles instructions for TinyVM. It supports only integers, if statements, and loops, but is many times faster than the treewalk version. I plan to design and write a more complete bytecode interpreter sometime soon.

Examples

Project Euler 01

Prints the sum of all numbers under 1000 that are divisible by 3 or 5.

let sum = 0

for (let i = 0; i < 1000; i += 1) {
    if ((i % 3 == 0) || (i % 5 == 0)) {
        print(i)
        sum += i
    }
}

sum

Recursive Fibonacci

fn fib(n) {
    if (n < 2) {
        1
    } else {
        fib(n - 1) + fib(n - 2)
    }
}

fib(15)

Memoized Fibonacci

let arr = [1, 1]

let n = 40

for (let i = 2; i < n; i += 1) {
    push(arr, arr[i - 1] + arr[i - 2])
}

for (let i = 0; i < len(arr); i += 1) {
     print(arr[i])
}

Features

Variables

  • Ints
  • Floats
  • Strings
  • Arrays
  • Booleans

To declare a variable, use let. To change the variable with typechecking, just assign it with =.

let x = 5
let y = "abc"

x = "abc" # errors
let y = 5 # doesn't error

Arithmetic operations are implemented between Floats and Integers.

Loops

While loops and C-style for loops are implemented.

let x = 0
while (x < 10) {
    print(x)
    x += 1
}

for (let i = 0; i < 10; i += 1) {
    print(x)
}

for loops are limited to one statement or expression per section.

Scopes

Any section delimited by curly braces is a scope. Variables in outer scopes are accessible and variables go out of scope at the end of the block they are declared in.

let x = 5

{
    print(x) # 5
    let x = "abc"
    print(x) # "abc"
}

print(x) # 5

Arrays

Arrays are expandible, heterogenous, and nestable. They can be indexed by square brackets. They also use two built in functions, push, and len.

let a = [1, 2, 3, "abc"]
print(a[0]) # 1
print(a[0 + 1]) # 2 
print(a[2 - a[0] + 1]) # 3

push(a, 5)
push(a, a)
print(a) # debug output, not very pretty
print(a[len(a) - 1][0]) # 1

Functions

First class functions are declared using the fn keyword.

fn add(a, b) {
    a + b
}

fn run(f, a, b) {
    f(a, b)
}

fn square(a) {
    a * a
}

fn call_n_times(n, f, x) {
    if (n == 1) {
        f(x)
    } else {
        call_n_times(n - 1, f, f(x))
    }
}

print(run(add, 15, 20)) # 35
print(call_n_times(4, square, 2)) # 65536

Examples

There are more examples in the test_files directory. The most impressive one is pong_stdg.slang which is Pong with two AIs. It needs to be run with https://github.com/calebwin/stdg/releases/tag/v0.2.0.

slang-v2's People

Contributors

mkhan45 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

hmrg-grmh

slang-v2's Issues

REPL variable assignment work

Every line is its own block which creates its own scope; the easiest way to fix is probably to make Block::run_in_current_scope() or similar

Known problems

A list of major-ish problems with Slang which I'm not planning to fix at the moment:

  • The error reporting really sucks
  • Functions have to return something (this can probably be fixed by adding a null/None type)
  • Functions can't mutate variables - all variables are passed by value right now
  • Order of operations is wrong - this would be pretty easy to fix
  • Converting between Int and Float is weird

Fixing these woluld probably make Slang much less of a pain to write

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.