Reid/src/main.rs

130 lines
3.9 KiB
Rust
Raw Normal View History

2020-06-23 20:08:54 +02:00
#![forbid(unsafe_code)]
2020-06-25 00:13:35 +02:00
#![warn(clippy::all)]
2020-06-23 20:08:54 +02:00
2020-06-25 01:00:53 +02:00
mod args;
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
2020-06-22 20:49:21 +02:00
mod compiler;
2020-06-21 00:21:24 +02:00
mod errors;
mod file_io;
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
2020-06-21 00:21:24 +02:00
mod parser;
mod vm;
2020-06-21 00:21:24 +02:00
2020-07-02 22:13:10 +02:00
use file_io::open_bytecode;
#[cfg(feature = "compiler")]
use file_io::{into_bytecode, open_source, write_bytecode};
#[cfg(feature = "compiler")]
use std::env;
2020-07-02 22:13:10 +02:00
use std::path::Path;
#[cfg(feature = "compiler")]
use std::path::PathBuf;
2020-06-21 00:21:24 +02:00
2020-06-25 01:00:53 +02:00
use args::*;
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
use compiler::Compiler;
#[cfg(feature = "compiler")]
use errors::GenericError;
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
use parser::Parser;
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
use vm::FunctionSignature;
use vm::{BuiltinFunctionDef, BuiltinFunctions, CompiledReid, Value, VariableType, VirtualMachine};
2020-06-18 17:06:57 +02:00
fn main() {
2020-06-24 20:58:16 +02:00
let print = BuiltinFunctionDef::new(
"print",
vec![VariableType::TypeString],
Box::new(move |args| {
2020-06-24 23:39:18 +02:00
if let Value::StringVal(string) = &args[0] {
println!("{}", string);
}
2020-06-24 20:58:16 +02:00
}),
);
let builtin_functions = BuiltinFunctions(vec![print]);
2020-06-25 01:00:53 +02:00
let opt: MainOpt = argh::from_env();
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
if let Some(run_path) = opt.run_path {
2020-07-02 22:13:10 +02:00
run_bytecode(&run_path, builtin_functions);
} 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);
}
}
}
2020-06-25 01:00:53 +02:00
}
} else {
let command = env::args().collect::<Vec<String>>().join(" ");
eprintln!("Please try running instead:");
eprintln!(" {} <path>", command);
eprintln!(" {} help", command);
2020-06-25 01:00:53 +02:00
}
2020-07-02 22:13:10 +02:00
#[cfg(not(feature = "compiler"))]
run_bytecode(&opt.run_path, builtin_functions);
}
fn run_bytecode(run_path: &Path, builtin_functions: BuiltinFunctions) {
let compiled = open_bytecode(run_path);
2020-07-05 21:56:11 +02:00
dbg!(&compiled);
2020-07-02 22:13:10 +02:00
match compiled {
Ok(compiled) => run(compiled, builtin_functions),
Err(error) => {
eprintln!("{}", error);
std::process::exit(1);
}
}
2020-06-25 01:00:53 +02:00
}
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
fn compile(path: &Path, builtin: Vec<FunctionSignature>) -> Result<CompiledReid, GenericError> {
let parsed = Parser::from(open_source(&path)?).parse()?;
//dbg!(&parsed);
2020-06-25 01:00:53 +02:00
let compiled = Compiler::from(parsed)
2020-06-25 01:00:53 +02:00
.with_builtin_functions(builtin)
.compile()?;
//dbg!(&compiled);
Ok(compiled)
2020-06-25 01:00:53 +02:00
}
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);
2020-06-21 00:37:56 +02:00
}
2020-06-18 17:06:57 +02:00
}