actually compiles and does stuff now
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
use super::{Function as PFunction, Node, ParserMsg, ParserOutput};
|
||||
use crate::ir::{
|
||||
BuiltinType, FileSpan, FnDef, FnIdent, Function, Idents, Instruction, Instructions,
|
||||
NamespaceGuard, Origin, Type, VarDef, VarIdent,
|
||||
use super::{FnLowerable, PFunction, Node, ParserMsg, ParserOutput};
|
||||
use crate::{
|
||||
ir::{
|
||||
BuiltinType, FileSpan, FnDef, FnID, IRUFunction, Idents, IRUInstruction, IRInstructions,
|
||||
NamespaceGuard, Origin, Type, VarDef, VarID,
|
||||
},
|
||||
parser,
|
||||
};
|
||||
|
||||
impl Node<PFunction> {
|
||||
@@ -9,15 +12,16 @@ impl Node<PFunction> {
|
||||
&self,
|
||||
map: &mut NamespaceGuard,
|
||||
output: &mut ParserOutput,
|
||||
) -> Option<FnIdent> {
|
||||
) -> Option<FnID> {
|
||||
self.as_ref()?.lower_header(map, output)
|
||||
}
|
||||
pub fn lower_body(&self, map: &mut NamespaceGuard, output: &mut ParserOutput) -> Option<Function> {
|
||||
if let Some(f) = self.as_ref() {
|
||||
Some(f.lower_body(map, output))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
pub fn lower_body(
|
||||
&self,
|
||||
id: FnID,
|
||||
map: &mut NamespaceGuard,
|
||||
output: &mut ParserOutput,
|
||||
) -> Option<IRUFunction> {
|
||||
Some(self.as_ref()?.lower_body(id, map, output))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +30,7 @@ impl PFunction {
|
||||
&self,
|
||||
map: &mut NamespaceGuard,
|
||||
output: &mut ParserOutput,
|
||||
) -> Option<FnIdent> {
|
||||
) -> Option<FnID> {
|
||||
let header = self.header.as_ref()?;
|
||||
let name = header.name.as_ref()?;
|
||||
let args = header
|
||||
@@ -44,50 +48,145 @@ impl PFunction {
|
||||
Some(ty) => ty.lower(map, output),
|
||||
None => Type::Concrete(BuiltinType::Unit.id()),
|
||||
};
|
||||
// ignoring self var for now
|
||||
Some(map.def_fn(FnDef {
|
||||
name: name.val().clone(),
|
||||
name: name.to_string(),
|
||||
origin: Origin::File(self.header.span),
|
||||
args,
|
||||
ret,
|
||||
}))
|
||||
}
|
||||
pub fn lower_body(&self, map: &mut NamespaceGuard, output: &mut ParserOutput) -> Function {
|
||||
let mut instructions = Instructions::new();
|
||||
pub fn lower_body(
|
||||
&self,
|
||||
id: FnID,
|
||||
map: &mut NamespaceGuard,
|
||||
output: &mut ParserOutput,
|
||||
) -> IRUFunction {
|
||||
let mut instructions = IRInstructions::new();
|
||||
let def = map.get_fn(id).clone();
|
||||
let args = def.args.iter().map(|a| {
|
||||
map.named_var(a.clone())
|
||||
}).collect();
|
||||
let mut ctx = FnLowerCtx {
|
||||
instructions: &mut instructions,
|
||||
map,
|
||||
output,
|
||||
span: self.body.span,
|
||||
};
|
||||
if let Some(res) = self.body.lower(&mut ctx) {
|
||||
match res {
|
||||
super::ExprResult::Var(v) => instructions.push(Instruction::Ret { src: v }),
|
||||
super::ExprResult::Fn(_) => todo!(),
|
||||
}
|
||||
if let Some(src) = self.body.lower(&mut ctx) {
|
||||
instructions.push(IRUInstruction::Ret { src });
|
||||
}
|
||||
Function::new(instructions)
|
||||
IRUFunction::new(def.name.clone(), args, instructions)
|
||||
}
|
||||
}
|
||||
|
||||
// impl Node<AsmFunction> {
|
||||
// pub fn lower_header(
|
||||
// &self,
|
||||
// map: &mut NamespaceGuard,
|
||||
// output: &mut ParserOutput,
|
||||
// ) -> Option<FnIdent> {
|
||||
// self.as_ref()?.lower_header(map, output)
|
||||
// }
|
||||
// pub fn lower_body(
|
||||
// &self,
|
||||
// map: &mut NamespaceGuard,
|
||||
// output: &mut ParserOutput,
|
||||
// ) -> Option<Function> {
|
||||
// Some(self.as_ref()?.lower_body(map, output))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl AsmFunction {
|
||||
// pub fn lower_header(
|
||||
// &self,
|
||||
// map: &mut NamespaceGuard,
|
||||
// output: &mut ParserOutput,
|
||||
// ) -> Option<FnIdent> {
|
||||
// let header = self.header.as_ref()?;
|
||||
// let name = header.name.as_ref()?;
|
||||
// let args = header
|
||||
// .args
|
||||
// .iter()
|
||||
// .map(|a| {
|
||||
// // a.lower(map, output).unwrap_or(VarDef {
|
||||
// // name: "{error}".to_string(),
|
||||
// // origin: Origin::File(a.span),
|
||||
// // ty: Type::Error,
|
||||
// // })
|
||||
// })
|
||||
// .collect();
|
||||
// // let ret = match &header.ret {
|
||||
// // Some(ty) => ty.lower(map, output),
|
||||
// // None => Type::Concrete(BuiltinType::Unit.id()),
|
||||
// // };
|
||||
// let ret = Type::Concrete(BuiltinType::Unit.id());
|
||||
// Some(map.def_fn(FnDef {
|
||||
// name: name.to_string(),
|
||||
// origin: Origin::File(self.header.span),
|
||||
// args,
|
||||
// ret,
|
||||
// }))
|
||||
// }
|
||||
// pub fn lower_body(&self, map: &mut NamespaceGuard, output: &mut ParserOutput) -> Function {
|
||||
// let mut instructions = Instructions::new();
|
||||
// let mut ctx = FnLowerCtx {
|
||||
// instructions: &mut instructions,
|
||||
// map,
|
||||
// output,
|
||||
// span: self.body.span,
|
||||
// };
|
||||
// self.body.lower(&mut ctx);
|
||||
// Function::new(instructions)
|
||||
// }
|
||||
// }
|
||||
|
||||
pub struct FnLowerCtx<'a, 'n> {
|
||||
pub map: &'a mut NamespaceGuard<'n>,
|
||||
pub instructions: &'a mut Instructions,
|
||||
pub instructions: &'a mut IRInstructions,
|
||||
pub output: &'a mut ParserOutput,
|
||||
pub span: FileSpan,
|
||||
}
|
||||
|
||||
impl<'a, 'n> FnLowerCtx<'a, 'n> {
|
||||
pub fn get(&self, name: &str) -> Option<Idents> {
|
||||
self.map.get(name)
|
||||
impl<'n> FnLowerCtx<'_, 'n> {
|
||||
pub fn span<'b>(&'b mut self, span: FileSpan) -> FnLowerCtx<'b, 'n> {
|
||||
FnLowerCtx {
|
||||
map: self.map,
|
||||
instructions: self.instructions,
|
||||
output: self.output,
|
||||
span,
|
||||
}
|
||||
}
|
||||
pub fn get(&mut self, node: &Node<parser::PIdent>) -> Option<Idents> {
|
||||
let name = node.inner.as_ref()?;
|
||||
let res = self.map.get(name);
|
||||
if res.is_none() {
|
||||
self.err_at(node.span, format!("Identifier '{}' not found", name));
|
||||
}
|
||||
res
|
||||
}
|
||||
pub fn get_var(&mut self, node: &Node<parser::PIdent>) -> Option<VarID> {
|
||||
let ids = self.get(node)?;
|
||||
if ids.var.is_none() {
|
||||
self.err_at(
|
||||
node.span,
|
||||
format!(
|
||||
"Variable '{}' not found; Type found but cannot be used here",
|
||||
node.inner.as_ref()?
|
||||
),
|
||||
);
|
||||
}
|
||||
ids.var
|
||||
}
|
||||
pub fn err(&mut self, msg: String) {
|
||||
self.output.err(ParserMsg::from_span(self.span, msg))
|
||||
}
|
||||
pub fn temp(&mut self, ty: Type) -> VarIdent {
|
||||
pub fn err_at(&mut self, span: FileSpan, msg: String) {
|
||||
self.output.err(ParserMsg::from_span(span, msg))
|
||||
}
|
||||
pub fn temp(&mut self, ty: Type) -> VarID {
|
||||
self.map.temp_var(self.span, ty)
|
||||
}
|
||||
pub fn push(&mut self, i: Instruction) {
|
||||
pub fn push(&mut self, i: IRUInstruction) {
|
||||
self.instructions.push(i);
|
||||
}
|
||||
pub fn sub<'b>(&'b mut self) -> FnLowerCtx<'b, 'n> {
|
||||
|
||||
Reference in New Issue
Block a user