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);
|
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,
|
||||||
|
|
Loading…
Reference in a new issue