reorganizing the type parser trait

This commit is contained in:
Jakub Doka 2024-10-20 16:43:25 +02:00
parent ccfde6c237
commit 3aff6fc006
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
3 changed files with 135 additions and 160 deletions

View file

@ -708,6 +708,44 @@ impl TypeParser for Codegen {
&mut self.tys &mut self.tys
} }
fn infer_type(&mut self, expr: &Expr) -> ty::Id {
let mut ci = ItemCtx {
file: self.ci.file,
ret: self.ci.ret,
task_base: self.ci.task_base,
..self.pool.cis.pop().unwrap_or_default()
};
ci.loops.extend(self.ci.loops.iter());
ci.vars.extend(self.ci.vars.iter().map(|v| Variable {
id: v.id,
value: Value { ty: v.value.ty, loc: v.value.loc.as_ref() },
}));
ci.stack_relocs.extend(self.ci.stack_relocs.iter());
ci.ret_relocs.extend(self.ci.ret_relocs.iter());
ci.loop_relocs.extend(self.ci.loop_relocs.iter());
ci.regs.init();
core::mem::swap(&mut self.ci, &mut ci);
let value = self.expr(expr).unwrap();
self.ci.free_loc(value.loc);
core::mem::swap(&mut self.ci, &mut ci);
ci.loops.clear();
ci.vars.clear();
ci.stack_relocs.clear();
ci.ret_relocs.clear();
ci.loop_relocs.clear();
ci.code.clear();
ci.relocs.clear();
self.pool.cis.push(ci);
value.ty
}
fn eval_const(&mut self, file: FileId, expr: &Expr, ty: ty::Id) -> u64 {
self.eval_const_low(file, expr, Some(ty)).0
}
fn on_reuse(&mut self, existing: ty::Id) { fn on_reuse(&mut self, existing: ty::Id) {
if let ty::Kind::Func(id) = existing.expand() if let ty::Kind::Func(id) = existing.expand()
&& let func = &mut self.tys.ins.funcs[id as usize] && let func = &mut self.tys.ins.funcs[id as usize]
@ -720,39 +758,16 @@ impl TypeParser for Codegen {
} }
} }
fn eval_ty( fn eval_global(&mut self, file: FileId, name: Ident, expr: &Expr) -> ty::Id {
&mut self,
file: FileId,
name: Option<Ident>,
expr: &Expr,
_: &[parser::Ast],
) -> ty::Id {
let prev_file = core::mem::replace(&mut self.ci.file, file);
let sym = match *expr {
Expr::Slice { size, item, .. } => {
let ty = self.ty(item);
let len = size.map_or(ArrayLen::MAX, |expr| {
self.eval_const(self.ci.file, expr, ty::U32) as _
});
self.tys.make_array(ty, len).expand()
}
Expr::Directive { name: "TypeOf", args: [expr], .. } => self.infer_type(expr).expand(),
_ if let Some(name) = name => {
let gid = self.tys.ins.globals.len() as ty::Global; let gid = self.tys.ins.globals.len() as ty::Global;
self.tys.ins.globals.push(Global { file, name, ..Default::default() }); self.tys.ins.globals.push(Global { file, name, ..Default::default() });
let ci = ItemCtx { file, ..self.pool.cis.pop().unwrap_or_default() }; let ci = ItemCtx { file, ..self.pool.cis.pop().unwrap_or_default() };
self.tys.ins.globals[gid as usize] = self self.tys.ins.globals[gid as usize] =
.ct_eval(ci, |s, _| Ok::<_, !>(s.generate_global(expr, file, name))) self.ct_eval(ci, |s, _| Ok::<_, !>(s.generate_global(expr, file, name))).into_ok();
.into_ok();
ty::Kind::Global(gid) ty::Kind::Global(gid).compress()
}
_ => ty::Id::from(self.eval_const(file, expr, ty::Id::TYPE)).expand(),
};
self.ci.file = prev_file;
sym.compress()
} }
fn report(&self, pos: Pos, msg: impl Display) -> ty::Id { fn report(&self, pos: Pos, msg: impl Display) -> ty::Id {
@ -882,7 +897,7 @@ impl Codegen {
E::Slice { size, item, .. } => { E::Slice { size, item, .. } => {
let ty = self.ty(item); let ty = self.ty(item);
let len = size.map_or(ArrayLen::MAX, |expr| { let len = size.map_or(ArrayLen::MAX, |expr| {
self.eval_const(self.ci.file, expr, ty::U32) as _ self.eval_const(self.ci.file, expr, ty::Id::U32) as _
}); });
Some(Value::ty(self.tys.make_array(ty, len))) Some(Value::ty(self.tys.make_array(ty, len)))
} }
@ -1853,45 +1868,6 @@ impl Codegen {
expr.has_ct(&self.cfile().symbols) expr.has_ct(&self.cfile().symbols)
} }
fn infer_type(&mut self, expr: &Expr) -> ty::Id {
// FIXME: very inneficient
let mut ci = ItemCtx {
file: self.ci.file,
ret: self.ci.ret,
task_base: self.ci.task_base,
..self.pool.cis.pop().unwrap_or_default()
};
ci.loops.extend(self.ci.loops.iter());
ci.vars.extend(self.ci.vars.iter().map(|v| Variable {
id: v.id,
value: Value { ty: v.value.ty, loc: v.value.loc.as_ref() },
}));
ci.stack_relocs.extend(self.ci.stack_relocs.iter());
ci.ret_relocs.extend(self.ci.ret_relocs.iter());
ci.loop_relocs.extend(self.ci.loop_relocs.iter());
ci.regs.init();
core::mem::swap(&mut self.ci, &mut ci);
let value = self.expr(expr).unwrap();
self.ci.free_loc(value.loc);
core::mem::swap(&mut self.ci, &mut ci);
ci.loops.clear();
ci.vars.clear();
ci.stack_relocs.clear();
ci.ret_relocs.clear();
ci.loop_relocs.clear();
ci.code.clear();
ci.relocs.clear();
self.pool.cis.push(ci);
value.ty
}
fn eval_const(&mut self, file: FileId, expr: &Expr, ty: impl Into<ty::Id>) -> u64 {
self.eval_const_low(file, expr, Some(ty.into())).0
}
fn eval_const_low( fn eval_const_low(
&mut self, &mut self,
file: FileId, file: FileId,

View file

@ -844,14 +844,10 @@ trait TypeParser {
fn tys(&mut self) -> &mut Types; fn tys(&mut self) -> &mut Types;
fn on_reuse(&mut self, existing: ty::Id); fn on_reuse(&mut self, existing: ty::Id);
fn find_local_ty(&mut self, name: Ident) -> Option<ty::Id>; fn find_local_ty(&mut self, name: Ident) -> Option<ty::Id>;
fn eval_const(&mut self, file: FileId, expr: &Expr, ty: ty::Id) -> u64;
fn eval_global(&mut self, file: FileId, name: Ident, expr: &Expr) -> ty::Id;
fn infer_type(&mut self, expr: &Expr) -> ty::Id;
fn report(&self, pos: Pos, msg: impl Display) -> ty::Id; fn report(&self, pos: Pos, msg: impl Display) -> ty::Id;
fn eval_ty(
&mut self,
file: FileId,
name: Option<Ident>,
expr: &Expr,
files: &[parser::Ast],
) -> ty::Id;
fn find_type( fn find_type(
&mut self, &mut self,
@ -943,14 +939,13 @@ trait TypeParser {
} }
Expr::Ident { id, .. } if ident::is_null(id) => id.into(), Expr::Ident { id, .. } if ident::is_null(id) => id.into(),
Expr::Ident { id, pos, .. } => self.find_type(pos, file, Ok(id), files), Expr::Ident { id, pos, .. } => self.find_type(pos, file, Ok(id), files),
Expr::Field { target, pos, name } => { Expr::Field { target, pos, name }
let ty::Kind::Module(file) = self.parse_ty(file, target, None, files).expand() if let ty::Kind::Module(file) =
else { self.parse_ty(file, target, None, files).expand() =>
return self.eval_ty(file, None, expr, files); {
};
self.find_type(pos, file, Err(name), files) self.find_type(pos, file, Err(name), files)
} }
Expr::Directive { name: "TypeOf", args: [expr], .. } => self.infer_type(expr),
Expr::Slice { size: None, item, .. } => { Expr::Slice { size: None, item, .. } => {
let ty = self.parse_ty(file, item, None, files); let ty = self.parse_ty(file, item, None, files);
self.tys().make_array(ty, ArrayLen::MAX) self.tys().make_array(ty, ArrayLen::MAX)
@ -959,6 +954,12 @@ trait TypeParser {
let ty = self.parse_ty(file, item, None, files); let ty = self.parse_ty(file, item, None, files);
self.tys().make_array(ty, value as _) self.tys().make_array(ty, value as _)
} }
Expr::Slice { size, item, .. } => {
let ty = self.parse_ty(file, item, None, files);
let len = size
.map_or(ArrayLen::MAX, |expr| self.eval_const(file, expr, ty::Id::U32) as _);
self.tys().make_array(ty, len)
}
Expr::Struct { pos, fields, packed, .. } => { Expr::Struct { pos, fields, packed, .. } => {
let sym = SymKey::Struct(file, pos); let sym = SymKey::Struct(file, pos);
let tys = self.tys(); let tys = self.tys();
@ -1021,7 +1022,8 @@ trait TypeParser {
ty::Kind::Func(id).compress() ty::Kind::Func(id).compress()
} }
_ => self.eval_ty(file, name, expr, files), _ if let Some(name) = name => self.eval_global(file, name, expr),
_ => ty::Id::from(self.eval_const(file, expr, ty::Id::TYPE)),
} }
} }
} }

View file

@ -1422,6 +1422,16 @@ impl TypeParser for Codegen<'_> {
&mut self.tys &mut self.tys
} }
#[expect(unused)]
fn eval_const(&mut self, file: FileId, expr: &Expr, ty: ty::Id) -> u64 {
todo!()
}
#[expect(unused)]
fn infer_type(&mut self, expr: &Expr) -> ty::Id {
todo!()
}
fn on_reuse(&mut self, existing: ty::Id) { fn on_reuse(&mut self, existing: ty::Id) {
if let ty::Kind::Func(id) = existing.expand() if let ty::Kind::Func(id) = existing.expand()
&& let func = &mut self.tys.ins.funcs[id as usize] && let func = &mut self.tys.ins.funcs[id as usize]
@ -1434,23 +1444,14 @@ impl TypeParser for Codegen<'_> {
} }
} }
#[expect(unused)] fn eval_global(&mut self, file: FileId, name: Ident, expr: &Expr) -> ty::Id {
fn eval_ty(
&mut self,
file: FileId,
name: Option<Ident>,
expr: &Expr,
files: &[parser::Ast],
) -> ty::Id {
let sym = match expr {
right if let Some(name) = name => {
let gid = self.tys.ins.globals.len() as ty::Global; let gid = self.tys.ins.globals.len() as ty::Global;
self.tys.ins.globals.push(Global { file, name, ..Default::default() }); self.tys.ins.globals.push(Global { file, name, ..Default::default() });
let ty = ty::Kind::Global(gid); let ty = ty::Kind::Global(gid);
self.pool.push_ci(file, None, self.tasks.len(), &mut self.ci); self.pool.push_ci(file, None, self.tasks.len(), &mut self.ci);
let ret = Expr::Return { pos: right.pos(), val: Some(right) }; let ret = Expr::Return { pos: expr.pos(), val: Some(expr) };
self.expr(&ret); self.expr(&ret);
self.ci.finalize(); self.ci.finalize();
@ -1483,8 +1484,7 @@ impl TypeParser for Codegen<'_> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
let mut vc = String::new(); let mut vc = String::new();
if let Err(e) = self.tys.disasm(&self.ct.code, self.files, &mut vc, |_| {}) if let Err(e) = self.tys.disasm(&self.ct.code, self.files, &mut vc, |_| {}) {
{
panic!("{e} {}", vc); panic!("{e} {}", vc);
} else { } else {
log::trace!("{}", vc); log::trace!("{}", vc);
@ -1505,8 +1505,9 @@ impl TypeParser for Codegen<'_> {
match mem.len() { match mem.len() {
0 => unreachable!(), 0 => unreachable!(),
len @ 1..=8 => mem len @ 1..=8 => {
.copy_from_slice(&self.ct.vm.read_reg(reg::RET).0.to_ne_bytes()[..len]), mem.copy_from_slice(&self.ct.vm.read_reg(reg::RET).0.to_ne_bytes()[..len])
}
9..=16 => todo!(), 9..=16 => todo!(),
_ => {} _ => {}
} }
@ -1517,11 +1518,7 @@ impl TypeParser for Codegen<'_> {
} }
self.tys.ins.globals[gid as usize].ty = ret; self.tys.ins.globals[gid as usize].ty = ret;
ty ty.compress()
}
e => self.report_unhandled_ast(expr, "type"),
};
sym.compress()
} }
fn report(&self, pos: Pos, msg: impl Display) -> ty::Id { fn report(&self, pos: Pos, msg: impl Display) -> ty::Id {