From a7718e1220619657958c8a63b6d50b6e3f308620 Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Sun, 17 Nov 2024 17:14:44 +0100 Subject: [PATCH] cleaning up some code --- lang/src/son.rs | 258 +++++++++++++++++++++--------------------------- 1 file changed, 115 insertions(+), 143 deletions(-) diff --git a/lang/src/son.rs b/lang/src/son.rs index 926e591..8f2ccda 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -2865,76 +2865,53 @@ impl<'a> Codegen<'a> { self.implicit_unwrap(pos, &mut vtarget); let tty = vtarget.ty; - if let ty::Kind::Module(m) = tty.expand() { - return match self - .find_type(pos, self.ci.file, m, Err(name), self.files) - .expand() - { - ty::Kind::NEVER => Value::NEVER, - ty::Kind::Global(global) => self.gen_global(global), - ty::Kind::Const(cnst) => self.gen_const(cnst, ctx), - v => Some(Value::new(Nid::MAX).ty(v.compress())), - }; - } + match self.tys.base_of(tty).unwrap_or(tty).expand() { + ty::Kind::Module(m) => { + match self.find_type(pos, self.ci.file, m, Err(name), self.files).expand() { + ty::Kind::NEVER => Value::NEVER, + ty::Kind::Global(global) => self.gen_global(global), + 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::(); + 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() { - 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::(); + Some(Value::ptr(self.offset(vtarget.id, offset)).ty(ty)) + } + _ => { self.report( pos, fa!( - "the '{}' does not have this variant, \ - but it does have '{field_list}'", + "the '{}' is not a struct, or pointer to one, or enum, \ + fo field access does not make sense", self.ty_display(tty) ), ); - return Value::NEVER; - }; - - return Some(self.ci.nodes.new_const_lit(tty, index as i64)); + Value::NEVER + } } - - 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::(); - 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 } => { 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 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::(); - 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)) + self.gen_enum_variant(pos, e, intrnd) } Expr::UnOp { pos, op: op @ TokenKind::Sub, 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 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.nodes.new_node(ty::Id::VOID, Kind::Else, [if_node], self.tys), &mut self.ci.nodes, @@ -3928,34 +3884,7 @@ impl<'a> Codegen<'a> { self.ci.ctrl.get() }; - 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::VOID) + self.close_if(lcntrl, rcntrl, then_scope) } Expr::Match { pos, value, branches } => { 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 scopes = vec![]; - let mut else_branch = None; + let mut else_branch = None::; for &MatchBranch { pat, pos: bp, body } in branches { 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); continue; } + let pat_val = self.eval_const(self.ci.file, &pat, value.ty); if covered_values[pat_val as usize] != Pos::MAX { 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; } covered_values[pat_val as usize] = bp; @@ -4036,36 +3974,16 @@ impl<'a> Codegen<'a> { self.ci.ctrl.get() }; - for (lcntrl, mut then_scope) in scopes.into_iter().rev() { - 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); + for (lcntrl, then_scope) in scopes.into_iter().rev() { + if let Some(v) = self.close_if(lcntrl, rcntrl, then_scope) + && v.id != VOID + { + rcntrl = v.id; } + } - rcntrl = self.ci.nodes.new_node( - ty::Id::VOID, - 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); + if rcntrl == Nid::MAX { + return None; } 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 { + 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) -> Option { + 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::(); + 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( &mut self, ctx: Ctx,