6个版本
0.3.2 | 2024年5月11日 |
---|---|
0.3.1 | 2024年5月11日 |
0.2.0 | 2022年12月1日 |
0.1.5 | 2022年11月15日 |
#109 in 编程语言
59KB
1K SLoC
A Rust实现Egg编程语言
egg
是来自 Marijn Haverbeke 的《Eloquent Javascript》一书中的一本玩具编程语言,第12章。这本书对我的早期编程之旅至关重要。我之前一段时间转向了 Rust,出于怀旧之情,我决定用 Rust 重新编写 egg
。
✨ 特性
- 广泛 和 模块化 的标准库;
Core
、Objects
、StringTools
、Console
和Functions
- 有效的作用域链:局部变量和全局变量按预期工作。
- 用户定义函数:使用
fn
关键字在 Egg 中创建函数。 - 高阶函数:将函数作为值传递给其他函数或内置的
Operators
。 - 可扩展性:通过实现
Operator
trait 创建自己的内置函数。 - no_std:仅依赖于
alloc
。启用std
功能会添加Print
、PrintLine
、ReadLine
和Sleep
内置函数。
🏋️♂️ 示例
要开始执行脚本,我们首先需要解析它,创建一个 Scope
并组装一个它可以访问的内置函数映射
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
定义自定义的内置函数
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();
}
示例 Egg 脚本可以在
scripts
目录中找到;
来源: u/Penguin-warrior-3105
依赖项
~3.5MB
~42K SLoC