Crates.io | egglang |
lib.rs | egglang |
version | 0.3.3 |
source | src |
created_at | 2022-11-15 21:52:40.849839 |
updated_at | 2024-09-19 13:13:24.074518 |
description | The Egg Programming Language From Eloquent JavaScript, but in Rust |
homepage | |
repository | https://github.com/sokorototo/egglang |
max_upload_size | |
id | 715971 |
size | 63,376 |
egg
is a toy Programming Language from the book Eloquent Javascript by Marijn Haverbeke, Chapter 12. The Book was pivotal to my early Programming journey. I moved to Rust some time back and in a fit of nostalgia I decided to rewrite egg
in Rust.Extensive and Modular standard library; Core
, Objects
, StringTools
, Console
and Functions
Effective Scope Chain: Local Variables and Global Variables work as expected.
User-Defined Functions: Create functions in Egg using the fn
keyword.
Higher Order Functions: Pass functions as values to other functions or to built-in Operators
.
Extensible: Create your own builtin functions by implementing the Operator
trait.
no_std: Only depends on alloc
. Enabling the std
feature adds the Print
, PrintLine
, ReadLine
and Sleep
builtins.
parse
it, create a Scope
and assemble a map of builtin functions it can access:use egglang::prelude::*;
// Create the default Scope, with necessary constants set
let mut scope = Scope::default();
// Create a minimal set of operators
let mut operators = operators::empty();
operators::minimal(&mut operators);
// Parse a Script into a list of expressions
let script = "sum(12.5, 12.5, 25)";
let expressions = parse(script).unwrap();
// Evaluate the expression
let expression = &expressions[0]; // the call to `sum`
let result = evaluate(expression, &mut scope, &operators).unwrap();
assert_eq!(result, 50f32.into());
Operator
on a type:use egglang::prelude::*;
use std::collections::BTreeMap;
// Create the default Scope, with necessary constants set
let mut scope = Scope::default();
// Insert base operators, and add console functions; Adds println
let mut operators = operators::empty();
operators::minimal(&mut operators);
operators::console(&mut operators);
// Define a `random(...)` builtin
struct Random;
impl Operator for Random {
fn evaluate(&self, _: &[Expression], _: &mut Scope, _: &BTreeMap<&str, Box<dyn Operator>>) -> EggResult<Value> {
// totally random value ;)
Ok(0.15.into())
}
}
// Insert `random(...)` into Operators map
operators.insert("random", Box::new(Random));
// Parse a Script into a list of expressions
let script = r#"
define(iterations, random(0, 120))
repeat(iterations, println("oi oi oi oi oi"))
"#;
let expressions = parse(script).unwrap();
// Evaluate the expressions; define -> repeat -> ...
for expression in expressions {
let _ = evaluate(&expression, &mut scope, &operators).unwrap();
}
Example Egg scripts can be found in the
scripts
directory;