Lagoon is a dynamic, weakly-typed and minimal scripting language. 🏞

Overview

🏞 The Lagoon Language

Lagoon is a dynamic, weakly-typed and minimal scripting language. It draws inspiration from a handful of modern languages including JavaScript, Rust and PHP.

If you want to learn more about the language itself, you can read the SPECIFICATION or take a look at the collection of examples in this repository.

Example

-- This is a recursive fibonacci function. It accepts a number `n`.
fn fib(n) {
    if n < 2 {
        return n
    }

    return fib(n - 1) + fib(n - 2)
}

println(fib(10)) -- `println` is a function in the standard library.

Theory

Lagoon parses a string of source code into a token stream and abstract syntax tree (AST).

The generated AST is then passed to an interpreter. It uses a tree-walk approach to recursively iterate through each node in the tree.

A tree-walk interpreter is one of the slowest methods of execution, but it's also one of the simplest. In the future Lagoon will likely move to a bytecode interpreter but whilst the language itself is still in early development, a tree-walk interpreter will continue to be used.

At the highest level, all operations in Lagoon are parsed as statements. A statement can contain one or more expressions. Those expressions are generally used to manipulate the execution environment and provide information to your script.

Development Checklist

Lagoon is nowhere near being feature complete or syntax complete. Below is a small checklist of things that we still need to add and design before marking it as "stable".

  • &&, || - Boolean infix operators
  • >, >=, <, <= - Mathematical comparison operators
  • ** - Exponent / power operator
  • &, |, ^, ~, <<, >> - Bitwise operators
  • Lists
  • for..in statements
  • in, not in operators
  • Scalar objects (methods on scalar types)
  • Module system
  • Standard Library
  • Nicer error reporting
  • Transpile to JavaScript
  • Nicer command-line interface
  • Constant declarations (const)
  • Migrate parser to on-demand token stream
  • Line/column numbers in errors
  • Build a virtual machine to replace the interpreter

Contributing

If you would like to contribute to Lagoon, please feel free to fork this repository and open a pull request. All contributions are highly appreciated, no matter your Rust knowledge.

Credit

