@@ -7,13 +7,16 @@ import std/{ traits, process, strings.Builder };
7
7
import ../token;
8
8
import ../utils;
9
9
10
- #[boxed; default_value(.Void)]
10
+ #[boxed; default_value(+mut .Void)]
11
11
pub enum Type < traits.Stringable {
12
12
Basic {
13
13
mut sym: ?+mut TypeSym;
14
14
mut is_unresolved: bool;
15
15
mut expr: +mut Expr;
16
- is_boxed: bool;
16
+ pos: token.Pos;
17
+ },
18
+ Boxed {
19
+ type: +mut Type;
17
20
is_mut: bool;
18
21
pos: token.Pos;
19
22
},
@@ -124,23 +127,22 @@ pub enum Type < traits.Stringable {
124
127
// unaliasing instead.
125
128
return match self.+ {
126
129
.Rawptr, .Boxedptr -> self,
127
- .Result(result) -> +mut .Result(result.inner.unalias() ?? result.inner),
128
- .Option(option) -> +mut .Option(option.inner.unalias() ?? option.inner),
130
+ .Boxed(boxed) -> +mut .Boxed(boxed.type.unalias() ?? boxed.type, ...self.+),
131
+ .Result(result) -> +mut .Result(result.inner.unalias() ?? result.inner, result.pos),
132
+ .Option(option) -> +mut .Option(option.inner.unalias() ?? option.inner, option.pos),
129
133
.Tuple(tuple_data) -> {
130
134
unaliased_types := []mut +mut Type(cap: tuple_data.inners.len);
131
135
for i, tuple_type in tuple_data.inners {
132
136
unaliased_types[i] = tuple_type.unalias() ?? tuple_type;
133
137
}
134
- // FIXME: fix concatenation bug with the previous and next expression as
135
- // a binary addition operation
136
- tmp := +mut Self.Tuple(unaliased_types, tuple_data.sym);
137
- tmp
138
+ +mut Self.Tuple(unaliased_types, tuple_data.sym, ...self.+)
138
139
},
139
140
.Slice(slice_data) -> +mut .Slice(
140
- slice_data.inner.unalias() ?? slice_data.inner, slice_data.is_mut
141
+ slice_data.inner.unalias() ?? slice_data.inner, slice_data.is_mut, ...self.+
141
142
),
142
143
.DynArray(dyn_array_data) -> +mut .DynArray(
143
- dyn_array_data.inner.unalias() ?? dyn_array_data.inner, dyn_array_data.is_mut
144
+ dyn_array_data.inner.unalias() ?? dyn_array_data.inner, dyn_array_data.is_mut,
145
+ ...self.+
144
146
),
145
147
.Array(array_data) -> +mut .Array(
146
148
array_data.inner.unalias() ?? array_data.inner, ...self.+
@@ -152,13 +154,10 @@ pub enum Type < traits.Stringable {
152
154
for arg in func_data.args {
153
155
arg.type = arg.type.unalias() ?? arg.type;
154
156
}
155
- // FIXME: fix concatenation bug with the previous and next expression as
156
- // a binary addition operation
157
- tmp := +mut Self.Func(
157
+ +mut Self.Func(
158
158
ret_type: func_data.ret_type.unalias() ?? func_data.ret_type,
159
159
...self.+
160
- );
161
- tmp
160
+ )
162
161
},
163
162
.Basic(basic) if !basic.is_unresolved -> if basic.sym?.info is .Alias(alias_info) {
164
163
alias_info.parent.unalias() ?? alias_info.parent
@@ -182,6 +181,7 @@ pub enum Type < traits.Stringable {
182
181
return match self.+ {
183
182
.Result(result) -> result.inner.symbol(),
184
183
.Option(option) -> option.inner.symbol(),
184
+ .Boxed(boxed) -> boxed.type.symbol(),
185
185
.Tuple(tuple_data) -> tuple_data.sym,
186
186
.Variadic(variadic_data) -> variadic_data.sym,
187
187
.Slice(slice_data) -> slice_data.sym,
@@ -205,11 +205,7 @@ pub enum Type < traits.Stringable {
205
205
206
206
#[inline]
207
207
pub func is_boxed(+self) -> bool {
208
- return if type_sym := self.symbol() {
209
- type_sym.is_boxed()
210
- } else {
211
- false
212
- };
208
+ return self is .Boxed;
213
209
}
214
210
215
211
#[inline]
@@ -238,12 +234,8 @@ pub enum Type < traits.Stringable {
238
234
#[inline]
239
235
pub func is_any_kind_of_pointer(+self) -> bool {
240
236
return match self.+ {
241
- .Pointer, .Rawptr, .Boxedptr, .Func -> true,
242
- else -> if type_sym := self.symbol() {
243
- type_sym.is_boxed()
244
- } else {
245
- false
246
- }
237
+ .Pointer, .Rawptr, .Boxedptr, .Func, .Boxed -> true,
238
+ else -> false
247
239
};
248
240
}
249
241
@@ -252,6 +244,7 @@ pub enum Type < traits.Stringable {
252
244
return match self.+ {
253
245
.Void, .None -> token.no_pos,
254
246
.Never(never_pos) -> never_pos,
247
+ .Boxed(boxed) -> boxed.pos,
255
248
.Option(opt_t) -> opt_t.pos,
256
249
.Result(res_t) -> res_t.pos,
257
250
.Tuple(tuple_t) -> tuple_t.pos,
@@ -277,6 +270,7 @@ pub enum Type < traits.Stringable {
277
270
.None if rhs is .None -> true,
278
271
.Void if rhs is .Void -> true,
279
272
.Never if rhs is .Never -> true,
273
+ .Boxed(boxed_lhs) if rhs is .Boxed(boxed_rhs) -> boxed_lhs.type == boxed_rhs.type,
280
274
.Result(result_lhs) if rhs is .Result(result_rhs) ->
281
275
result_lhs.inner == result_rhs.inner,
282
276
.Option(option_lhs) if rhs is .Option(option_rhs) ->
@@ -324,9 +318,7 @@ pub enum Type < traits.Stringable {
324
318
},
325
319
.Basic(basic_lhs) if rhs is .Basic(basic_rhs) ->
326
320
!(basic_lhs.is_unresolved && basic_rhs.is_unresolved)
327
- && basic_lhs.sym? == basic_rhs.sym?
328
- && basic_lhs.is_boxed == basic_rhs.is_boxed
329
- && basic_lhs.is_mut == basic_rhs.is_mut,
321
+ && basic_lhs.sym? == basic_rhs.sym?,
330
322
else -> false
331
323
};
332
324
}
@@ -348,6 +340,11 @@ pub enum Type < traits.Stringable {
348
340
.None -> "<none>",
349
341
.Void -> "<void>",
350
342
.Never -> "never",
343
+ .Boxed(boxed) -> if boxed.is_mut {
344
+ "+mut ".concat(boxed.type.to_string())
345
+ } else {
346
+ "+".concat(boxed.type.to_string())
347
+ },
351
348
.Result(result) -> if result.inner is .Void {
352
349
"!"
353
350
} else {
@@ -434,12 +431,6 @@ pub enum Type < traits.Stringable {
434
431
},
435
432
.Basic(basic) -> {
436
433
mut sb := Builder.new(150);
437
- if basic.is_boxed {
438
- sb.write("+");
439
- if basic.is_mut {
440
- sb.write("mut ");
441
- }
442
- }
443
434
sb.write(if type_sym := basic.sym {
444
435
if qualstr {
445
436
type_sym.qualname()
@@ -539,8 +530,12 @@ extend Env {
539
530
pub func type_size(+mut self, type: +mut Type, is_raw: bool := false) -> (uint, uint) {
540
531
return match type.+ {
541
532
.Result, .Option -> self.type_symbol_size(self.throwable_sym, is_raw),
542
- .Rawptr, .Boxedptr, .Pointer, .Func -> (self.pointer_size, self.pointer_size),
543
- .Basic(basic_t) if basic_t.is_boxed && !is_raw -> (self.pointer_size, self.pointer_size),
533
+ .Rawptr, .Boxedptr, .Pointer, .Func, .Boxed -> (self.pointer_size, self.pointer_size),
534
+ .Boxed(boxed) -> if is_raw {
535
+ (self.pointer_size, self.pointer_size)
536
+ } else {
537
+ self.type_size(boxed.type, is_raw)
538
+ },
544
539
else -> if type_sym := type.symbol() {
545
540
self.type_symbol_size(type_sym, is_raw)
546
541
} else {
@@ -554,94 +549,86 @@ extend Env {
554
549
(type_sym.size, type_sym.align)
555
550
} else {
556
551
(mut size: uint, mut align: uint) := (0, 0);
557
- (size, align) = if type_sym.is_boxed() && !is_raw {
558
- (self.pointer_size, self.pointer_size)
559
- } else {
560
- match type_sym.info.+ {
561
- .Func -> (self.pointer_size, self.pointer_size),
562
- .Alias(alias_info) -> self.type_size(alias_info.parent),
563
- .Bool -> (1, 1),
564
- .Uint, .Int -> (self.pointer_size, self.pointer_size),
565
- .SizedInt(int_) -> match int_.size {
566
- 8 -> (1, 1),
567
- 16 -> (2, 2),
568
- 32 -> (4, 4),
569
- 64 -> (8, 8),
570
- else -> (0, 0)
571
- },
572
- .SizedUint(uint_) -> match uint_.size {
573
- 8 -> (1, 1),
574
- 16 -> (2, 2),
575
- 32 -> (4, 4),
576
- 64 -> (8, 8),
577
- else -> (0, 0)
578
- },
579
- .Float(float) -> match float.size {
580
- 32 -> (4, 4),
581
- 64 -> (8, 8),
582
- else -> (0, 0)
583
- },
584
- .Rune -> (4, 4),
585
- .ComptimeFloat, .ComptimeInt -> (8, 8),
586
- .Enum(enum_info) -> if enum_info.is_tagged {
587
- if enum_info.is_boxed {
588
- ((type_sym.fields.len + 2) * self.pointer_size, self.pointer_size)
589
- } else {
590
- mut total_size := self.pointer_size;
591
- mut max_alignment := self.pointer_size;
592
- for variant in enum_info.variants {
593
- if variant.has_type {
594
- (variant_size, alignment) := self.type_size(variant.type);
595
- if alignment > max_alignment {
596
- max_alignment = alignment;
597
- }
598
- total_size = utils.round_up(total_size, alignment) + variant_size;
599
- }
600
- }
601
- (utils.round_up(total_size, max_alignment), max_alignment)
602
- }
603
- } else {
604
- self.type_size(enum_info.underlying_type)
605
- },
606
- .Slice -> (self.pointer_size * 3, self.pointer_size),
607
- .DynArray -> self.type_symbol_size(self.dyn_array_sym, is_raw),
608
- .Array(array_info) -> {
609
- (elem_size, elem_align) := self.type_size(array_info.elem_type);
610
- (array_info.size * elem_size, elem_align)
611
- },
612
- .Struct, .Tuple -> {
613
- mut total_size: uint := 0;
614
- mut max_alignment: uint := 0;
615
- types := if type_sym.info is .Tuple(tuple_lit) {
616
- tuple_lit.types
617
- } else {
618
- mut tmp := []+mut Type();
619
- for field in type_sym.full_fields() {
620
- tmp.push(field.type);
621
- }
622
- tmp
623
- };
624
- for ftype in types {
625
- (field_size, alignment) := self.type_size(ftype);
552
+ (size, align) = match type_sym.info.+ {
553
+ .Func -> (self.pointer_size, self.pointer_size),
554
+ .Alias(alias_info) -> self.type_size(alias_info.parent),
555
+ .Bool -> (1, 1),
556
+ .Uint, .Int -> (self.pointer_size, self.pointer_size),
557
+ .SizedInt(int_) -> match int_.size {
558
+ 8 -> (1, 1),
559
+ 16 -> (2, 2),
560
+ 32 -> (4, 4),
561
+ 64 -> (8, 8),
562
+ else -> (0, 0)
563
+ },
564
+ .SizedUint(uint_) -> match uint_.size {
565
+ 8 -> (1, 1),
566
+ 16 -> (2, 2),
567
+ 32 -> (4, 4),
568
+ 64 -> (8, 8),
569
+ else -> (0, 0)
570
+ },
571
+ .Float(float) -> match float.size {
572
+ 32 -> (4, 4),
573
+ 64 -> (8, 8),
574
+ else -> (0, 0)
575
+ },
576
+ .Rune -> (4, 4),
577
+ .ComptimeFloat, .ComptimeInt -> (8, 8),
578
+ .Enum(enum_info) -> if enum_info.is_tagged {
579
+ mut total_size := self.pointer_size;
580
+ mut max_alignment := self.pointer_size;
581
+ for variant in enum_info.variants {
582
+ if variant.has_type {
583
+ (variant_size, alignment) := self.type_size(variant.type);
626
584
if alignment > max_alignment {
627
585
max_alignment = alignment;
628
586
}
629
- total_size = utils.round_up(total_size, alignment) + field_size ;
587
+ total_size = utils.round_up(total_size, alignment) + variant_size ;
630
588
}
631
- (utils.round_up(total_size, max_alignment), max_alignment)
632
- },
633
- .Trait(trait_info) -> {
634
- (size, align) = ((type_sym.fields.len + 2) * self.pointer_size, self.pointer_size);
635
- for btype in trait_info.bases {
636
- (bsize, _balign) := self.type_symbol_size(btype, is_raw);
637
- size += bsize - 2 * self.pointer_size;
589
+ }
590
+ (utils.round_up(total_size, max_alignment), max_alignment)
591
+ } else {
592
+ self.type_size(enum_info.underlying_type)
593
+ },
594
+ .Slice -> (self.pointer_size * 3, self.pointer_size),
595
+ .DynArray -> self.type_symbol_size(self.dyn_array_sym, is_raw),
596
+ .Array(array_info) -> {
597
+ (elem_size, elem_align) := self.type_size(array_info.elem_type);
598
+ (array_info.size * elem_size, elem_align)
599
+ },
600
+ .Struct, .Tuple -> {
601
+ mut total_size: uint := 0;
602
+ mut max_alignment: uint := 0;
603
+ types := if type_sym.info is .Tuple(tuple_lit) {
604
+ tuple_lit.types
605
+ } else {
606
+ mut tmp := []+mut Type();
607
+ for field in type_sym.full_fields() {
608
+ tmp.push(field.type);
638
609
}
639
- (size, align)
640
- },
641
- else -> process.panic(
642
- "Env.type_size: unsupported type `{}`", type_sym.qualname()
643
- )
644
- }
610
+ tmp
611
+ };
612
+ for ftype in types {
613
+ (field_size, alignment) := self.type_size(ftype);
614
+ if alignment > max_alignment {
615
+ max_alignment = alignment;
616
+ }
617
+ total_size = utils.round_up(total_size, alignment) + field_size;
618
+ }
619
+ (utils.round_up(total_size, max_alignment), max_alignment)
620
+ },
621
+ .Trait(trait_info) -> {
622
+ (size, align) = ((type_sym.fields.len + 2) * self.pointer_size, self.pointer_size);
623
+ for btype in trait_info.bases {
624
+ (bsize, _balign) := self.type_symbol_size(btype, is_raw);
625
+ size += bsize - 2 * self.pointer_size;
626
+ }
627
+ (size, align)
628
+ },
629
+ else -> process.panic(
630
+ "Env.type_size: unsupported type `{}`", type_sym.qualname()
631
+ )
645
632
};
646
633
type_sym.size = size;
647
634
type_sym.align = align;
0 commit comments