#![forbid(unsafe_code)] #![warn(clippy::all)] mod args; mod compiler; mod errors; mod file_io; mod parser; mod vm; use file_io::{into_bytecode, open_bytecode, open_source, write_bytecode}; use std::env; use std::path::{Path, PathBuf}; use args::*; use compiler::{CompiledReid, Compiler}; use errors::GenericError; use parser::Parser; use vm::{ BuiltinFunctionDef, BuiltinFunctions, FunctionSignature, Value, VariableType, VirtualMachine, }; // cargo run c_run reid_src/test.reid for previous functionality fn main() { let print = BuiltinFunctionDef::new( "print", vec![VariableType::TypeString], Box::new(move |args| { if let Value::StringVal(string) = &args[0] { println!("{}", string); } }), ); let builtin_functions = BuiltinFunctions(vec![print]); let opt: MainOpt = argh::from_env(); if let Some(run_path) = opt.run_path { let compiled = open_bytecode(&run_path); match compiled { Ok(compiled) => run(compiled, builtin_functions), Err(error) => { eprintln!("{}", error); std::process::exit(1); } } } else if let Some(subcommand) = opt.subcommand { match subcommand { Subcommand::Compile(opt) => { let source = Path::new(&opt.source); let output = if let Some(output) = opt.output { PathBuf::from(output) } else { source.with_extension("reidc") }; let compiled = compile(source, builtin_functions.signatures()); match compiled { Ok(compiled) => { let bytecode = into_bytecode(&compiled); if let Err(err) = write_bytecode(bytecode, &output) { eprintln!("{}", err); std::process::exit(1); } } Err(error) => { eprintln!("{}", error); std::process::exit(1); } } } Subcommand::Run(opt) => { let path = Path::new(&opt.source); let compiled = compile(path, builtin_functions.signatures()); match compiled { Ok(compiled) => run(compiled, builtin_functions), Err(error) => { eprintln!("{}", error); std::process::exit(1); } } } } } else { let command = env::args().collect::>().join(" "); eprintln!("Please try running instead:"); eprintln!(" {} ", command); eprintln!(" {} help", command); } } fn compile(path: &Path, builtin: Vec) -> Result { let parsed = Parser::from(open_source(&path)?).parse()?; //dbg!(&parsed); let compiled = Compiler::from(parsed) .with_builtin_functions(builtin) .compile()?; //dbg!(&compiled); Ok(compiled) } fn run(reid: CompiledReid, builtin: BuiltinFunctions) { let mut vm = VirtualMachine::from(reid); vm.add_builtin_functions(builtin); if let Err(error) = vm.run() { eprintln!("Runtime panic: {:#?}", error); std::process::exit(1); } }