cleaning up some code

This commit is contained in:
Jakub Doka 2024-11-17 17:14:44 +01:00
parent e079bbd312
commit a7718e1220
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143

View file

@ -2865,76 +2865,53 @@ impl<'a> Codegen<'a> {
self.implicit_unwrap(pos, &mut vtarget); self.implicit_unwrap(pos, &mut vtarget);
let tty = vtarget.ty; let tty = vtarget.ty;
if let ty::Kind::Module(m) = tty.expand() { match self.tys.base_of(tty).unwrap_or(tty).expand() {
return match self ty::Kind::Module(m) => {
.find_type(pos, self.ci.file, m, Err(name), self.files) match self.find_type(pos, self.ci.file, m, Err(name), self.files).expand() {
.expand() ty::Kind::NEVER => Value::NEVER,
{ ty::Kind::Global(global) => self.gen_global(global),
ty::Kind::NEVER => Value::NEVER, ty::Kind::Const(cnst) => self.gen_const(cnst, ctx),
ty::Kind::Global(global) => self.gen_global(global), v => Some(Value::new(Nid::MAX).ty(v.compress())),
ty::Kind::Const(cnst) => self.gen_const(cnst, ctx), }
v => Some(Value::new(Nid::MAX).ty(v.compress())), }
}; ty::Kind::Enum(e) => {
} let intrnd = self.tys.names.project(name);
self.gen_enum_variant(pos, e, intrnd)
}
ty::Kind::Struct(s) => {
let Some((offset, ty)) = OffsetIter::offset_of(self.tys, s, name) else {
let field_list = self
.tys
.struct_fields(s)
.iter()
.map(|f| self.tys.names.ident_str(f.name))
.intersperse("', '")
.collect::<String>();
self.report(
pos,
fa!(
"the '{}' does not have this field, \
but it does have '{field_list}'",
self.ty_display(tty)
),
);
return Value::NEVER;
};
if let ty::Kind::Enum(e) = tty.expand() { Some(Value::ptr(self.offset(vtarget.id, offset)).ty(ty))
let intrnd = self.tys.names.project(name); }
let Some(index) = _ => {
self.tys.enum_fields(e).iter().position(|f| Some(f.name) == intrnd)
else {
let field_list = self
.tys
.enum_fields(e)
.iter()
.map(|f| self.tys.names.ident_str(f.name))
.intersperse("', '")
.collect::<String>();
self.report( self.report(
pos, pos,
fa!( fa!(
"the '{}' does not have this variant, \ "the '{}' is not a struct, or pointer to one, or enum, \
but it does have '{field_list}'", fo field access does not make sense",
self.ty_display(tty) self.ty_display(tty)
), ),
); );
return Value::NEVER; Value::NEVER
}; }
return Some(self.ci.nodes.new_const_lit(tty, index as i64));
} }
let ty::Kind::Struct(s) = self.tys.base_of(tty).unwrap_or(tty).expand() else {
self.report(
pos,
fa!(
"the '{}' is not a struct, or pointer to one, \
but accessing fields is only possible on structs",
self.ty_display(tty)
),
);
return Value::NEVER;
};
let Some((offset, ty)) = OffsetIter::offset_of(self.tys, s, name) else {
let field_list = self
.tys
.struct_fields(s)
.iter()
.map(|f| self.tys.names.ident_str(f.name))
.intersperse("', '")
.collect::<String>();
self.report(
pos,
fa!(
"the '{}' does not have this field, \
but it does have '{field_list}'",
self.ty_display(tty)
),
);
return Value::NEVER;
};
Some(Value::ptr(self.offset(vtarget.id, offset)).ty(ty))
} }
Expr::UnOp { op: TokenKind::Band, val, pos } => { Expr::UnOp { op: TokenKind::Band, val, pos } => {
let ctx = Ctx { ty: ctx.ty.and_then(|ty| self.tys.base_of(ty)) }; let ctx = Ctx { ty: ctx.ty.and_then(|ty| self.tys.base_of(ty)) };
@ -2982,28 +2959,7 @@ impl<'a> Codegen<'a> {
}; };
let intrnd = self.tys.names.project(self.file().ident_str(id)); let intrnd = self.tys.names.project(self.file().ident_str(id));
let Some(index) = self.gen_enum_variant(pos, e, intrnd)
self.tys.enum_fields(e).iter().position(|f| Some(f.name) == intrnd)
else {
let field_list = self
.tys
.enum_fields(e)
.iter()
.map(|f| self.tys.names.ident_str(f.name))
.intersperse("', '")
.collect::<String>();
self.report(
pos,
fa!(
"the '{}' does not have this variant, \
but it does have '{field_list}'",
self.ty_display(ty)
),
);
return Value::NEVER;
};
Some(self.ci.nodes.new_const_lit(ty, index as i64))
} }
Expr::UnOp { pos, op: op @ TokenKind::Sub, val } => { Expr::UnOp { pos, op: op @ TokenKind::Sub, val } => {
let val = let val =
@ -3917,7 +3873,7 @@ impl<'a> Codegen<'a> {
); );
let lcntrl = self.expr(then).map_or(Nid::MAX, |_| self.ci.ctrl.get()); let lcntrl = self.expr(then).map_or(Nid::MAX, |_| self.ci.ctrl.get());
let mut then_scope = mem::replace(&mut self.ci.scope, else_scope); let then_scope = mem::replace(&mut self.ci.scope, else_scope);
self.ci.ctrl.set( self.ci.ctrl.set(
self.ci.nodes.new_node(ty::Id::VOID, Kind::Else, [if_node], self.tys), self.ci.nodes.new_node(ty::Id::VOID, Kind::Else, [if_node], self.tys),
&mut self.ci.nodes, &mut self.ci.nodes,
@ -3928,34 +3884,7 @@ impl<'a> Codegen<'a> {
self.ci.ctrl.get() self.ci.ctrl.get()
}; };
if lcntrl == Nid::MAX && rcntrl == Nid::MAX { self.close_if(lcntrl, rcntrl, then_scope)
then_scope.clear(&mut self.ci.nodes);
return None;
} else if lcntrl == Nid::MAX {
then_scope.clear(&mut self.ci.nodes);
return Some(Value::VOID);
} else if rcntrl == Nid::MAX {
self.ci.scope.clear(&mut self.ci.nodes);
self.ci.scope = then_scope;
self.ci.ctrl.set(lcntrl, &mut self.ci.nodes);
return Some(Value::VOID);
}
self.ci.ctrl.set(
self.ci.nodes.new_node(ty::Id::VOID, Kind::Region, [lcntrl, rcntrl], self.tys),
&mut self.ci.nodes,
);
self.ci.nodes.merge_scopes(
&mut self.ci.loops,
&self.ci.ctrl,
&mut self.ci.scope,
&mut then_scope,
self.tys,
);
then_scope.clear(&mut self.ci.nodes);
Some(Value::VOID)
} }
Expr::Match { pos, value, branches } => { Expr::Match { pos, value, branches } => {
let value = self.expr(value)?; let value = self.expr(value)?;
@ -3973,16 +3902,25 @@ impl<'a> Codegen<'a> {
let mut covered_values = vec![Pos::MAX; self.tys.enum_field_range(e).len()]; let mut covered_values = vec![Pos::MAX; self.tys.enum_field_range(e).len()];
let mut scopes = vec![]; let mut scopes = vec![];
let mut else_branch = None; let mut else_branch = None::<Expr>;
for &MatchBranch { pat, pos: bp, body } in branches { for &MatchBranch { pat, pos: bp, body } in branches {
if let Expr::Wildcard { .. } = pat { if let Expr::Wildcard { .. } = pat {
if let Some(prev) = else_branch {
self.report(bp, "duplicate branch");
self.report(prev.pos(), "...first branch declared here");
}
else_branch = Some(body); else_branch = Some(body);
continue; continue;
} }
let pat_val = self.eval_const(self.ci.file, &pat, value.ty); let pat_val = self.eval_const(self.ci.file, &pat, value.ty);
if covered_values[pat_val as usize] != Pos::MAX { if covered_values[pat_val as usize] != Pos::MAX {
self.report(bp, "duplicate branch"); self.report(bp, "duplicate branch");
self.report(covered_values[pat_val as usize], "first branch declared here"); self.report(
covered_values[pat_val as usize],
"...first branch declared here",
);
continue; continue;
} }
covered_values[pat_val as usize] = bp; covered_values[pat_val as usize] = bp;
@ -4036,36 +3974,16 @@ impl<'a> Codegen<'a> {
self.ci.ctrl.get() self.ci.ctrl.get()
}; };
for (lcntrl, mut then_scope) in scopes.into_iter().rev() { for (lcntrl, then_scope) in scopes.into_iter().rev() {
if lcntrl == Nid::MAX && rcntrl == Nid::MAX { if let Some(v) = self.close_if(lcntrl, rcntrl, then_scope)
then_scope.clear(&mut self.ci.nodes); && v.id != VOID
return None; {
} else if lcntrl == Nid::MAX { rcntrl = v.id;
then_scope.clear(&mut self.ci.nodes);
return Some(Value::VOID);
} else if rcntrl == Nid::MAX {
self.ci.scope.clear(&mut self.ci.nodes);
self.ci.scope = then_scope;
self.ci.ctrl.set(lcntrl, &mut self.ci.nodes);
return Some(Value::VOID);
} }
}
rcntrl = self.ci.nodes.new_node( if rcntrl == Nid::MAX {
ty::Id::VOID, return None;
Kind::Region,
[lcntrl, rcntrl],
self.tys,
);
self.ci.ctrl.set(rcntrl, &mut self.ci.nodes);
self.ci.nodes.merge_scopes(
&mut self.ci.loops,
&self.ci.ctrl,
&mut self.ci.scope,
&mut then_scope,
self.tys,
);
then_scope.clear(&mut self.ci.nodes);
} }
Some(Value::VOID) Some(Value::VOID)
@ -4077,6 +3995,60 @@ impl<'a> Codegen<'a> {
} }
} }
fn close_if(&mut self, lcntrl: Nid, rcntrl: Nid, mut then_scope: Scope) -> Option<Value> {
if lcntrl == Nid::MAX && rcntrl == Nid::MAX {
then_scope.clear(&mut self.ci.nodes);
return None;
} else if lcntrl == Nid::MAX {
then_scope.clear(&mut self.ci.nodes);
return Some(Value::VOID);
} else if rcntrl == Nid::MAX {
self.ci.scope.clear(&mut self.ci.nodes);
self.ci.scope = then_scope;
self.ci.ctrl.set(lcntrl, &mut self.ci.nodes);
return Some(Value::VOID);
}
self.ci.ctrl.set(
self.ci.nodes.new_node(ty::Id::VOID, Kind::Region, [lcntrl, rcntrl], self.tys),
&mut self.ci.nodes,
);
self.ci.nodes.merge_scopes(
&mut self.ci.loops,
&self.ci.ctrl,
&mut self.ci.scope,
&mut then_scope,
self.tys,
);
then_scope.clear(&mut self.ci.nodes);
Some(Value::new(self.ci.ctrl.get()).ty(ty::Id::VOID))
}
fn gen_enum_variant(&mut self, pos: Pos, e: ty::Enum, intrnd: Option<Ident>) -> Option<Value> {
let Some(index) = self.tys.enum_fields(e).iter().position(|f| Some(f.name) == intrnd)
else {
let field_list = self
.tys
.enum_fields(e)
.iter()
.map(|f| self.tys.names.ident_str(f.name))
.intersperse("', '")
.collect::<String>();
self.report(
pos,
fa!(
"the '{}' does not have this variant, \
but it does have '{field_list}'",
self.ty_display(e.into())
),
);
return Value::NEVER;
};
Some(self.ci.nodes.new_const_lit(e.into(), index as i64))
}
fn gen_inferred_const( fn gen_inferred_const(
&mut self, &mut self,
ctx: Ctx, ctx: Ctx,