add parse only mode

This commit is contained in:
nora 2022-05-01 12:22:49 +02:00
parent aab4d95b21
commit 3ac2746658
4 changed files with 19 additions and 8 deletions

View file

@ -25,3 +25,6 @@ insta = "1.9.0"
[[bench]] [[bench]]
name = "parser" name = "parser"
harness = false harness = false
[profile.release]
debug = true

View file

@ -36,6 +36,7 @@ type HashSet<T> = rustc_hash::FxHashSet<T>;
pub struct Config<'io> { pub struct Config<'io> {
pub debug: bool, pub debug: bool,
pub step: bool, pub step: bool,
pub parse_only: bool,
pub stdout: &'io mut dyn Write, pub stdout: &'io mut dyn Write,
} }
@ -53,7 +54,12 @@ pub fn run_program(program: &str, cfg: &mut Config) {
let ast = parse::parse(lexer, &ast_alloc); let ast = parse::parse(lexer, &ast_alloc);
match ast { match ast {
Ok(ast) => process_ast(program, &ast, runtime, cfg), Ok(ast) => {
if cfg.parse_only {
return;
}
process_ast(program, &ast, runtime, cfg)
}
Err(err) => errors::display_error(program, err), Err(err) => errors::display_error(program, err),
} }
} }

View file

@ -11,6 +11,7 @@ fn main() {
let mut cfg = Config { let mut cfg = Config {
debug: false, debug: false,
step: false, step: false,
parse_only: false,
stdout: &mut stdout, stdout: &mut stdout,
}; };
@ -18,6 +19,7 @@ fn main() {
match &*arg { match &*arg {
"--debug" => cfg.debug = true, "--debug" => cfg.debug = true,
"--step" => cfg.step = true, "--step" => cfg.step = true,
"--parse-only" => cfg.parse_only = true,
_ => {} _ => {}
} }
} }

View file

@ -89,28 +89,28 @@ enum HeapObjectKind {
#[derive(Debug)] #[derive(Debug)]
pub struct RtAlloc { pub struct RtAlloc {
symbols: HashSet<NonNullStrWrapper>, symbols: HashSet<NonNullStrStructuralEq>,
objects: LinkedList<HeapObject>, objects: LinkedList<HeapObject>,
} }
#[derive(Debug)] #[derive(Debug)]
struct NonNullStrWrapper(NonNull<str>); struct NonNullStrStructuralEq(NonNull<str>);
impl Hash for NonNullStrWrapper { impl Hash for NonNullStrStructuralEq {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
// SAFETY: Assume the ptr is valid, same rules as `Gc<T>` // SAFETY: Assume the ptr is valid, same rules as `Gc<T>`
unsafe { self.0.as_ref().hash(state) } unsafe { self.0.as_ref().hash(state) }
} }
} }
impl PartialEq for NonNullStrWrapper { impl PartialEq for NonNullStrStructuralEq {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
// SAFETY: Assume the ptr is valid, same rules as `Gc<T>` // SAFETY: Assume the ptr is valid, same rules as `Gc<T>`
unsafe { self.0.as_ref().eq(other.0.as_ref()) } unsafe { self.0.as_ref().eq(other.0.as_ref()) }
} }
} }
impl Eq for NonNullStrWrapper {} impl Eq for NonNullStrStructuralEq {}
impl RtAlloc { impl RtAlloc {
/// # Safety /// # Safety
@ -153,11 +153,11 @@ impl RtAlloc {
pub fn intern_string(&mut self, str: &str) -> Symbol { pub fn intern_string(&mut self, str: &str) -> Symbol {
let original_nonnull = NonNull::from(str); let original_nonnull = NonNull::from(str);
if let Some(interned) = self.symbols.get(&NonNullStrWrapper(original_nonnull)) { if let Some(interned) = self.symbols.get(&NonNullStrStructuralEq(original_nonnull)) {
Symbol::new(Gc { ptr: interned.0 }) Symbol::new(Gc { ptr: interned.0 })
} else { } else {
let allocated = self.alloc_str(str); let allocated = self.alloc_str(str);
self.symbols.insert(NonNullStrWrapper(allocated.ptr)); self.symbols.insert(NonNullStrStructuralEq(allocated.ptr));
Symbol::new(allocated) Symbol::new(allocated)
} }
} }