mod arch; mod asm; mod block; mod def; mod expr; mod func; mod struc; mod ty; use super::*; use crate::ir::{Type, UFunc, UProgram}; impl PModule { pub fn lower( &self, path: Vec, p: &mut UProgram, imports: &mut Imports, output: &mut CompilerOutput, ) { let name = path.last().unwrap().clone(); p.set_module(path); let fid = p.def_searchable(&name, None, self.block.origin); p.push_name(&name); let mut fctx = FnLowerCtx { program: p, instructions: Vec::new(), output, origin: self.block.origin, imports, }; self.block.lower(&mut fctx); let f = UFunc { args: Vec::new(), instructions: fctx.instructions, ret: Type::Unit, }; p.write(fid, f); p.pop_name(); } } pub use func::FnLowerCtx; use import::Imports; pub trait FnLowerable { type Output; fn lower(&self, ctx: &mut FnLowerCtx) -> Option; } impl FnLowerable for Node { type Output = T::Output; fn lower(&self, ctx: &mut FnLowerCtx) -> Option { let old_span = ctx.origin; ctx.origin = self.origin; let res = self.as_ref()?.lower(ctx); ctx.origin = old_span; res } } impl FnLowerable for Box { type Output = T::Output; fn lower(&self, ctx: &mut FnLowerCtx) -> Option { self.as_ref().lower(ctx) } }