mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-14 17:35:03 +01:00
117 lines
2.8 KiB
Rust
117 lines
2.8 KiB
Rust
#![deny(clippy::disallowed_types)]
|
|
|
|
mod ast;
|
|
mod bytecode;
|
|
mod compile;
|
|
mod errors;
|
|
mod gc;
|
|
mod lex;
|
|
mod parse;
|
|
mod util;
|
|
mod vm;
|
|
|
|
use std::io::Write;
|
|
|
|
pub use bumpalo::Bump;
|
|
pub use lex::*;
|
|
pub use parse::*;
|
|
|
|
use crate::{ast::Program, gc::RtAlloc};
|
|
|
|
#[cfg(not(feature = "fxhash"))]
|
|
#[allow(clippy::disallowed_types)]
|
|
type HashMap<K, V> = std::collections::HashMap<K, V>;
|
|
|
|
#[cfg(feature = "fxhash")]
|
|
type HashMap<K, V> = rustc_hash::FxHashMap<K, V>;
|
|
|
|
#[cfg(not(feature = "fxhash"))]
|
|
#[allow(clippy::disallowed_types)]
|
|
type HashSet<T> = std::collections::HashSet<T>;
|
|
|
|
#[cfg(feature = "fxhash")]
|
|
type HashSet<T> = rustc_hash::FxHashSet<T>;
|
|
|
|
pub struct Config<'io> {
|
|
pub debug: bool,
|
|
pub step: bool,
|
|
pub stdout: &'io mut dyn Write,
|
|
}
|
|
|
|
pub fn run_program(program: &str, cfg: &mut Config) {
|
|
if cfg.debug {
|
|
eprintln!("Config: debug: {}, step: {}", cfg.debug, cfg.step);
|
|
}
|
|
|
|
let ast_alloc = Bump::new();
|
|
|
|
// SAFETY: I will try to 🥺
|
|
let mut runtime = unsafe { RtAlloc::new() };
|
|
|
|
let lexer = lex::Lexer::new(program, &mut runtime);
|
|
let ast = parse::parse(lexer, &ast_alloc);
|
|
|
|
match ast {
|
|
Ok(ast) => process_ast(program, &ast, runtime, cfg),
|
|
Err(err) => errors::display_error(program, err),
|
|
}
|
|
}
|
|
|
|
fn process_ast(program: &str, ast: &Program, mut runtime: RtAlloc, cfg: &mut Config<'_>) {
|
|
if cfg.debug {
|
|
util::dbg("AST:\n", ast);
|
|
}
|
|
|
|
let bytecode_alloc = Bump::new();
|
|
|
|
let bytecode = compile::compile(ast, &bytecode_alloc, &mut runtime);
|
|
|
|
match bytecode {
|
|
Ok(code) => {
|
|
if cfg.debug {
|
|
util::dbg("Bytecode:\n", code);
|
|
}
|
|
|
|
let result = vm::execute(code, runtime, cfg);
|
|
if let Err(msg) = result {
|
|
eprintln!("error: {msg}");
|
|
}
|
|
}
|
|
Err(err) => errors::display_error(program, err),
|
|
}
|
|
}
|
|
|
|
// have the code here and not in the fuzzer, it's easier to find when it breaks like this
|
|
|
|
#[doc(hidden)]
|
|
pub fn _fuzz_compile(program: &str) {
|
|
// SAFETY: Just this scope
|
|
let mut runtime = unsafe { RtAlloc::new() };
|
|
let ast_alloc = Bump::new();
|
|
|
|
let lexer = lex::Lexer::new(program, &mut runtime);
|
|
let ast = parse::parse(lexer, &ast_alloc);
|
|
|
|
if let Ok(ast) = ast {
|
|
let bytecode_alloc = Bump::new();
|
|
let _bytecode = compile::compile(&ast, &bytecode_alloc, &mut runtime);
|
|
}
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
pub fn _fuzz_parse(program: &str) {
|
|
// SAFETY: Just this scope
|
|
let mut runtime = unsafe { RtAlloc::new() };
|
|
let ast_alloc = Bump::new();
|
|
|
|
let lexer = lex::Lexer::new(program, &mut runtime);
|
|
let _ast = parse::parse(lexer, &ast_alloc);
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
pub fn _fuzz_lex(program: &str) {
|
|
// SAFETY: Just this scope
|
|
let mut runtime = unsafe { RtAlloc::new() };
|
|
let lexer = lex::Lexer::new(program, &mut runtime);
|
|
for _token in lexer {}
|
|
}
|