Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedding In A Rust Application #34

Open
Pebaz opened this issue Mar 30, 2021 · 1 comment
Open

Embedding In A Rust Application #34

Pebaz opened this issue Mar 30, 2021 · 1 comment
Labels
documentation Needed documentation or quide help-wanted This is an great first issue for first time contributers question Question asking for help or clarification
Milestone

Comments

@Pebaz
Copy link

Pebaz commented Mar 30, 2021

I noticed that Passerine is listed in this list for scripting languages for Rust:

https://arewegameyet.rs/ecosystem/scripting/

Can documentation be made that shows how to run Passerine code within a Rust application for scripting purposes?

@slightknack slightknack added question Question asking for help or clarification documentation Needed documentation or quide labels Mar 31, 2021
@slightknack
Copy link
Member

slightknack commented Mar 31, 2021

Yes! This is something that is much needed, and isn't up-to-par yet. Ideally, Passerine should expose functions at the top level that run scripts and produce results. This isn't the case yet:

Right now the bindings are pretty low level; to run some Passerine, you'd have to do something along the lines of:

let source = Source::source(/* passerine code to run */)
let compiled = lex(source)
    .and_then(parse)
    .and_then(desugar)
    .and_then(gen)

if let Some(bytecode) = compiled {
    let mut vm = VM::init(Closure::wrap(lambda));
    let ran = vm.run();
    if let Err(trace) = ran {
        eprintln!("{}", trace);
    }
}  else if let Err(syntax) = compiled {
    eprintln!("{}", syntax);
}

To bind Rust functions to passerine, you have to use the gen_with_ffi function; by default, the core FFI is included.

This above scheme is not ideal for a number of reasons:

  1. When compiling, you have to list each compilation step. A function like compile would go a long way. The good news is that this isn't too hard.
  2. When running, Passerine doesn't return a value; to get useful values out of Passerine, you'd have to inspect the stack. This is very bad. The module system should help fix this; it'll make the value returned by Passerine be a record, so that variables can be inspected. The module system will also allow Passerine to be run in a repl-like environment, where the state in the VM is preserved between runs. See Records and Modules #27 for more.
  3. When passing data across the FFI boundary, you have to use Passerine Data. Arbitrary Rust data can't be passed. In the future, it should be possible to pass arbitrary Rust data, or use something like #[derive(passerine::ExternalData)] which automatically 'serializes' and 'de-serializes' data for you.

Here's what needs to happen, in order of urgency, to meet these goals:

  • In lib.rs, export common functionality - this includes the lex, parse, gen functions, etc. as well as core datatypes like Data and VM.
  • Also in lib.rs, export common helper functions - one example could be the compile function mentioned in (1); others might be compile_with_ffi or run.
  • Implement Records and Modules #27, and provide functionality to easily pull values out of modules.
  • Implement macros that derive serialization for Rust structs to Passerine data to make the FFI more convenient.
  • Write an official tutorial/guide that shows how we can use Passerine and Rust to build a basic application.

The first two items in this list could be done today (I might try to knock them out, actually). The second ones will take a bit more time. If you'd like to get a feel for how the project is structured, I think putting in either one of these as a PR would be fairly straightforward - if anyone intends to do this, let me know, and I'll answer any questions as needed.

What are your thoughts?

@slightknack slightknack added the help-wanted This is an great first issue for first time contributers label Mar 31, 2021
@slightknack slightknack added this to the 0.10.0 milestone Jul 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Needed documentation or quide help-wanted This is an great first issue for first time contributers question Question asking for help or clarification
Projects
None yet
Development

No branches or pull requests

2 participants