mrubyedge_cli/subcommands/
run.rs1use clap::Args;
2use std::{fs::File, io::Read, path::PathBuf};
3
4use mruby_compiler2_sys as mrbc;
5use mrubyedge;
6
7#[derive(Args)]
8pub struct RunArgs {
9 #[arg(long)]
11 pub dump_insns: bool,
12
13 #[arg(short = 'e', long = "eval", value_name = "CODE")]
15 pub eval: Option<String>,
16
17 pub file: Option<PathBuf>,
19}
20
21pub fn execute(args: RunArgs) -> Result<(), Box<dyn std::error::Error>> {
22 let buf = if let Some(code) = &args.eval {
23 code.clone().into_bytes()
25 } else if let Some(file) = args.file {
26 let mut buf = Vec::new();
28 File::open(&file)?.read_to_end(&mut buf)?;
29 buf
30 } else {
31 return Err("Either -e option or file path must be provided".into());
32 };
33
34 let is_mrb_direct =
35 args.eval.is_none() && buf.len() >= 4 && buf[0..4] == [b'R', b'I', b'T', b'E'][..];
36 unsafe {
37 let mrb_bin = if is_mrb_direct {
38 buf.to_vec()
39 } else {
40 let buf = String::from_utf8(buf)?;
41 let mut ctx = mrbc::MRubyCompiler2Context::new();
42 if args.dump_insns {
43 ctx.dump_bytecode(&buf)?;
44 }
45 ctx.compile(&buf)?
46 };
47 let mut rite = mrubyedge::rite::load(&mrb_bin)?;
48 let mut vm = mrubyedge::yamrb::vm::VM::open(&mut rite);
49 vm.run()?;
50 }
51
52 Ok(())
53}