@raviqqe/stak 0.3.23 → 0.3.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -41,17 +41,34 @@ cargo install stak
41
41
 
42
42
  ## Examples
43
43
 
44
- ### Embedding Scheme scripts in Rust
44
+ ### Dynamic scripting in Rust
45
45
 
46
- First, prepare a Scheme script at `src/hello.scm`.
46
+ First, prepare a Scheme script named `src/fight.scm`:
47
47
 
48
48
  ```scheme
49
- (import (scheme base))
49
+ (import (scheme base) (stak rust))
50
50
 
51
- (write-string "Hello, world!\n")
51
+ (define-rust
52
+ make-person
53
+ person-throw-pie
54
+ person-wasted)
55
+
56
+ (define me (make-person 4 0.2))
57
+ (define you (make-person 2 0.6))
58
+
59
+ (person-throw-pie me you)
60
+ (person-throw-pie you me)
61
+ (person-throw-pie me you)
62
+ (person-throw-pie you me)
63
+
64
+ (when (person-wasted you)
65
+ (write-string "Congrats!"))
66
+ (when (person-wasted me)
67
+ (write-string "Oh, no!"))
52
68
  ```
53
69
 
54
- Then, add a build script at `build.rs` to build the Scheme source file into bytecodes.
70
+ Then, add a build script at `build.rs` to build the Scheme source file
71
+ into bytecodes.
55
72
 
56
73
  ```rust no_run
57
74
  use stak_build::{build_r7rs, BuildError};
@@ -61,115 +78,70 @@ fn main() -> Result<(), BuildError> {
61
78
  }
62
79
  ```
63
80
 
