8 个不稳定版本 (3 个破坏性版本)
0.4.0 | 2022年8月9日 |
---|---|
0.3.1 | 2022年4月13日 |
0.2.1 | 2022年4月9日 |
0.2.0 | 2020年1月28日 |
0.1.2 | 2020年1月25日 |
#63 在 模拟器
每月 23 次下载
76KB
1K SLoC
Scriptful 是一个极简的 no_std
,无依赖堆栈机器,用于解释用特定领域解释性语言编写的脚本。
这个库受到了 Forth 编程语言和 Script(比特币中的脚本语言)的极大启发。
总体设计
整个库都是围绕以下概念构建的
- Stack:一个有序的值序列,可以像 LIFO 一样操作。
- Item:一个
Value
(要推入堆栈的数据片段)或一个Operator
(在堆栈顶部元素上操作的动作描述符)。 - 类型系统:一个
enum
,其变体是Stack
中允许的所有可能数据类型。 - 运算符系统:一个函数,决定每个运算符如何修改给定的堆栈。
- Script:一个有序的项目(值和运算符)序列,可以传递给运算符系统,以在给定的堆栈上执行操作。
- Machine:一个方便的堆栈包装器,使操作模式多样化。
- [编解码器]:一组用于编码和解码脚本和项目的算法,通常是将它们转换成二进制格式或从二进制格式转换出来。
使用此库就像
- 定义自己的操作符集,或使用
op_systems
模块中提供的任何操作符。 - 定义自己的类型系统,或使用
Value
类型系统,该系统包含在core::value
模块中。 - 定义自己的操作符系统函数,或使用
op_systems
模块中提供的任何操作符。 - 用对您的操作符系统的引用实例化一个机器。
- 组合一个脚本并在机器中运行它。
快速示例
use scriptful::prelude::*;
use scriptful::core::value::Value::*;
// You can define your own operators.
#[derive(Debug, PartialEq, Eq)]
enum MyOperator {
Add,
Equal,
Sub,
}
// An operator system decides what to do with the stack when each operator is applied on it.
fn my_operator_system(stack: &mut Stack, operator: &MyOperator) {
match operator {
MyOperator::Add => {
let a = stack.pop();
let b = stack.pop();
stack.push(a + b);
}
MyOperator::Equal => {
let a = stack.pop();
let b = stack.pop();
stack.push(Boolean(a == b));
}
MyOperator::Sub => {
let a = stack.pop();
let b = stack.pop();
stack.push(a - b);
}
}
}
// Instantiate the machine with a reference to your operator system.
let mut machine = Machine::new(&my_operator_system);
// Run a script that simply adds 1 and 2.
let result = machine.run_script(&[
Item::Value(Integer(1)),
Item::Value(Integer(2)),
Item::Operator(MyOperator::Add),
]);
// The result should unsurprisingly be 3.
assert_eq!(result, Some(&Integer(3)));
已知限制
- 注意解包操作! 这是一个概念验证示例,它模拟在错误发生时引发恐慌。尽管如此,使库适用于生产用途的工作正在接近完成。
许可证
Scriptful是在MIT许可证和Apache许可证(版本2.0)的条款下分发的。
请参阅LICENSE-APACHE、LICENSE-MIT和COPYRIGHT以获取详细信息。
依赖关系
~180KB