Dividing function into template and instance, rmoving cumbersome options
Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
c5d5301b7b
commit
71ba2c2486
|
@ -273,7 +273,7 @@ impl Backend for HbvmBackend {
|
|||
tys: &Types,
|
||||
files: &EntSlice<Module, parser::Ast>,
|
||||
) {
|
||||
let sig = tys.ins.funcs[id].sig.unwrap();
|
||||
let sig = tys.ins.funcs[id].sig;
|
||||
|
||||
debug_assert!(self.code.is_empty());
|
||||
|
||||
|
|
|
@ -272,6 +272,10 @@ impl Ident {
|
|||
self.0 & ((1 << Self::LEN_BITS) - 1)
|
||||
}
|
||||
|
||||
pub fn is_type(self) -> bool {
|
||||
ty::Builtin::try_from(self) == Ok(ty::Builtin::TYPE)
|
||||
}
|
||||
|
||||
pub fn is_empty(self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
|
269
lang/src/son.rs
269
lang/src/son.rs
|
@ -16,7 +16,7 @@ use {
|
|||
ty::{
|
||||
self, Arg, ArrayLen, CompState, ConstData, EnumData, EnumField, FTask, FuncData,
|
||||
GlobalData, Loc, Module, Offset, OffsetIter, OptLayout, Sig, StringRef, StructData,
|
||||
StructField, SymKey, Tuple, TypeBase, TypeIns, Types, UnionData,
|
||||
StructField, SymKey, TemplateData, Tuple, TypeBase, TypeIns, Types, UnionData,
|
||||
},
|
||||
utils::{BitSet, EntSlice, Vc},
|
||||
Ident,
|
||||
|
@ -2782,7 +2782,7 @@ impl<'a> Codegen<'a> {
|
|||
|
||||
let fuc = self.tys.ins.funcs.push(FuncData {
|
||||
file,
|
||||
sig: Some(Sig { args: Tuple::empty(), ret }),
|
||||
sig: Sig { args: Tuple::empty(), ret },
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
|
@ -2894,8 +2894,8 @@ impl<'a> Codegen<'a> {
|
|||
fn make_func_reachable(&mut self, func: ty::Func) {
|
||||
let state_slot = self.ct.active() as usize;
|
||||
let fuc = &mut self.tys.ins.funcs[func];
|
||||
if fuc.comp_state[state_slot] == CompState::Dead {
|
||||
fuc.comp_state[state_slot] = CompState::Queued(self.tys.tasks.len() as _);
|
||||
if CompState::from(fuc.comp_state[state_slot]) == CompState::Dead {
|
||||
fuc.comp_state[state_slot] = CompState::Queued(self.tys.tasks.len() as _).into();
|
||||
self.tys.tasks.push(Some(FTask { file: fuc.file, id: func, ct: self.ct.active() }));
|
||||
}
|
||||
}
|
||||
|
@ -4231,12 +4231,7 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
ref e => {
|
||||
let ty = self.parse_ty(
|
||||
TyScope {
|
||||
file: self.ci.file,
|
||||
parent: self.ci.parent,
|
||||
name: None,
|
||||
alloc_const: false,
|
||||
},
|
||||
TyScope { file: self.ci.file, parent: self.ci.parent, ..Default::default() },
|
||||
e,
|
||||
);
|
||||
Some(self.ci.nodes.new_const_lit(ty::Id::TYPE, ty))
|
||||
|
@ -4327,6 +4322,7 @@ impl<'a> Codegen<'a> {
|
|||
| ty::Kind::Slice(_)
|
||||
| ty::Kind::Opt(_)
|
||||
| ty::Kind::Func(_)
|
||||
| ty::Kind::Template(_)
|
||||
| ty::Kind::Global(_)
|
||||
| ty::Kind::Const(_)) => self.error(
|
||||
pos,
|
||||
|
@ -4432,21 +4428,16 @@ impl<'a> Codegen<'a> {
|
|||
ref e => (self.ty(e), None),
|
||||
};
|
||||
|
||||
let ty::Kind::Func(mut fu) = ty.expand() else {
|
||||
self.error(func.pos(), fa!("compiler cant (yet) call '{}'", self.ty_display(ty)));
|
||||
let Some(fu) = self.compute_signature(ty, func.pos(), args) else {
|
||||
return Value::NEVER;
|
||||
};
|
||||
|
||||
let Some(sig) = self.compute_signature(&mut fu, func.pos(), args) else {
|
||||
return Value::NEVER;
|
||||
};
|
||||
|
||||
inline |= sig.ret == ty::Id::TYPE;
|
||||
|
||||
let FuncData { expr, file, is_inline, parent, .. } = self.tys.ins.funcs[fu];
|
||||
let FuncData { expr, file, is_inline, parent, sig, .. } = self.tys.ins.funcs[fu];
|
||||
let ast = &self.files[file];
|
||||
let &Expr::Closure { args: cargs, body, .. } = expr.get(ast) else { unreachable!() };
|
||||
|
||||
inline |= sig.ret == ty::Id::TYPE;
|
||||
|
||||
let arg_count = args.len() + caller.is_some() as usize;
|
||||
if arg_count != cargs.len() {
|
||||
self.error(
|
||||
|
@ -4803,79 +4794,90 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn compute_signature(&mut self, func: &mut ty::Func, pos: Pos, args: &[Expr]) -> Option<Sig> {
|
||||
let FuncData { file, expr, sig, parent, .. } = self.tys.ins.funcs[*func];
|
||||
fn compute_signature(&mut self, func: ty::Id, pos: Pos, args: &[Expr]) -> Option<ty::Func> {
|
||||
let template = match func.expand() {
|
||||
ty::Kind::Func(f) => return Some(f),
|
||||
ty::Kind::Template(t) => t,
|
||||
_ => {
|
||||
self.error(pos, fa!("compiler cant (yet) call '{}'", self.ty_display(func)));
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let TemplateData { file, expr, parent, name, is_inline, .. } =
|
||||
self.tys.ins.templates[template];
|
||||
let fast = &self.files[file];
|
||||
let &Expr::Closure { args: cargs, ret, .. } = expr.get(fast) else {
|
||||
let &Expr::Closure { pos, args: cargs, ret, .. } = expr.get(fast) else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
Some(if let Some(sig) = sig {
|
||||
sig
|
||||
} else {
|
||||
let arg_base = self.tys.tmp.args.len();
|
||||
let arg_base = self.tys.tmp.args.len();
|
||||
|
||||
let base = self.ci.scope.vars.len();
|
||||
for (arg, carg) in args.iter().zip(cargs) {
|
||||
let ty = self.ty_in(file, parent, &carg.ty);
|
||||
let base = self.ci.scope.vars.len();
|
||||
for (arg, carg) in args.iter().zip(cargs) {
|
||||
let ty = self.ty_in(file, parent, &carg.ty);
|
||||
|
||||
self.tys.tmp.args.push(ty);
|
||||
let sym = parser::find_symbol(&fast.symbols, carg.id);
|
||||
let ty = if sym.flags & idfl::COMPTIME == 0 {
|
||||
// FIXME: could fuck us
|
||||
continue;
|
||||
} else {
|
||||
if ty != ty::Id::TYPE {
|
||||
self.error(
|
||||
arg.pos(),
|
||||
fa!(
|
||||
"arbitrary comptime types are not supported yet \
|
||||
self.tys.tmp.args.push(ty);
|
||||
let sym = parser::find_symbol(&fast.symbols, carg.id);
|
||||
let ty = if sym.flags & idfl::COMPTIME == 0 {
|
||||
// FIXME: could fuck us
|
||||
continue;
|
||||
} else {
|
||||
if ty != ty::Id::TYPE {
|
||||
self.error(
|
||||
arg.pos(),
|
||||
fa!(
|
||||
"arbitrary comptime types are not supported yet \
|
||||
(expected '{}' got '{}')",
|
||||
self.ty_display(ty::Id::TYPE),
|
||||
self.ty_display(ty)
|
||||
),
|
||||
);
|
||||
return None;
|
||||
}
|
||||
let ty = self.ty(arg);
|
||||
self.tys.tmp.args.push(ty);
|
||||
ty
|
||||
};
|
||||
|
||||
self.ci.scope.vars.push(Variable::new(
|
||||
carg.id,
|
||||
ty::Id::TYPE,
|
||||
false,
|
||||
self.ci.nodes.new_const(ty::Id::TYPE, ty),
|
||||
&mut self.ci.nodes,
|
||||
));
|
||||
}
|
||||
|
||||
let Some(args) = self.tys.pack_args(arg_base) else {
|
||||
self.error(pos, "function instance has too many arguments");
|
||||
return None;
|
||||
self.ty_display(ty::Id::TYPE),
|
||||
self.ty_display(ty)
|
||||
),
|
||||
);
|
||||
return None;
|
||||
}
|
||||
let ty = self.ty(arg);
|
||||
self.tys.tmp.args.push(ty);
|
||||
ty
|
||||
};
|
||||
let ret = self.ty_in(file, parent, ret);
|
||||
|
||||
self.ci.scope.vars.drain(base..).for_each(|v| v.remove(&mut self.ci.nodes));
|
||||
self.ci.scope.vars.push(Variable::new(
|
||||
carg.id,
|
||||
ty::Id::TYPE,
|
||||
false,
|
||||
self.ci.nodes.new_const(ty::Id::TYPE, ty),
|
||||
&mut self.ci.nodes,
|
||||
));
|
||||
}
|
||||
|
||||
let sym = SymKey::FuncInst(*func, args);
|
||||
let ct = |ins: &mut TypeIns| {
|
||||
let fuc = ins.funcs[*func];
|
||||
debug_assert!(fuc.comp_state.iter().all(|&s| s == CompState::default()));
|
||||
ins.funcs
|
||||
.push(FuncData { base: Some(*func), sig: Some(Sig { args, ret }), ..fuc })
|
||||
.into()
|
||||
};
|
||||
let ty::Kind::Func(f) =
|
||||
self.tys.syms.get_or_insert(sym, &mut self.tys.ins, ct).expand()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
*func = f;
|
||||
let Some(args) = self.tys.pack_args(arg_base) else {
|
||||
self.error(pos, "function instance has too many arguments");
|
||||
return None;
|
||||
};
|
||||
let ret = self.ty_in(file, parent, ret);
|
||||
|
||||
Sig { args, ret }
|
||||
})
|
||||
self.ci.scope.vars.drain(base..).for_each(|v| v.remove(&mut self.ci.nodes));
|
||||
|
||||
let sym = SymKey::Type(parent, pos, args);
|
||||
let ct = |ins: &mut TypeIns| {
|
||||
ins.funcs
|
||||
.push(FuncData {
|
||||
file,
|
||||
parent,
|
||||
name,
|
||||
pos,
|
||||
expr,
|
||||
sig: Sig { args, ret },
|
||||
is_inline,
|
||||
is_generic: true,
|
||||
comp_state: Default::default(),
|
||||
})
|
||||
.into()
|
||||
};
|
||||
let ty::Kind::Func(f) = self.tys.syms.get_or_insert(sym, &mut self.tys.ins, ct).expand()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
Some(f)
|
||||
}
|
||||
|
||||
fn assign_pattern(&mut self, pat: &Expr, mut right: Value) {
|
||||
|
@ -5032,8 +5034,8 @@ impl<'a> Codegen<'a> {
|
|||
debug_assert_eq!(func.file, file);
|
||||
let cct = self.ct.active();
|
||||
debug_assert_eq!(cct, ct);
|
||||
func.comp_state[cct as usize] = CompState::Compiled;
|
||||
let sig = func.sig.expect("to emmit only concrete functions");
|
||||
func.comp_state[cct as usize] = CompState::Compiled.into();
|
||||
let sig = func.sig;
|
||||
let ast = &self.files[file];
|
||||
let expr = func.expr.get(ast);
|
||||
|
||||
|
@ -5198,7 +5200,7 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
|
||||
fn ty_in(&mut self, file: Module, parent: ty::Id, expr: &Expr) -> ty::Id {
|
||||
self.parse_ty(TyScope { file, parent, name: None, alloc_const: true }, expr)
|
||||
self.parse_ty(TyScope { file, parent, alloc_const: true, ..Default::default() }, expr)
|
||||
}
|
||||
|
||||
fn ty_display(&self, ty: ty::Id) -> ty::Display {
|
||||
|
@ -5495,10 +5497,10 @@ impl<'a> Codegen<'a> {
|
|||
let state_slot = self.ct.active() as usize;
|
||||
if let ty::Kind::Func(id) = existing.expand()
|
||||
&& let func = &mut self.tys.ins.funcs[id]
|
||||
&& let CompState::Queued(idx) = func.comp_state[state_slot]
|
||||
&& let CompState::Queued(idx) = func.comp_state[state_slot].into()
|
||||
&& idx < self.tys.tasks.len()
|
||||
{
|
||||
func.comp_state[state_slot] = CompState::Queued(self.tys.tasks.len());
|
||||
func.comp_state[state_slot] = CompState::Queued(self.tys.tasks.len()).into();
|
||||
let task = self.tys.tasks[idx].take();
|
||||
self.tys.tasks.push(task);
|
||||
}
|
||||
|
@ -5643,9 +5645,9 @@ impl<'a> Codegen<'a> {
|
|||
{
|
||||
ty
|
||||
} else {
|
||||
let (is_ct, ty) = left
|
||||
let ty = left
|
||||
.find_pattern_path(name, right, |right, is_ct| {
|
||||
let ty = if is_ct && !matches!(right, Expr::Closure { .. }) {
|
||||
if is_ct && !matches!(right, Expr::Closure { .. }) {
|
||||
self.tys
|
||||
.ins
|
||||
.consts
|
||||
|
@ -5653,23 +5655,23 @@ impl<'a> Codegen<'a> {
|
|||
.into()
|
||||
} else {
|
||||
self.parse_ty(
|
||||
TyScope { file, parent, name: Some(name), alloc_const: true },
|
||||
TyScope {
|
||||
file,
|
||||
parent,
|
||||
name: Some(name),
|
||||
alloc_const: true,
|
||||
is_ct,
|
||||
},
|
||||
right,
|
||||
)
|
||||
};
|
||||
(is_ct, ty)
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|_| unreachable!());
|
||||
if let ty::Kind::Func(f) = ty.expand()
|
||||
&& is_ct
|
||||
{
|
||||
self.tys.ins.funcs[f].is_inline = true;
|
||||
}
|
||||
self.tys.syms.insert(SymKey::Decl(parent, name), ty, &self.tys.ins);
|
||||
ty
|
||||
};
|
||||
|
||||
if let Err(proper_case) = self.tys.case(ty)(f.ident_str(name)) {
|
||||
if let Err(proper_case) = self.tys.case(ty, self.files)(f.ident_str(name)) {
|
||||
self.warn_low(
|
||||
from_file,
|
||||
pos,
|
||||
|
@ -5775,35 +5777,53 @@ impl<'a> Codegen<'a> {
|
|||
|s, base| s.ins.unions.push(UnionData { base, ..Default::default() }),
|
||||
),
|
||||
Expr::Closure { pos, args, ret, .. } if let Some(name) = sc.name => {
|
||||
let func = FuncData {
|
||||
file: sc.file,
|
||||
parent: sc.parent,
|
||||
name,
|
||||
sig: 'b: {
|
||||
let arg_base = self.tys.tmp.args.len();
|
||||
for arg in args {
|
||||
let sym = parser::find_symbol(&self.files[sc.file].symbols, arg.id);
|
||||
if sym.flags & idfl::COMPTIME != 0 {
|
||||
self.tys.tmp.args.truncate(arg_base);
|
||||
break 'b None;
|
||||
}
|
||||
let ty = self.parse_ty(sc.anon(), &arg.ty);
|
||||
self.tys.tmp.args.push(ty);
|
||||
let sig = 'b: {
|
||||
let arg_base = self.tys.tmp.args.len();
|
||||
for arg in args {
|
||||
let sym = parser::find_symbol(&self.files[sc.file].symbols, arg.id);
|
||||
if sym.flags & idfl::COMPTIME != 0 {
|
||||
self.tys.tmp.args.truncate(arg_base);
|
||||
break 'b None;
|
||||
}
|
||||
let ty = self.parse_ty(sc.anon(), &arg.ty);
|
||||
self.tys.tmp.args.push(ty);
|
||||
}
|
||||
|
||||
let Some(args) = self.tys.pack_args(arg_base) else {
|
||||
return self.error_low(sc.file, pos, "function has too many argumnets");
|
||||
};
|
||||
let ret = self.parse_ty(sc.anon(), ret);
|
||||
let Some(args) = self.tys.pack_args(arg_base) else {
|
||||
return self.error_low(sc.file, pos, "function has too many argumnets");
|
||||
};
|
||||
let ret = self.parse_ty(sc.anon(), ret);
|
||||
|
||||
Some(Sig { args, ret })
|
||||
},
|
||||
expr: ExprRef::new(expr),
|
||||
returns_type: matches!(ret, &Expr::Ident { id, .. } if ty::Builtin::try_from(id) == Ok(ty::Builtin::TYPE)),
|
||||
..Default::default()
|
||||
Some(Sig { args, ret })
|
||||
};
|
||||
//let returns_type = matches!(ret, &Expr::Ident { id, .. } if );
|
||||
|
||||
self.tys.ins.funcs.push(func).into()
|
||||
match sig {
|
||||
Some(sig) => {
|
||||
let func = FuncData {
|
||||
file: sc.file,
|
||||
parent: sc.parent,
|
||||
name,
|
||||
pos,
|
||||
sig,
|
||||
expr: ExprRef::new(expr),
|
||||
is_inline: sc.is_ct,
|
||||
is_generic: false,
|
||||
comp_state: Default::default(),
|
||||
};
|
||||
self.tys.ins.funcs.push(func).into()
|
||||
}
|
||||
None => {
|
||||
let template = TemplateData {
|
||||
file: sc.file,
|
||||
parent: sc.parent,
|
||||
name,
|
||||
expr: ExprRef::new(expr),
|
||||
is_inline: sc.is_ct,
|
||||
};
|
||||
self.tys.ins.templates.push(template).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ if sc.alloc_const
|
||||
&& let Some(name) = sc.name =>
|
||||
|
@ -5839,7 +5859,7 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
let captured = self.tys.pack_args(captures_start).expect("TODO");
|
||||
|
||||
let sym = SymKey::Type(sc.file, pos, captured);
|
||||
let sym = SymKey::Type(sc.parent, pos, captured);
|
||||
if let Some(&ty) = self.tys.syms.get(sym, &self.tys.ins) {
|
||||
return ty;
|
||||
}
|
||||
|
@ -5871,17 +5891,18 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
struct TyScope {
|
||||
file: Module,
|
||||
parent: ty::Id,
|
||||
name: Option<Ident>,
|
||||
alloc_const: bool,
|
||||
is_ct: bool,
|
||||
}
|
||||
|
||||
impl TyScope {
|
||||
fn anon(self) -> Self {
|
||||
Self { name: None, ..self }
|
||||
Self { name: None, is_ct: false, ..self }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
108
lang/src/ty.rs
108
lang/src/ty.rs
|
@ -119,29 +119,32 @@ impl crate::ctx_map::CtxEntry for Id {
|
|||
Kind::Struct(s) => {
|
||||
let st = &ctx.structs[s];
|
||||
debug_assert_ne!(st.pos, Pos::MAX);
|
||||
SymKey::Type(st.file, st.pos, st.captured)
|
||||
SymKey::Type(st.parent, st.pos, st.captured)
|
||||
}
|
||||
Kind::Enum(e) => {
|
||||
let en = &ctx.enums[e];
|
||||
debug_assert_ne!(en.pos, Pos::MAX);
|
||||
SymKey::Type(en.file, en.pos, en.captured)
|
||||
SymKey::Type(en.parent, en.pos, en.captured)
|
||||
}
|
||||
Kind::Union(e) => {
|
||||
let en = &ctx.unions[e];
|
||||
debug_assert_ne!(en.pos, Pos::MAX);
|
||||
SymKey::Type(en.file, en.pos, en.captured)
|
||||
SymKey::Type(en.parent, en.pos, en.captured)
|
||||
}
|
||||
Kind::Ptr(p) => SymKey::Pointer(&ctx.ptrs[p]),
|
||||
Kind::Opt(p) => SymKey::Optional(&ctx.opts[p]),
|
||||
Kind::Func(f) => {
|
||||
let fc = &ctx.funcs[f];
|
||||
if let Some(base) = fc.base {
|
||||
// TODO: merge base and sig
|
||||
SymKey::FuncInst(base, fc.sig.unwrap().args)
|
||||
if fc.is_generic {
|
||||
SymKey::Type(fc.parent, fc.pos, fc.sig.args)
|
||||
} else {
|
||||
SymKey::Decl(fc.parent, fc.name)
|
||||
}
|
||||
}
|
||||
Kind::Template(t) => {
|
||||
let tc = &ctx.templates[t];
|
||||
SymKey::Decl(tc.parent, tc.name)
|
||||
}
|
||||
Kind::Global(g) => {
|
||||
let gb = &ctx.globals[g];
|
||||
SymKey::Decl(gb.file.into(), gb.name)
|
||||
|
@ -271,7 +274,11 @@ impl Id {
|
|||
Kind::Ptr(_) | Kind::Enum(_) | Kind::Builtin(_) => Loc::Reg,
|
||||
Kind::Struct(_) | Kind::Union(_) if tys.size_of(*self) == 0 => Loc::Reg,
|
||||
Kind::Struct(_) | Kind::Union(_) | Kind::Slice(_) | Kind::Opt(_) => Loc::Stack,
|
||||
c @ (Kind::Func(_) | Kind::Global(_) | Kind::Module(_) | Kind::Const(_)) => {
|
||||
c @ (Kind::Func(_)
|
||||
| Kind::Global(_)
|
||||
| Kind::Module(_)
|
||||
| Kind::Const(_)
|
||||
| Kind::Template(_)) => {
|
||||
unreachable!("{c:?}")
|
||||
}
|
||||
}
|
||||
|
@ -439,6 +446,7 @@ type_kind! {
|
|||
Slice,
|
||||
Opt,
|
||||
Func,
|
||||
Template,
|
||||
Global,
|
||||
Module,
|
||||
Const,
|
||||
|
@ -568,6 +576,10 @@ impl core::fmt::Display for Display<'_> {
|
|||
f.write_str("fn")?;
|
||||
idx.fmt(f)
|
||||
}
|
||||
TK::Template(idx) => {
|
||||
f.write_str("fn")?;
|
||||
idx.fmt(f)
|
||||
}
|
||||
TK::Global(idx) => {
|
||||
let global = &self.tys.ins.globals[idx];
|
||||
let file = &self.files[global.file];
|
||||
|
@ -598,30 +610,71 @@ impl core::fmt::Display for Display<'_> {
|
|||
pub enum SymKey<'a> {
|
||||
Pointer(&'a PtrData),
|
||||
Optional(&'a OptData),
|
||||
Type(Module, Pos, Tuple),
|
||||
FuncInst(Func, Tuple),
|
||||
Type(Id, Pos, Tuple),
|
||||
Decl(Id, Ident),
|
||||
Array(&'a ArrayData),
|
||||
Constant(&'a ConstData),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct Sig {
|
||||
pub args: Tuple,
|
||||
pub ret: Id,
|
||||
}
|
||||
|
||||
pub struct TemplateData {
|
||||
pub file: Module,
|
||||
pub parent: Id,
|
||||
pub name: Ident,
|
||||
pub expr: ExprRef,
|
||||
pub is_inline: bool,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub struct FuncData {
|
||||
pub file: Module,
|
||||
pub parent: Id,
|
||||
pub name: Ident,
|
||||
pub base: Option<Func>,
|
||||
pub pos: Pos,
|
||||
pub expr: ExprRef,
|
||||
pub sig: Option<Sig>,
|
||||
pub sig: Sig,
|
||||
pub is_inline: bool,
|
||||
pub returns_type: bool,
|
||||
pub comp_state: [CompState; 2],
|
||||
pub is_generic: bool,
|
||||
pub comp_state: [PackedCompState; 2],
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub struct PackedCompState(u16);
|
||||
|
||||
impl Default for PackedCompState {
|
||||
fn default() -> Self {
|
||||
CompState::default().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl PackedCompState {
|
||||
const COMPILED: u16 = u16::MAX - 1;
|
||||
const DEAD: u16 = u16::MAX;
|
||||
}
|
||||
|
||||
impl From<PackedCompState> for CompState {
|
||||
fn from(value: PackedCompState) -> Self {
|
||||
match value.0 {
|
||||
PackedCompState::DEAD => CompState::Dead,
|
||||
PackedCompState::COMPILED => CompState::Compiled,
|
||||
v => CompState::Queued(v as _),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CompState> for PackedCompState {
|
||||
fn from(value: CompState) -> Self {
|
||||
Self(match value {
|
||||
CompState::Dead => Self::DEAD,
|
||||
CompState::Queued(v) => v.try_into().unwrap(),
|
||||
CompState::Compiled => Self::COMPILED,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Eq, Clone, Copy)]
|
||||
|
@ -774,6 +827,7 @@ pub struct TypeIns {
|
|||
pub struct_fields: Vec<StructField>,
|
||||
pub enum_fields: Vec<EnumField>,
|
||||
pub funcs: EntVec<Func, FuncData>,
|
||||
pub templates: EntVec<Template, TemplateData>,
|
||||
pub globals: EntVec<Global, GlobalData>,
|
||||
pub consts: EntVec<Const, ConstData>,
|
||||
pub structs: EntVec<Struct, StructData>,
|
||||
|
@ -812,7 +866,11 @@ pub struct Types {
|
|||
}
|
||||
|
||||
impl Types {
|
||||
pub fn case(&self, ty: Id) -> fn(&str) -> Result<(), &'static str> {
|
||||
pub fn case(
|
||||
&self,
|
||||
ty: Id,
|
||||
files: &EntSlice<Module, parser::Ast>,
|
||||
) -> fn(&str) -> Result<(), &'static str> {
|
||||
match ty.expand() {
|
||||
Kind::NEVER => |_| Ok(()),
|
||||
Kind::Enum(_)
|
||||
|
@ -822,8 +880,23 @@ impl Types {
|
|||
| Kind::Ptr(_)
|
||||
| Kind::Slice(_)
|
||||
| Kind::Opt(_) => utils::is_pascal_case,
|
||||
Kind::Func(f) if self.ins.funcs[f].returns_type => utils::is_pascal_case,
|
||||
Kind::Func(_) | Kind::Global(_) | Kind::Module(_) => utils::is_snake_case,
|
||||
Kind::Func(f)
|
||||
if let &Expr::Closure { ret: &Expr::Ident { id, .. }, .. } =
|
||||
self.ins.funcs[f].expr.get(&files[self.ins.funcs[f].file])
|
||||
&& id.is_type() =>
|
||||
{
|
||||
utils::is_pascal_case
|
||||
}
|
||||
Kind::Template(f)
|
||||
if let &Expr::Closure { ret: &Expr::Ident { id, .. }, .. } =
|
||||
self.ins.templates[f].expr.get(&files[self.ins.templates[f].file])
|
||||
&& id.is_type() =>
|
||||
{
|
||||
utils::is_pascal_case
|
||||
}
|
||||
Kind::Func(_) | Kind::Template(_) | Kind::Global(_) | Kind::Module(_) => {
|
||||
utils::is_snake_case
|
||||
}
|
||||
Kind::Const(_) => utils::is_screaming_case,
|
||||
}
|
||||
}
|
||||
|
@ -1063,6 +1136,7 @@ impl Types {
|
|||
| Kind::Slice(_)
|
||||
| Kind::Opt(_)
|
||||
| Kind::Func(_)
|
||||
| Kind::Template(_)
|
||||
| Kind::Global(_)
|
||||
| Kind::Module(_)
|
||||
| Kind::Const(_) => return None,
|
||||
|
|
Loading…
Reference in a new issue