Changelog

0.4.2


  • Added in benchmarks.

0.4.1


  • Updated .travis.yml to initiate code coverage.

0.4.0


  • First pass refactoring towards library stablisation.
  • Added ExternCrate support. You can now use extern crate crate_name as alias;. This will work in most cases, please raise a PR if it doesn't.
  • Compilation status is redirected to the console.
  • Panics now get shown, and statements won't be added if code panics.

Installation

Back to SUMMARY

papyrus depends on proc-macro2 and syn which contains features that are only available on a nightly compiler. Further to this, the features are underneath a config flag, so compiling requires the RUSTFLAGS environment variable to include --cfg procmacro2_semver_exempt.

Linux, Mac

RUSTFLAGS="--cfg procmacro2_semver_exempt" cargo install papyrus

Windows

$env:RUSTFLAGS="--cfg procmacro2_semver_exempt"
cargo install papyrus;

REPL

Back to SUMMARY

The repl takes the commands given and evaluates them, setting a local variable such that the data can be continually referenced.

papyrus=> let a = 1;
papyrus.> a
papyrus [out0]: 1
papyrus=>

Here we define a variable let a = 1;. Papyrus knows that the end result is not an expression (given the trailing semi colon) so waits for more input (.>). We then give it a which is an expression and gets evaluated. If compilation is successful the expression is set to the variable out0 (where the number will increment with expressions) and then be printed with the Debug trait. If an expression evaluates to something that is not Debug then you will receive a compilation error. Finally the repl awaits more input =>.

The expression is using let out# = <expr>; behind the scenes.

You can also define structures and functions.

papyrus=> fn a(i: u32) -> u32 {
papyrus.> i + 1
papyrus.> }
papyrus=> a(1)
papyrus [out0]: 2
papyrus=>
papyrus=> #[derive(Debug)] struct A {
papyrus.> a: u32,
papyrus.> b: u32
papyrus.> }
papyrus=> let a = A {a: 1, b: 2};
papyrus.> a
papyrus [out0]: A { a: 1, b: 2 }
papyrus=>

Please help if the Repl cannot parse your statements, or help with documentation! https://github.com/kurtlawrence/papyrus.

Commands

Back to SUMMARY

Current list of commands.

help

Show help for commands.

.help [text]

Args is another command, and will explicitly show the help for that command.

exit

Exit repl.

.exit [text]

Exits the repl loop. Arguments are ignored.

load

Loads a *.rs or *.rscript file as inputs.

.load <filename>

See File Interaction.

Suggest or add a command on github.

Run from Command Line or Right Click Context Menu

Run interactive REPL.

papyrus run

Add right click context menu. (May need admin rights)

papyrus rc-add

Remove right click context menu. (May need admin rights)

papyrus rc-remove

Run papyrus from command line.

papyrus run path_to_src_file.rs
papyrus run path_to_script_file.rscript

Implementation Notes

  • Right click on a .rs or .rscript file and choose Run with Papyrus to compile and run code!
  • Papyrus will take the contents of the source code and construct a directory to be used with cargo. For now the directory is created under a .papyrus directory in the users home directory.
  • The compiled binary will be executed with the current directory the one that houses the file. So env::current_dir() will return the directory of the .rs or .rscript file.

Example - .rs

File hello.rs.

extern crate some_crate;

fn main() {
  println!("Hello, world!");
}

Use papyrus to execute code.

papyrus run hello.rs

The src/main.rs will be populated with the same contents as hello.rs. A Cargo.toml file will be created, where some_crate will be added as a dependency some-crate = "*".

Example - .rscript

File hello.rscript.

extern crate some_crate;

println!("Hello, world!");

Use papyrus to execute code.

papyrus run hello.rscript

The src/main.rs will be populated with a main function encapsulating the code, and crate references placed above it. A similar Cargo.toml will be created as before.

File Interaction

papyrus comes with the command load which lets you load a file as source code. papyrus accepts both *.rs and *.rscript files, and handles the code slightly differently when it loads it into the Repl.

  • *.rs files are treated as source files where code is defined with functions and structs, etc.
  • *.rscript files are treated like expressions, where each line is passed through to the main function.

Load is used with the syntax =>.load <filename>.

Examples

.rs File

Let us define a source file pwr.rs.


# #![allow(unused_variables)]
#fn main() {
fn pwr(base: u32, exponent: u32) -> u32 {
  (0..=exponent).into_iter().fold(1, |acc, x| acc * base)
}
#}

In the papyrus repl:

papyrus=> .load pwr.rs
papyrus=> pwr(2,3)
papyrus [out0]: 8
papyrus=>

.rscript File

Let us define a source file count_files.rscript.


# #![allow(unused_variables)]
#fn main() {
let dir = std::env::current_dir().unwrap();
let mut count = 0;
for entry in dir.read_dir().unwrap() {
  if entry.is_ok() {
    count += 1;
  }
}
count
#}

In the papyrus repl:

papyrus=> .load count_files.rscript
papyrus [out0]: 20
papyrus=>

The number of files will vary.

Papyrus Vision

A REPL that contains functionality like Jupyter.