64
- Now, you can include the Scheme script into a program in Rust using [the `stak::include_module` macro](https://docs.rs/stak/latest/stak/macro.include_module.html).
81
+ Finally, you can embed and run the Scheme script in a Rust program.
65
82
 
66
83
  ```rust
84
+ use any_fn::{r#fn, Ref};
67
85
  use core::error::Error;
86
+ use rand::random;
68
87
  use stak::{
69
- device::StdioDevice,
70
- file::VoidFileSystem,
88
+ engine::{Engine, EngineError},
71
89
  include_module,
72
- process_context::VoidProcessContext,
73
- module::{Module, UniversalModule},
74
- r7rs::{SmallError, SmallPrimitiveSet},
75
- time::VoidClock,
76
- vm::Vm,
90
+ module::UniversalModule,
77
91
  };
78
92
 
79
93
  const HEAP_SIZE: usize = 1 << 16;
80
94
 
81
- // Include a Scheme script in the bytecode format built by the build script above.
82
- static MODULE: UniversalModule = include_module!("hello.scm");
83
-
84
- fn main() -> Result<(), Box<dyn Error>> {
85
- run(&MODULE.bytecode())?;
86
-
87
- Ok(())
88
- }
89
-
90
- fn run(bytecodes: &[u8]) -> Result<(), SmallError> {
91
- // Prepare a heap memory of a virtual machine.
92
- let mut heap = [Default::default(); HEAP_SIZE];
93
- // Create a virtual machine with its heap memory primitive procedures.
94
- let mut vm = Vm::new(
95
- &mut heap,
96
- SmallPrimitiveSet::new(
97
- // Attach standard input, output, and error of this process to a virtual machine.
98
- StdioDevice::new(),
99
- // Use void system interfaces for security because we don't need them for this example.
100
- VoidFileSystem::new(),
101
- VoidProcessContext::new(),
102
- VoidClock::new(),
103
- ),
104
- )?;
105
-
106
- // Initialize a virtual machine with bytecodes.
107
- vm.initialize(bytecodes.iter().copied())?;
108
- // Run bytecodes on a virtual machine.
109
- vm.run()
95
+ struct Person {
96
+ pies: usize,
97
+ dodge: f64,
98
+ wasted: bool,
110
99
  }
111
- ```
112
100
 
113
- ### Communication between Scheme and Rust
101
+ impl Person {
102
+ pub fn new(pies: usize, dodge: f64) -> Self {
103
+ Self {
104
+ pies,
105
+ dodge,
106
+ wasted: false,
107
+ }
108
+ }
114
109
 
115
- Currently, in-memory standard input (`stdin`) and output (`stdout`) to Scheme scripts are the only way to communicate information between Rust programs and Scheme scripts.
110
+ pub fn wasted(&self) -> bool {
111
+ self.wasted
112
+ }
116
113
 
117
- ```rust
118
- use core::{error::Error, str::{self, FromStr}};
119
- use stak::{
120
- device::ReadWriteDevice,
121
- file::VoidFileSystem,
122
- include_module,
123
- process_context::VoidProcessContext,
124
- module::{Module, UniversalModule},
125
- r7rs::{SmallError, SmallPrimitiveSet},
126
- time::VoidClock,
127
- vm::Vm,
128
- };
114
+ pub fn throw_pie(&mut self, other: &mut Person) {
115
+ if self.wasted {
116
+ return;
117
+ }
129
118
 
130
- const BUFFER_SIZE: usize = 1 << 8;
131
- const HEAP_SIZE: usize = 1 << 16;
119
+ self.pies -= 1;
132
120
 
133
- static MODULE: UniversalModule = include_module!("fibonacci.scm");
121
+ if random::<f64>() > other.dodge {
122
+ other.wasted = true;
123
+ }
124
+ }
125
+ }
134
126
 
135
127
  fn main() -> Result<(), Box<dyn Error>> {
136
- let input = 15;
137
- let mut output = vec![];
138
- let mut error = vec![];
139
-
140
- run(&MODULE.bytecode(), input.to_string().as_bytes(), &mut output, &mut error)?;
141
-
142
- // If stderr is not empty, we assume that some error has occurred.
143
- if !error.is_empty() {
144
- return Err(str::from_utf8(&error)?.into());
145
- }
128
+ static MODULE: UniversalModule = include_module!("fight.scm");
146
129
 
147
- // Decode and test the output.
148
- assert_eq!(isize::from_str(&str::from_utf8(&output)?)?, 610);
130
+ run(&MODULE)?;
149
131
 
150
132
  Ok(())
151
133
  }
152
134
 
153
- fn run(
154
- bytecodes: &[u8],
155
- input: &[u8],
156
- output: &mut Vec<u8>,
157
- error: &mut Vec<u8>,
158
- ) -> Result<(), SmallError> {
135
+ fn run(module: &'static UniversalModule) -> Result<(), EngineError> {
159
136
  let mut heap = [Default::default(); HEAP_SIZE];
160
- let mut vm = Vm::new(
161
- &mut heap,
162
- SmallPrimitiveSet::new(
163
- // Create and attach an in-memory I/O device.
164
- ReadWriteDevice::new(input, output, error),
165
- VoidFileSystem::new(),
166
- VoidProcessContext::new(),
167
- VoidClock::new(),
168
- ),
169
- )?;
170
-
171
- vm.initialize(bytecodes.iter().copied())?;
172
- vm.run()
137
+ let mut functions = [
138
+ r#fn(Person::new),
139
+ r#fn(Person::throw_pie),
140
+ r#fn::<(Ref<_>,), _>(Person::wasted),
141
+ ];
142
+ let mut engine = Engine::new(&mut heap, &mut functions)?;
143
+
144
+ engine.run(module)
173
145
  }
174
146
  ```
175
147
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@raviqqe/stak",
3
3
  "type": "module",
4
4
  "description": "Stak Scheme in WebAssembly",
5
- "version": "0.3.23",
5
+ "version": "0.3.24",
6
6
  "license": "SEE LICENSE IN ../LICENSE",
7
7
  "repository": {
8
8
  "type": "git",
package/stak_wasm_bg.wasm CHANGED
Binary file