#stack #machine #script #dsl #scripting-language #programming-language

无 std scriptful

一个用于解释特定领域解释性语言的极简 no_std 堆栈机器库

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 次下载

MIT/Apache

76KB
1K SLoC

Scriptful

Build Status Crate Docs License

Scriptful 是一个极简的 no_std,无依赖堆栈机器,用于解释用特定领域解释性语言编写的脚本。

这个库受到了 Forth 编程语言和 Script(比特币中的脚本语言)的极大启发。

总体设计

整个库都是围绕以下概念构建的

  • Stack:一个有序的值序列,可以像 LIFO 一样操作。
  • Item:一个 Value(要推入堆栈的数据片段)或一个 Operator(在堆栈顶部元素上操作的动作描述符)。
  • 类型系统:一个 enum,其变体是 Stack 中允许的所有可能数据类型。
  • 运算符系统:一个函数,决定每个运算符如何修改给定的堆栈。
  • Script:一个有序的项目(值和运算符)序列,可以传递给运算符系统,以在给定的堆栈上执行操作。
  • Machine:一个方便的堆栈包装器,使操作模式多样化。
  • [编解码器]:一组用于编码和解码脚本和项目的算法,通常是将它们转换成二进制格式或从二进制格式转换出来。

使用此库就像

  1. 定义自己的操作符集,或使用op_systems模块中提供的任何操作符。
  2. 定义自己的类型系统,或使用Value类型系统,该系统包含在core::value模块中。
  3. 定义自己的操作符系统函数,或使用op_systems模块中提供的任何操作符。
  4. 用对您的操作符系统的引用实例化一个机器
  5. 组合一个脚本并在机器中运行它。

快速示例

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-APACHELICENSE-MITCOPYRIGHT以获取详细信息。

依赖关系

~180KB