## Expand description

*Scriptful* is a minimalist `no_std`

, zero dependency stack machine for interpreting scripts written with domain
specific interpreted languages.

This library is heavily inspired by the Forth programming language and Script (the scripting language in Bitcoin).

## General design

The whole library is built around these concepts:

**Stack**: an ordered sequence of values that can be operated in a LIFO-alike way.**Item**: either a`Value`

(a piece of data to be pushed into the stack) or an`Operator`

(the descriptor for an action that operates on the topmost items in the stack).**Type system**: an`enum`

whose variants are all the possible data types allowed in a`Stack`

.**Operator system**: a function that decides how each operator will mutate a given stack.**Script**: an ordered sequence of items (values and operators) that can be passed to an operator system for operating on a given stack.**Machine**: a convenient wrapper around a stack that enables multiple modes of operation.**Codec**: a set of methods for encoding and decoding scripts and items, normally into and from binary formats.

Using this library is as easy as:

- Defining your own set of operators, or using any of the ones that come bundled in the
`op_systems`

module. - Defining your own type system, or using the
`Value`

type system that comes bundled in the`core::value`

module. - Defining your own operator system function, or using any of the ones that come bundled in the
`op_systems`

module. - Instantiating a machine with a reference to your operator system.
- Composing a script and running it in the machine.

## Quick example

```
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(&Vec::from([
Item::Value(Integer(1)),
Item::Value(Integer(2)),
Item::Operator(MyOperator::Add),
]));
// The result should unsurprisingly be 3.
assert_eq!(result, Some(&Integer(3)));
```

Run## Known limitations

*Beware of unwraps!*This is a proof-of-concept and it is modelled to panic upon errors. Making the library safe for production usage is in the near horizon though.

## License

Scriptful is distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE and LICENSE-MIT, and COPYRIGHT for details.

## Modules

Codecs are different ways to encode and decode scripts, normally into and from compact binary formats.

The core of this library.

Some ready-to-use operator systems that may be useful for *someone*, *somewhere*, *somewhen*.

Re-exports the most frequently used parts of this library so that they can be used more conveniently.