Comments
  • feature: bytecode VM

    feature: bytecode VM

    This is the start of a bytecode virtual machine for Lagoon.

    I'm not well versed in bytecode machines, so I've winged it and built some sort of stack machine. Whether it's any good, I don't know.

    Using this pull request to track the progress made on the machine, as it'll take some time to figure things out.

    TODO:

    • [ ] Implement all scalar values
    • [ ] Implement support for native functions
    • [ ] Implement support for user defined functions
    • [ ] Implement support for if/else statements
    • [ ] Implement return statements
    • [ ] Add support for while statements
    • [ ] Implement support for lists
    • [ ] Implement support for for..in statements
    • [ ] Implement support for assignments
    • [ ] Implement support for infix operations
    • [ ] Implement support for prefix operations
    • [ ] Implement support for structs
    • [ ] Implement support for struct methods
    • [ ] Implement support for struct instantiation
    • [ ] Implement support for constants
    • [ ] Implement support for native methods / objects
    • [ ] Implement support closures
    • [ ] Implement support for require() calls
    opened by ryangjchandler 0
  • Feature/require

    Feature/require

    Adds a native require() function that accepts a relative path.

    The relative path should be relative to the current file.

    It allows you to execute another file in the current context, meaning all functions, variables and structs are then available inside of the current context.

    Person.lag

    struct Person {
        name
    }
    

    main.lag

    require("./Person")
    
    const Ryan = Person { name: "Ryan" }
    

    This is the simplest form of modules really. I'll likely try to implement an explicit export / import syntax in the future but this should help separate things for now.

    opened by ryangjchandler 0
  • feature: JS transpilation

    feature: JS transpilation

    This pull request adds a new JS transpiler to Lagoon.

    You can run it through lagoon js ./path/to/source.lag ./path/to/output.js.

    It's very much a work-in-progress but functional enough to merge.

    Here's a list of everything that is currently supported:

    • [x] Strings, numbers, booleans, null
    • [x] Struct definitions (become JS classes with explicit field declaration and constructor)
    • [x] All mathematical operators, as well as polyfilled in/not in support.
    • [x] If/else statements
    • [x] for..in statements
    • [x] Closures
    • [x] Index expressions
    • [x] Assignments
    • [x] Struct methods (transpile to prototype modifications...?)
    • [x] List object methods
    • [x] String object methods
    • [x] Numeric object methods
    opened by ryangjchandler 0
  • chore: migrate to workspace folders

    chore: migrate to workspace folders

    This pull request migrates all of the old files into a workspace structure.

    1. Move to workspace / crate folders.
    2. Use more intelligent exports to reduce namespace scope.
    opened by ryangjchandler 0
  • feature: better error reporting

    feature: better error reporting

    This isn't everything that I want to do but it's definitely a good start.

    Will output ParseError and InterpreterResult errors in bold red text to stderr, instead of the panic that it was doing before.

    opened by ryangjchandler 0
  • feature: `in` / `not in`

    feature: `in` / `not in`

    Adds new in and not in infix operators.

    Can currently be used to check if a list contains, or doesn't contain, a scalar value (anything but a struct or list). Can also be used to check if a string contains, or doesn't contain, another string.

    opened by ryangjchandler 0
  • feature: for..in

    feature: for..in

    Adds support for for..in statements.

    At the moment, the only iterable value is the new list value. (#1)

    In the future, I'll likely add support for iterating over strings too. Or perhaps a .chars() method on the string type that returns a list is smarter.

    let names = ["Ryan"]
    
    for name in names {
    
    }
    
    for (i, name) in names {
    
    }
    
    enhancement 
    opened by ryangjchandler 0
  • feature: add support for lists

    feature: add support for lists

    This pull request adds support for lists (arrays).

    A list can be created using [] tokens:

    let items = ["Ryan", "John", "Jane"]
    

    You can retrieve an item from the list at a particular index using the postfix index notation:

    let ryan = items[0]
    

    Lists are not limited to one type of data, you can use any type of data.

    If you wish to assign a new value to a particular index, you can use the postfix index notation on the left hand side of an assignment expression:

    items[1] = "Jimmy"
    

    If you wish to append an item to the list, use the postfix index notation with an empty index:

    items[] = "Nora"
    
    enhancement 
    opened by ryangjchandler 0
Owner
Ryan Chandler
Ryan Chandler
A simple programming language made for scripting inspired on rust and javascript.

FnXY Programming Language Quick move: CONTRIBUTING | LICENSE What? FnXY is a simple programming language made for scripting inspired on rust and javas

null 2 Nov 27, 2021
A dynamically typed, interpreted, stack-based language.

Stacc A dynamically typed, interpreted, stack-based language. How does it work? Each call-frame/scope has its own variables and stack, so you can get/

null 8 Nov 12, 2021
A shell scripting language

Slash The system level language for getting the job done. Detailed documentation is available on the Slash site Motivation Bash is an awesome shell, b

null 27 Jun 17, 2022
A small scripting language running on V8.

Rook A small scripting language running on V8. After spending a few hours playing with V8, it seems like the only way to make this work is by transpil

Ryan Chandler 2 Dec 16, 2022
A forth-inspired, bytecode-compiled scripting language for Anachro Powerbus

Anachro Forth (core) Anachro Forth is a forth-inspired, bytecode-compiled scripting language for Anachro Powerbus platform. Use Case The intended use

null 14 May 27, 2022
A small embeddable scripting language

There is currently a tree-walking interpreter called bird in progress, but the plan is to have a bytecode vm in the end language_name is a small embed

nils 15 Dec 10, 2022
Sol is a lightweight language primarily designed for scripting environments

☀️ Sol A dynamically-typed (for now) and procedural programming language. About Sol is a lightweight language primarily designed for scripting environ

Joshua 3 Jul 25, 2022
whydia is a small embeddable scripting language

whydia is a small embeddable scripting language It's inspired by Javascript, Lox, Lua, Python, Rust and more Reference Overview Declaring variables us

Adi Yenuubarii 4 Apr 15, 2022
plugy empowers you to construct agnostic dynamic plugin systems using Rust and WebAssembly.

plugy plugy is a plugin system designed to enable the seamless integration of Rust-based plugins into your application. It provides a runtime environm

Geoffrey Mureithi 22 Aug 12, 2023
CosmWasm Contract for Dynamic CW721 NFTs on Terra

CosmWasm Starter Pack This is a template to build smart contracts in Rust to run inside a Cosmos SDK module on all chains that enable it.

null 9 Sep 12, 2022
Build a python wheel from a dynamic library

build_wheel Small utility to create a Python wheel given a pre-built dynamic library (.so, .dylib, .dll). If you are just trying to produce a wheel fr

Tangram 1 Dec 2, 2021
A parser, compiler, and virtual machine evaluator for a minimal subset of Lua; written from scratch in Rust.

lust: Lua in Rust This project implements a parser, compiler, and virtual machine evaluator for a minimal subset of Lua. It is written from scratch in

Phil Eaton 146 Dec 16, 2022
A minimal library for building compiled Node.js add-ons in Rust via Node-API

A minimal library for building compiled Node.js add-ons in Rust via Node-API

Node-API (N-API) for Rust 3.1k Dec 29, 2022
Minimal framework to inject the .NET Runtime into a process in Rust

錆の核 sabinokaku Minimal framework to inject the .NET Runtime into a process. Supports Windows and Linux. macOS support is complicated due to SIP, and w

Snowflake Emulator Frontend 8 Mar 6, 2022
Ethereal - a general-purpose programming language that is designed to be fast and simple

Ethereal is a general-purpose programming language that is designed to be fast and simple. Heavly inspired by Monkey and written in Rust

Synthesized Infinity 21 Nov 25, 2022
A script language like Python or Lua written in Rust, with exactly the same syntax as Go's.

A script language like Python or Lua written in Rust, with exactly the same syntax as Go's.

null 1.4k Jan 1, 2023
Tyrade: a pure functional language for type-level programming in Rust

A pure functional language for type-level programming in Rust

Will Crichton 286 Jan 1, 2023
An OOP programming language I am making by following Crafting Interpreters.

horba An OOP programming language I am making by following Crafting Interpreters. https://craftinginterpreters.com/ I intend it to have a somewhat C-s

Thomas 3 Dec 5, 2021
Yet Another Programming Language

Yet Another Programming Language

null 4 Sep 15, 2021