zesterer/forge
{ "createdAt": "2019-02-22T12:31:33Z", "defaultBranch": "master", "description": "A lightweight, elegant scripting language with built-in Rust-FFI.", "fullName": "zesterer/forge", "homepage": "https://forge.jsbarretto.com/", "language": "Rust", "name": "forge", "pushedAt": "2019-11-01T12:37:24Z", "stargazersCount": 167, "topics": [ "compiler", "interpreter", "language", "parser" ], "updatedAt": "2025-10-22T03:19:31Z", "url": "https://github.com/zesterer/forge"}Forge is a dynamically-typed language written in Rust. It is inspired by JavaScript, Rust, Python and Rhai. In the future, you’ll be able to use Forge as a general-purpose lightweight scripting language in your applications.
You can try out Forge in your browser here!
Example
Section titled “Example”# A function to square numbersvar square = |x| { return x * x;};
var n = input "How many squares? ";
# Create a list of squaresvar squares = [];for x in 1..n + 1 { squares += square(x);}
# Iterate and print squaresfor square in squares { print square;}- Simple, familiar syntax
- Lightweight, quick to parse
- Moderately fast execution speeds
- Well-considered, ‘common-sense’ design
- Useful, informative error messages
- Easy to build into an existing codebase
- Python-like REPL prompt
Using Forge is similar in principle to using Python.
Once compiled, running the shell or executing scripts with the interpreter is trivial.
You’ll need to compile the cli/ crate to gain access to the interpreter binary.
To access the REPL shell, run:
$ forgeTo execute a script, run:
$ forge my_script.fgRoadmap
Section titled “Roadmap”- Numbers, strings and booleans
- Arithmetic operators
+,-,*,/,% - Logical operators
and,or,xor,==,!=,!,<,<=,>,>= -
if/elsestatements -
whileandforstatements - Assignment operators
=,+=,-=,*=,/=,%= - Scoped variable declaration
- Function objects
- Function calling
- Rust-to-Forge object interface
- Rust-to-Forge type coercion
- Rust callbacks Only Rust closures with no arguments or functions are currently supported
- Iterators
- Rust-to-Forge iterators
- Lists
- List splicing
- Indexing and ranges
-
cloneandmirroroperators - Lvalues vs rvalues
- Maps
- Map construction
- Map iteration
- Immutability by default
- Structures
- Enums
- Objects
- Modules as objects
- Scoped constants
- C-based FFI for non-Rust integration
- AST optimisation
- Bytecode generation
- Bytecode interpretation
- LLVM-driven recompilation
Some Syntax Examples
Section titled “Some Syntax Examples”List splicing
>> var my_list = [0, 1, 2, 3];>> my_list[1..2][1]>> my_list[1..3] = ["this", "is", "a", "list", "splice"];>> my_list[0, this, is, a, list, splice, 3]String splicing
>> "Hello, world!"[7..12]world>> var test = "An apple is what I am eating";>> test[3..8] = "pear";>> testAn pear is what I am eating>>Design
Section titled “Design”Forge has several distinct types:
- Number 64-bit, floating-point
- String unicode-compliant
- Char unicode-compliant
- Boolean
- Range
- Function
- List
- Map
- Object Currently unimplemented
- Custom Used to call to and from Rust
- Null
Things To Do
Section titled “Things To Do”- Investigate design features that would make the dynamic type system easier to optimise
Interpreter
Section titled “Interpreter”Currently, Forge is only implemented as an AST-walking interpreter. In the future, I aim to generate more efficient low-level bytecode for the language. I also aim to implement many a variety of optimisations throughout the compilation process.
Error Messages
Section titled “Error Messages”Forge aims to produce the most useful, informative and intelligence error messages it can. Errors can be emitted at compile-time or run-time. Below are a few examples.
Parser errors:
[ERROR] Parsing error at 1:45... ...while parsing if-else statement... ...while parsing print statement... 1| var x = 1; if x > 2 { print "Hello, world!" oops; } | ^^^^ Expected ';', found identifier 'oops'.Runtime errors:
[ERROR] Runtime error at 1:21... 1| var p = true; while p { print "On the next iteration, p will be null"; p = null; } | ^ Cannot determine the truthiness of value of type 'null'. Did you mean for this to be a bool?Runtime errors that produce error messages that reference code written during the previous declaration of a function object:
[ERROR] Runtime error at 1:10... 1| var say_hello = || { print "Hello, world!"; }; | ^^ 1| say_hello(1); # Wrong number of parameters | ^^^ Tried to call a function with the wrong number of parameters. Expected 0, found 1.