forked from AbleOS/holey-bytes
adding default values to struct fields and @kindof directive
Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
0516ce68f4
commit
86f7d70747
|
@ -186,7 +186,7 @@ Ty := struct {
|
||||||
|
|
||||||
Ty2 := struct {
|
Ty2 := struct {
|
||||||
ty: Ty,
|
ty: Ty,
|
||||||
c: uint,
|
c: uint = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
useless := struct {}
|
useless := struct {}
|
||||||
|
@ -197,7 +197,7 @@ main := fn(): uint {
|
||||||
return 9001
|
return 9001
|
||||||
}
|
}
|
||||||
|
|
||||||
finst := Ty2.{ty: .{a: 4}, c: 3}
|
finst := Ty2.{ty: .{a: 4}}
|
||||||
inst := odher_pass(finst)
|
inst := odher_pass(finst)
|
||||||
if inst.c == 3 {
|
if inst.c == 3 {
|
||||||
return pass(&inst.ty)
|
return pass(&inst.ty)
|
||||||
|
@ -439,6 +439,8 @@ main := fn(): uint {
|
||||||
hardcoded_pointer := @as(^u8, @bitcast(10))
|
hardcoded_pointer := @as(^u8, @bitcast(10))
|
||||||
ecall_that_returns_uint := @as(uint, @eca(1, foo.Type.(10, 20), 5, 6))
|
ecall_that_returns_uint := @as(uint, @eca(1, foo.Type.(10, 20), 5, 6))
|
||||||
embedded_array := @as([u8; 15], @embed("text.txt"))
|
embedded_array := @as([u8; 15], @embed("text.txt"))
|
||||||
|
two_fields := @len(foo.Type)
|
||||||
|
the_struct_kind := @kindof(foo.Type)
|
||||||
return @inline(foo.foo)
|
return @inline(foo.foo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,6 +466,8 @@ arbitrary text
|
||||||
- `@eca(...<expr>)`: invoke `eca` instruction, where return type is inferred and `<expr>...` are arguments passed to the call in the standard call convention
|
- `@eca(...<expr>)`: invoke `eca` instruction, where return type is inferred and `<expr>...` are arguments passed to the call in the standard call convention
|
||||||
- `@embed(<string>)`: include relative file as an array of bytes
|
- `@embed(<string>)`: include relative file as an array of bytes
|
||||||
- `@inline(<func>, ...<args>)`: equivalent to `<func>(...<args>)` but function is guaranteed to inline, compiler will otherwise never inline
|
- `@inline(<func>, ...<args>)`: equivalent to `<func>(...<args>)` but function is guaranteed to inline, compiler will otherwise never inline
|
||||||
|
- `@len(<ty>)`: reports a length of the type of indexing purposes
|
||||||
|
- `@kindof(<ty>)`: gives an u8 integer describing the kind of type as an index to array `[Builtin, Struct, Enum, Union, Ptr, Slice, Opt, Func, Template, Global, Const, Module]`
|
||||||
|
|
||||||
#### c_strings
|
#### c_strings
|
||||||
```hb
|
```hb
|
||||||
|
|
|
@ -3,6 +3,7 @@ use {
|
||||||
lexer::{self, Lexer, TokenKind},
|
lexer::{self, Lexer, TokenKind},
|
||||||
parser::{
|
parser::{
|
||||||
self, CommentOr, CtorField, EnumField, Expr, FieldList, Poser, Radix, StructField,
|
self, CommentOr, CtorField, EnumField, Expr, FieldList, Poser, Radix, StructField,
|
||||||
|
UnionField,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
core::{
|
core::{
|
||||||
|
@ -339,10 +340,15 @@ impl<'a> Formatter<'a> {
|
||||||
"struct",
|
"struct",
|
||||||
trailing_comma,
|
trailing_comma,
|
||||||
fields,
|
fields,
|
||||||
|s, StructField { name, ty, .. }, f| {
|
|s, StructField { name, ty, default_value, .. }, f| {
|
||||||
f.write_str(name)?;
|
f.write_str(name)?;
|
||||||
f.write_str(": ")?;
|
f.write_str(": ")?;
|
||||||
s.fmt(ty, f)
|
s.fmt(ty, f)?;
|
||||||
|
if let Some(deva) = default_value {
|
||||||
|
f.write_str(" = ")?;
|
||||||
|
s.fmt(deva, f)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -351,7 +357,7 @@ impl<'a> Formatter<'a> {
|
||||||
"union",
|
"union",
|
||||||
trailing_comma,
|
trailing_comma,
|
||||||
fields,
|
fields,
|
||||||
|s, StructField { name, ty, .. }, f| {
|
|s, UnionField { name, ty, .. }, f| {
|
||||||
f.write_str(name)?;
|
f.write_str(name)?;
|
||||||
f.write_str(": ")?;
|
f.write_str(": ")?;
|
||||||
s.fmt(ty, f)
|
s.fmt(ty, f)
|
||||||
|
|
|
@ -378,10 +378,15 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
}
|
}
|
||||||
let name = s.expect_advance(T::Ident)?;
|
let name = s.expect_advance(T::Ident)?;
|
||||||
s.expect_advance(T::Colon)?;
|
s.expect_advance(T::Colon)?;
|
||||||
|
let (ty, default_value) = match s.expr()? {
|
||||||
|
Expr::BinOp { left, op: T::Assign, right, .. } => (*left, Some(*right)),
|
||||||
|
ty => (ty, None),
|
||||||
|
};
|
||||||
Some(Some(StructField {
|
Some(Some(StructField {
|
||||||
pos: name.start,
|
pos: name.start,
|
||||||
name: s.tok_str(name),
|
name: s.tok_str(name),
|
||||||
ty: s.expr()?,
|
ty,
|
||||||
|
default_value,
|
||||||
}))
|
}))
|
||||||
})?,
|
})?,
|
||||||
captured: self.collect_captures(prev_boundary, prev_captured),
|
captured: self.collect_captures(prev_boundary, prev_captured),
|
||||||
|
@ -395,11 +400,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
}
|
}
|
||||||
let name = s.expect_advance(T::Ident)?;
|
let name = s.expect_advance(T::Ident)?;
|
||||||
s.expect_advance(T::Colon)?;
|
s.expect_advance(T::Colon)?;
|
||||||
Some(Some(StructField {
|
Some(Some(UnionField { pos: name.start, name: s.tok_str(name), ty: s.expr()? }))
|
||||||
pos: name.start,
|
|
||||||
name: s.tok_str(name),
|
|
||||||
ty: s.expr()?,
|
|
||||||
}))
|
|
||||||
})?,
|
})?,
|
||||||
captured: self.collect_captures(prev_boundary, prev_captured),
|
captured: self.collect_captures(prev_boundary, prev_captured),
|
||||||
trailing_comma: core::mem::take(&mut self.trailing_sep) || must_trail,
|
trailing_comma: core::mem::take(&mut self.trailing_sep) || must_trail,
|
||||||
|
@ -790,15 +791,19 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
|
|
||||||
fn flag_idents(&mut self, e: Expr<'a>, flags: IdentFlags) {
|
fn flag_idents(&mut self, e: Expr<'a>, flags: IdentFlags) {
|
||||||
match e {
|
match e {
|
||||||
Expr::Ident { id, .. } => find_ident(&mut self.ctx.idents, id).flags |= flags,
|
Expr::Ident { id, .. } => {
|
||||||
|
if let Some(f) = find_ident(&mut self.ctx.idents, id) {
|
||||||
|
f.flags |= flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
Expr::Field { target, .. } => self.flag_idents(*target, flags),
|
Expr::Field { target, .. } => self.flag_idents(*target, flags),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_ident(idents: &mut [ScopeIdent], id: Ident) -> &mut ScopeIdent {
|
fn find_ident(idents: &mut [ScopeIdent], id: Ident) -> Option<&mut ScopeIdent> {
|
||||||
idents.binary_search_by_key(&id, |si| si.ident).map(|i| &mut idents[i]).unwrap()
|
idents.binary_search_by_key(&id, |si| si.ident).map(|i| &mut idents[i]).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_symbol(symbols: &[Symbol], id: Ident) -> &Symbol {
|
pub fn find_symbol(symbols: &[Symbol], id: Ident) -> &Symbol {
|
||||||
|
@ -1005,7 +1010,7 @@ generate_expr! {
|
||||||
/// `'union' LIST('{', ',', '}', Ident ':' Expr)`
|
/// `'union' LIST('{', ',', '}', Ident ':' Expr)`
|
||||||
Union {
|
Union {
|
||||||
pos: Pos,
|
pos: Pos,
|
||||||
fields: FieldList<'a, StructField<'a>>,
|
fields: FieldList<'a, UnionField<'a>>,
|
||||||
captured: &'a [Ident],
|
captured: &'a [Ident],
|
||||||
trailing_comma: bool,
|
trailing_comma: bool,
|
||||||
},
|
},
|
||||||
|
@ -1158,11 +1163,25 @@ impl Poser for EnumField<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
pub struct UnionField<'a> {
|
||||||
|
pub pos: Pos,
|
||||||
|
pub name: &'a str,
|
||||||
|
pub ty: Expr<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Poser for UnionField<'_> {
|
||||||
|
fn posi(&self) -> Pos {
|
||||||
|
self.pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
pub struct StructField<'a> {
|
pub struct StructField<'a> {
|
||||||
pub pos: Pos,
|
pub pos: Pos,
|
||||||
pub name: &'a str,
|
pub name: &'a str,
|
||||||
pub ty: Expr<'a>,
|
pub ty: Expr<'a>,
|
||||||
|
pub default_value: Option<Expr<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Poser for StructField<'_> {
|
impl Poser for StructField<'_> {
|
||||||
|
@ -1227,9 +1246,9 @@ pub enum CommentOr<'a, T> {
|
||||||
Comment { literal: &'a str, pos: Pos },
|
Comment { literal: &'a str, pos: Pos },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy> CommentOr<'_, T> {
|
impl<T> CommentOr<'_, T> {
|
||||||
pub fn or(&self) -> Option<T> {
|
pub fn or(&self) -> Option<&T> {
|
||||||
match *self {
|
match self {
|
||||||
CommentOr::Or(v) => Some(v),
|
CommentOr::Or(v) => Some(v),
|
||||||
CommentOr::Comment { .. } => None,
|
CommentOr::Comment { .. } => None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ use {
|
||||||
self, Arg, ArrayLen, CompState, ConstData, EnumData, EnumField, FTask, FuncData,
|
self, Arg, ArrayLen, CompState, ConstData, EnumData, EnumField, FTask, FuncData,
|
||||||
GlobalData, Loc, Module, Offset, OffsetIter, OptLayout, Sig, StringRef, StructData,
|
GlobalData, Loc, Module, Offset, OffsetIter, OptLayout, Sig, StringRef, StructData,
|
||||||
StructField, SymKey, TemplateData, Tuple, TypeBase, TypeIns, Types, UnionData,
|
StructField, SymKey, TemplateData, Tuple, TypeBase, TypeIns, Types, UnionData,
|
||||||
|
UnionField,
|
||||||
},
|
},
|
||||||
utils::{BitSet, EntSlice, Vc},
|
utils::{BitSet, EntSlice, Vc},
|
||||||
Ident,
|
Ident,
|
||||||
|
@ -1281,6 +1282,10 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.nodes.new_node(glob.ty, Kind::Global { global: id }, [VOID], self.tys);
|
self.ci.nodes.new_node(glob.ty, Kind::Global { global: id }, [VOID], self.tys);
|
||||||
Some(Value::ptr(g).ty(glob.ty))
|
Some(Value::ptr(g).ty(glob.ty))
|
||||||
}
|
}
|
||||||
|
Expr::Directive { name: "kindof", args: [ty], .. } => {
|
||||||
|
let ty = self.ty(ty);
|
||||||
|
self.gen_inferred_const(ctx, ty::Id::U8, ty.kind())
|
||||||
|
}
|
||||||
Expr::Directive { name: "nameof", args: [ty], .. } => {
|
Expr::Directive { name: "nameof", args: [ty], .. } => {
|
||||||
let ty = self.ty(ty);
|
let ty = self.ty(ty);
|
||||||
let mut data = core::mem::take(&mut self.pool.lit_buf);
|
let mut data = core::mem::take(&mut self.pool.lit_buf);
|
||||||
|
@ -1672,6 +1677,22 @@ impl<'a> Codegen<'a> {
|
||||||
self.store_mem(mem, ty, value.id);
|
self.store_mem(mem, ty, value.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i, &mut (ref mut ty, offset)) in
|
||||||
|
self.tys.struct_field_range(s).zip(&mut offs)
|
||||||
|
{
|
||||||
|
if *ty == ty::Id::UNDECLARED {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let field = &self.tys.ins.struct_fields[i];
|
||||||
|
let Some(deva) = field.default_value else { continue };
|
||||||
|
let value = self.gen_const(deva, Ctx::default().with_ty(*ty))?;
|
||||||
|
let mem = self.offset(mem, offset);
|
||||||
|
self.store_mem(mem, *ty, value.id);
|
||||||
|
|
||||||
|
*ty = ty::Id::UNDECLARED;
|
||||||
|
}
|
||||||
|
|
||||||
let field_list = self
|
let field_list = self
|
||||||
.tys
|
.tys
|
||||||
.struct_fields(s)
|
.struct_fields(s)
|
||||||
|
@ -2616,14 +2637,16 @@ impl<'a> Codegen<'a> {
|
||||||
let prev_file = mem::replace(&mut self.ci.file, c.file);
|
let prev_file = mem::replace(&mut self.ci.file, c.file);
|
||||||
let prev_parent = mem::replace(&mut self.ci.parent, c.parent);
|
let prev_parent = mem::replace(&mut self.ci.parent, c.parent);
|
||||||
let f = &self.files[c.file];
|
let f = &self.files[c.file];
|
||||||
let Expr::BinOp { left, right, .. } = c.ast.get(f) else { unreachable!() };
|
let value = match c.ast.get(f) {
|
||||||
|
Expr::BinOp { left, op: TokenKind::Decl, right, .. } => left
|
||||||
|
.find_pattern_path(c.name, right, |expr, is_ct| {
|
||||||
|
debug_assert!(is_ct);
|
||||||
|
self.ptr_expr_ctx(expr, ctx)
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|_| unreachable!()),
|
||||||
|
v => self.ptr_expr_ctx(v, ctx),
|
||||||
|
}?;
|
||||||
|
|
||||||
let value = left
|
|
||||||
.find_pattern_path(c.name, right, |expr, is_ct| {
|
|
||||||
debug_assert!(is_ct);
|
|
||||||
self.ptr_expr_ctx(expr, ctx)
|
|
||||||
})
|
|
||||||
.unwrap_or_else(|_| unreachable!())?;
|
|
||||||
self.ci.file = prev_file;
|
self.ci.file = prev_file;
|
||||||
self.ci.parent = prev_parent;
|
self.ci.parent = prev_parent;
|
||||||
Some(value)
|
Some(value)
|
||||||
|
@ -3731,14 +3754,32 @@ impl<'a> Codegen<'a> {
|
||||||
|s| [&mut s.ins.struct_fields, &mut s.tmp.struct_fields],
|
|s| [&mut s.ins.struct_fields, &mut s.tmp.struct_fields],
|
||||||
|s, field| {
|
|s, field| {
|
||||||
let ty = s.parse_ty(sc.anon(), &field.ty);
|
let ty = s.parse_ty(sc.anon(), &field.ty);
|
||||||
StructField { name: s.tys.names.intern(field.name), ty }
|
StructField {
|
||||||
|
name: s.tys.names.intern(field.name),
|
||||||
|
ty,
|
||||||
|
default_value: field.default_value.as_ref().map(|expr| {
|
||||||
|
s.tys.ins.consts.push(ConstData {
|
||||||
|
ast: ExprRef::new(expr),
|
||||||
|
name: Default::default(),
|
||||||
|
file: sc.file,
|
||||||
|
parent: Default::default(),
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|s, base| {
|
|s, base| {
|
||||||
s.ins.structs.push(StructData {
|
let str = s.ins.structs.push(StructData {
|
||||||
base,
|
base,
|
||||||
explicit_alignment: packed.then_some(1),
|
explicit_alignment: packed.then_some(1),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
});
|
||||||
|
|
||||||
|
s.ins.struct_fields[s.struct_field_range(str)]
|
||||||
|
.iter()
|
||||||
|
.filter_map(|f| f.default_value)
|
||||||
|
.for_each(|c| s.ins.consts[c].parent = str.into());
|
||||||
|
|
||||||
|
str
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Expr::Enum { pos, variants, captured, .. } => self.parse_base_ty(
|
Expr::Enum { pos, variants, captured, .. } => self.parse_base_ty(
|
||||||
|
@ -3757,10 +3798,10 @@ impl<'a> Codegen<'a> {
|
||||||
captured,
|
captured,
|
||||||
fields,
|
fields,
|
||||||
sc,
|
sc,
|
||||||
|s| [&mut s.ins.struct_fields, &mut s.tmp.struct_fields],
|
|s| [&mut s.ins.union_fields, &mut s.tmp.union_fields],
|
||||||
|s, field| {
|
|s, field| {
|
||||||
let ty = s.parse_ty(sc.anon(), &field.ty);
|
let ty = s.parse_ty(sc.anon(), &field.ty);
|
||||||
StructField { name: s.tys.names.intern(field.name), ty }
|
UnionField { name: s.tys.names.intern(field.name), ty }
|
||||||
},
|
},
|
||||||
|s, base| s.ins.unions.push(UnionData { base, ..Default::default() }),
|
|s, base| s.ins.unions.push(UnionData { base, ..Default::default() }),
|
||||||
),
|
),
|
||||||
|
@ -3829,7 +3870,7 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
fn parse_base_ty<A: Copy, F, T: Into<ty::Id>>(
|
fn parse_base_ty<A, F, T: Into<ty::Id>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
pos: Pos,
|
pos: Pos,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
|
@ -3837,7 +3878,7 @@ impl<'a> Codegen<'a> {
|
||||||
fields: FieldList<A>,
|
fields: FieldList<A>,
|
||||||
sc: TyScope,
|
sc: TyScope,
|
||||||
get_fields: impl Fn(&mut Types) -> [&mut Vec<F>; 2],
|
get_fields: impl Fn(&mut Types) -> [&mut Vec<F>; 2],
|
||||||
check_field: impl Fn(&mut Self, A) -> F,
|
check_field: impl Fn(&mut Self, &A) -> F,
|
||||||
check: impl Fn(&mut Types, TypeBase) -> T,
|
check: impl Fn(&mut Types, TypeBase) -> T,
|
||||||
) -> ty::Id {
|
) -> ty::Id {
|
||||||
let captures_start = self.tys.tmp.args.len();
|
let captures_start = self.tys.tmp.args.len();
|
||||||
|
@ -3853,7 +3894,9 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let prev_tmp = get_fields(self.tys)[1].len();
|
let prev_tmp = get_fields(self.tys)[1].len();
|
||||||
for field in fields.iter().filter_map(CommentOr::or).filter_map(Result::ok) {
|
for field in
|
||||||
|
fields.iter().filter_map(CommentOr::or).map(Result::as_ref).filter_map(Result::ok)
|
||||||
|
{
|
||||||
let field = check_field(self, field);
|
let field = check_field(self, field);
|
||||||
get_fields(self.tys)[1].push(field);
|
get_fields(self.tys)[1].push(field);
|
||||||
}
|
}
|
||||||
|
@ -3864,7 +3907,7 @@ impl<'a> Codegen<'a> {
|
||||||
pos,
|
pos,
|
||||||
captured,
|
captured,
|
||||||
name: sc.name.unwrap_or_default(),
|
name: sc.name.unwrap_or_default(),
|
||||||
field_start: self.tys.ins.struct_fields.len() as _,
|
field_start: get_fields(self.tys)[0].len() as _,
|
||||||
ast: ExprRef::new(expr),
|
ast: ExprRef::new(expr),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -414,6 +414,12 @@ macro_rules! type_kind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Id {
|
||||||
|
pub fn kind(self) -> u8 {
|
||||||
|
(self.repr() >> $name::FLAG_OFFSET) as _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$(
|
$(
|
||||||
impl From<$variant> for $name {
|
impl From<$variant> for $name {
|
||||||
fn from(value: $variant) -> Self {
|
fn from(value: $variant) -> Self {
|
||||||
|
@ -449,8 +455,8 @@ type_kind! {
|
||||||
Func,
|
Func,
|
||||||
Template,
|
Template,
|
||||||
Global,
|
Global,
|
||||||
Module,
|
|
||||||
Const,
|
Const,
|
||||||
|
Module,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,7 +535,7 @@ impl core::fmt::Display for Display<'_> {
|
||||||
f.write_str("[")?;
|
f.write_str("[")?;
|
||||||
idx.fmt(f)?;
|
idx.fmt(f)?;
|
||||||
f.write_str("]{")?;
|
f.write_str("]{")?;
|
||||||
for (i, &StructField { name, ty }) in
|
for (i, &StructField { name, ty, .. }) in
|
||||||
self.tys.struct_fields(idx).iter().enumerate()
|
self.tys.struct_fields(idx).iter().enumerate()
|
||||||
{
|
{
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
|
@ -551,7 +557,7 @@ impl core::fmt::Display for Display<'_> {
|
||||||
f.write_str("[")?;
|
f.write_str("[")?;
|
||||||
idx.fmt(f)?;
|
idx.fmt(f)?;
|
||||||
f.write_str("]{")?;
|
f.write_str("]{")?;
|
||||||
for (i, &StructField { name, ty }) in
|
for (i, &UnionField { name, ty }) in
|
||||||
self.tys.union_fields(idx).iter().enumerate()
|
self.tys.union_fields(idx).iter().enumerate()
|
||||||
{
|
{
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
|
@ -724,6 +730,11 @@ pub struct EnumData {
|
||||||
|
|
||||||
impl_deref!(EnumData { base: TypeBase });
|
impl_deref!(EnumData { base: TypeBase });
|
||||||
|
|
||||||
|
pub struct UnionField {
|
||||||
|
pub name: Ident,
|
||||||
|
pub ty: Id,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct UnionData {
|
pub struct UnionData {
|
||||||
pub base: TypeBase,
|
pub base: TypeBase,
|
||||||
|
@ -736,6 +747,7 @@ impl_deref!(UnionData { base: TypeBase });
|
||||||
pub struct StructField {
|
pub struct StructField {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub ty: Id,
|
pub ty: Id,
|
||||||
|
pub default_value: Option<Const>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -818,6 +830,7 @@ impl IdentInterner {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TypesTmp {
|
pub struct TypesTmp {
|
||||||
pub struct_fields: Vec<StructField>,
|
pub struct_fields: Vec<StructField>,
|
||||||
|
pub union_fields: Vec<UnionField>,
|
||||||
pub enum_fields: Vec<EnumField>,
|
pub enum_fields: Vec<EnumField>,
|
||||||
pub args: Vec<Id>,
|
pub args: Vec<Id>,
|
||||||
}
|
}
|
||||||
|
@ -826,6 +839,7 @@ pub struct TypesTmp {
|
||||||
pub struct TypeIns {
|
pub struct TypeIns {
|
||||||
pub args: Vec<Id>,
|
pub args: Vec<Id>,
|
||||||
pub struct_fields: Vec<StructField>,
|
pub struct_fields: Vec<StructField>,
|
||||||
|
pub union_fields: Vec<UnionField>,
|
||||||
pub enum_fields: Vec<EnumField>,
|
pub enum_fields: Vec<EnumField>,
|
||||||
pub funcs: EntVec<Func, FuncData>,
|
pub funcs: EntVec<Func, FuncData>,
|
||||||
pub templates: EntVec<Template, TemplateData>,
|
pub templates: EntVec<Template, TemplateData>,
|
||||||
|
@ -917,8 +931,8 @@ impl Types {
|
||||||
Tuple::new(sp, len)
|
Tuple::new(sp, len)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn union_fields(&self, union: Union) -> &[StructField] {
|
pub fn union_fields(&self, union: Union) -> &[UnionField] {
|
||||||
&self.ins.struct_fields[self.union_field_range(union)]
|
&self.ins.union_fields[self.union_field_range(union)]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn union_field_range(&self, union: Union) -> Range<usize> {
|
fn union_field_range(&self, union: Union) -> Range<usize> {
|
||||||
|
@ -927,7 +941,7 @@ impl Types {
|
||||||
.ins
|
.ins
|
||||||
.unions
|
.unions
|
||||||
.next(union)
|
.next(union)
|
||||||
.map_or(self.ins.struct_fields.len(), |s| s.field_start as usize);
|
.map_or(self.ins.union_fields.len(), |s| s.field_start as usize);
|
||||||
start..end
|
start..end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,7 +949,7 @@ impl Types {
|
||||||
&self.ins.struct_fields[self.struct_field_range(strct)]
|
&self.ins.struct_fields[self.struct_field_range(strct)]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn struct_field_range(&self, strct: Struct) -> Range<usize> {
|
pub fn struct_field_range(&self, strct: Struct) -> Range<usize> {
|
||||||
let start = self.ins.structs[strct].field_start as usize;
|
let start = self.ins.structs[strct].field_start as usize;
|
||||||
let end = self
|
let end = self
|
||||||
.ins
|
.ins
|
||||||
|
@ -1103,7 +1117,7 @@ impl Types {
|
||||||
self.struct_fields(s).iter().position(|f| f.name == name)
|
self.struct_fields(s).iter().position(|f| f.name == name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_union_field(&self, u: Union, name: &str) -> Option<(usize, &StructField)> {
|
pub fn find_union_field(&self, u: Union, name: &str) -> Option<(usize, &UnionField)> {
|
||||||
let name = self.names.project(name)?;
|
let name = self.names.project(name)?;
|
||||||
self.union_fields(u).iter().enumerate().find(|(_, f)| f.name == name)
|
self.union_fields(u).iter().enumerate().find(|(_, f)| f.name == name)
|
||||||
}
|
}
|
||||||
|
@ -1118,10 +1132,14 @@ impl Types {
|
||||||
self.ins.globals.clear();
|
self.ins.globals.clear();
|
||||||
self.ins.structs.clear();
|
self.ins.structs.clear();
|
||||||
self.ins.struct_fields.clear();
|
self.ins.struct_fields.clear();
|
||||||
|
self.ins.union_fields.clear();
|
||||||
|
self.ins.enum_fields.clear();
|
||||||
self.ins.ptrs.clear();
|
self.ins.ptrs.clear();
|
||||||
self.ins.slices.clear();
|
self.ins.slices.clear();
|
||||||
|
|
||||||
debug_assert_eq!(self.tmp.struct_fields.len(), 0);
|
debug_assert_eq!(self.tmp.struct_fields.len(), 0);
|
||||||
|
debug_assert_eq!(self.tmp.union_fields.len(), 0);
|
||||||
|
debug_assert_eq!(self.tmp.enum_fields.len(), 0);
|
||||||
debug_assert_eq!(self.tmp.args.len(), 0);
|
debug_assert_eq!(self.tmp.args.len(), 0);
|
||||||
|
|
||||||
debug_assert_eq!(self.tasks.len(), 0);
|
debug_assert_eq!(self.tasks.len(), 0);
|
||||||
|
|
Loading…
Reference in a new issue