initial structure impl
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// TODO: move this into ir, not parser
|
||||
use super::{IRUProgram, Type};
|
||||
use super::{IRUInstruction, IRUProgram, Type};
|
||||
use crate::common::{CompilerMsg, CompilerOutput};
|
||||
|
||||
impl IRUProgram {
|
||||
@@ -8,18 +8,18 @@ impl IRUProgram {
|
||||
for (f, fd) in self.fns.iter().flatten().zip(&self.fn_defs) {
|
||||
for i in &f.instructions {
|
||||
match &i.i {
|
||||
super::IRUInstruction::Mv { dest, src } => {
|
||||
IRUInstruction::Mv { dest, src } => {
|
||||
let dest = self.get_var(dest.id);
|
||||
let src = self.get_var(src.id);
|
||||
output.check_assign(self, &src.ty, &dest.ty, i.span);
|
||||
}
|
||||
super::IRUInstruction::Ref { dest, src } => todo!(),
|
||||
super::IRUInstruction::LoadData { dest, src } => {
|
||||
IRUInstruction::Ref { dest, src } => todo!(),
|
||||
IRUInstruction::LoadData { dest, src } => {
|
||||
let dest = self.get_var(dest.id);
|
||||
let src = self.get_data(*src);
|
||||
output.check_assign(self, &src.ty, &dest.ty, i.span);
|
||||
}
|
||||
super::IRUInstruction::LoadSlice { dest, src } => {
|
||||
IRUInstruction::LoadSlice { dest, src } => {
|
||||
let dest = self.get_var(dest.id);
|
||||
let src = self.get_data(*src);
|
||||
let Type::Array(srcty, ..) = &src.ty else {
|
||||
@@ -27,8 +27,8 @@ impl IRUProgram {
|
||||
};
|
||||
output.check_assign(self, &Type::Slice(srcty.clone()), &dest.ty, i.span);
|
||||
}
|
||||
super::IRUInstruction::LoadFn { dest, src } => todo!(),
|
||||
super::IRUInstruction::Call { dest, f, args } => {
|
||||
IRUInstruction::LoadFn { dest, src } => todo!(),
|
||||
IRUInstruction::Call { dest, f, args } => {
|
||||
let destty = &self.get_var(dest.id).ty;
|
||||
let f = self.get_var(f.id);
|
||||
let Type::Fn { args: argtys, ret } = &f.ty else {
|
||||
@@ -46,13 +46,66 @@ impl IRUProgram {
|
||||
output.check_assign(self, argt, &dest.ty, argv.span);
|
||||
}
|
||||
}
|
||||
super::IRUInstruction::AsmBlock { instructions, args } => {
|
||||
IRUInstruction::AsmBlock { instructions, args } => {
|
||||
// TODO
|
||||
}
|
||||
super::IRUInstruction::Ret { src } => {
|
||||
IRUInstruction::Ret { src } => {
|
||||
let srcty = &self.get_var(src.id).ty;
|
||||
output.check_assign(self, srcty, &fd.ret, src.span);
|
||||
},
|
||||
}
|
||||
IRUInstruction::Construct { dest, fields } => {
|
||||
let dest_def = self.get_var(dest.id);
|
||||
let tyid = match dest_def.ty {
|
||||
Type::Concrete(id) => id,
|
||||
_ => {
|
||||
output.err(CompilerMsg {
|
||||
msg: "uhh type is not struct".to_string(),
|
||||
spans: vec![dest.span],
|
||||
});
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let def = self.get_struct(tyid);
|
||||
for (name, field) in &def.fields {
|
||||
if let Some(var) = fields.get(name) {
|
||||
let ety = &self.get_var(var.id).ty;
|
||||
output.check_assign(self, &field.ty, ety, var.span);
|
||||
} else {
|
||||
output.err(CompilerMsg {
|
||||
msg: format!("field '{name}' missing from struct"),
|
||||
spans: vec![dest.span],
|
||||
});
|
||||
}
|
||||
}
|
||||
for name in fields.keys() {
|
||||
if !def.fields.contains_key(name) {
|
||||
output.err(CompilerMsg {
|
||||
msg: format!("field '{name}' not in struct"),
|
||||
spans: vec![dest.span],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
IRUInstruction::Access { dest, src, field } => {
|
||||
let dest_def = self.get_var(dest.id);
|
||||
let src_def = self.get_var(src.id);
|
||||
let tyid = match src_def.ty {
|
||||
Type::Concrete(id) => id,
|
||||
_ => {
|
||||
output.err(CompilerMsg {
|
||||
msg: "uhh type is not struct".to_string(),
|
||||
spans: vec![dest.span],
|
||||
});
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let def = self.get_struct(tyid);
|
||||
let field = def.fields.get(field).expect(
|
||||
"already validated during parse lowering... probably shouldn't be?",
|
||||
);
|
||||
output.check_assign(self, &field.ty, &dest_def.ty, i.span);
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user