use crate::{ io::{CompilerMsg, CompilerOutput, Span}, parser::{Cursor, nodes::*}, }; mod ctx; mod dsp; pub use ctx::*; pub use dsp::*; pub struct Parsed { pub node: N, pub span: Span, } pub trait Node: Sized { fn parse(ctx: &mut ParseCtx) -> Result; fn fmt(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result; } pub fn parse_root(path: &str, output: &mut CompilerOutput) -> Option> { let root_code = match std::fs::read_to_string(path) { Ok(code) => code, Err(err) => { output.error(format!("Failed to read input file: {err}")); return None; } }; output.files.push(path.to_string()); let mut ctx = ParseCtx::new(Cursor::new(&root_code, 0)); let root = match ctx.parse() { Ok(v) => v, Err(msg) => { output.error(msg); return None; } }; Some(root) } impl Parsed { pub fn new(node: N, span: Span) -> Self { Self { node, span } } pub fn boxed(self) -> Box { Box::new(self) } } impl std::ops::Deref for Parsed { type Target = N; fn deref(&self) -> &Self::Target { &self.node } } impl std::ops::DerefMut for Parsed { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.node } } impl std::fmt::Display for Parsed { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.node.fmt(f, DisplayCtx { indent: 0 }) } }