cleaning up some code
This commit is contained in:
parent
e079bbd312
commit
a7718e1220
258
lang/src/son.rs
258
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::<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() {
|
||||
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>();
|
||||
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::<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 } => {
|
||||
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::<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))
|
||||
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::<Expr>;
|
||||
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<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(
|
||||
&mut self,
|
||||
ctx: Ctx,
|
||||
|
|
Loading…
Reference in a new issue