Skip to content

Commit 74b85d6

Browse files
committed
Compiler: make void a separate typekind
* remove `BuiltinType.isChar()`, `BuiltinType.isInt8()`, `BuiltinType.isUInt8()`, `QualType.isInt8()` * add `QualType.isCharCompatible()` * remove `Void` builtin type, add `Void` `TypeKind` and `TypeRefKind` * simplify binary operation dispatch * fix unary type checking, detect more type errors
1 parent 49b2e62 commit 74b85d6

28 files changed

+313
-244
lines changed

analyser/conversion_checker.c2

Lines changed: 62 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,27 @@ import src_loc local;
3838
// 14 = Enum -> Enum
3939
// 15 = Builtin -> Func
4040
// 16 = Func -> Builtin
41+
// 17 = Anything -> Void
4142
const u8[elemsof(TypeKind)][elemsof(TypeKind)] Conversions = {
42-
// Builtin Pointer Array Struct Enum Func Alias Module
43+
// Builtin Pointer Array Struct Enum Func Void Alias Module
4344
// Builtin ->
44-
{ 2, 3, 1, 1, 13, 15, 0, 0 },
45+
{ 2, 3, 1, 1, 13, 15, 17, 0, 0 },
4546
// Pointer ->
46-
{ 4, 5, 1, 1, 1, 6, 0, 0 },
47+
{ 4, 5, 1, 1, 1, 6, 17, 0, 0 },
4748
// Array ->
48-
{ 1, 7, 8, 1, 1, 1, 0, 0 },
49+
{ 1, 7, 8, 1, 1, 1, 17, 0, 0 },
4950
// Struct ->
50-
{ 1, 1, 1, 9, 1, 1, 0, 0 },
51+
{ 1, 1, 1, 9, 1, 1, 17, 0, 0 },
5152
// Enum ->
52-
{ 10, 1, 1, 1, 14, 1, 0, 0 },
53+
{ 10, 1, 1, 1, 14, 1, 17, 0, 0 },
5354
// Function ->
54-
{ 16, 11, 1, 1, 1, 12, 0, 0 },
55+
{ 16, 11, 1, 1, 1, 12, 17, 0, 0 },
56+
// Void += / -=
57+
{ 1, 1, 1, 1, 1, 1, 17, 0, 0 },
5558
// Alias ->
56-
{ 0, 0, 0, 0, 0, 0, 0, 0 },
59+
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
5760
// Module ->
58-
{ 0, 0, 0, 0, 0, 0, 0, 0 },
61+
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
5962
}
6063

6164
// 0 = should not happen? (same)
@@ -68,38 +71,36 @@ const u8[elemsof(TypeKind)][elemsof(TypeKind)] Conversions = {
6871
// 7 = ok, no conversion needed (eg. char -> u8, isize -> i64, i32 -> bool)
6972
// No need to adjust for 32-bit as ISize and USize are converted before the lookup
7073
const u8[elemsof(BuiltinKind)][elemsof(BuiltinKind)] BuiltinConversions = {
71-
// Char Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Flt32 Flt64 ISize USize Bool Void
72-
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
74+
// Char Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Flt32 Flt64 ISize USize Bool
75+
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14
7376
// Char ->
74-
{ 0, 3, 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 7, 2 },
77+
{ 0, 3, 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 7 },
7578
// Int8 ->
76-
{ 3, 0, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 3, 7, 2 },
79+
{ 3, 0, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 3, 7 },
7780
// Int16 ->
78-
{ 4, 4, 0, 1, 1, 4, 3, 3, 3, 1, 1, 1, 3, 7, 2 },
81+
{ 4, 4, 0, 1, 1, 4, 3, 3, 3, 1, 1, 1, 3, 7 },
7982
// Int32 ->
80-
{ 4, 4, 4, 7, 1, 4, 4, 3, 3, 1, 1, 1, 3, 7, 2 },
83+
{ 4, 4, 4, 7, 1, 4, 4, 3, 3, 1, 1, 1, 3, 7 },
8184
// Int64 ->
82-
{ 4, 4, 4, 4, 7, 4, 4, 4, 3, 1, 1, 7, 3, 7, 2 },
85+
{ 4, 4, 4, 4, 7, 4, 4, 4, 3, 1, 1, 7, 3, 7 },
8386
// UInt8 ->
84-
{ 1, 3, 1, 1, 1, 0, 1, 1, 1, 1, 1, 3, 1, 7, 2 },
87+
{ 1, 3, 1, 1, 1, 0, 1, 1, 1, 1, 1, 3, 1, 7 },
8588
// UInt16 ->
86-
{ 4, 4, 3, 1, 1, 4, 0, 1, 1, 1, 1, 3, 1, 7, 2 },
89+
{ 4, 4, 3, 1, 1, 4, 0, 1, 1, 1, 1, 3, 1, 7 },
8790
// UInt32 ->
88-
{ 4, 4, 4, 3, 1, 4, 4, 7, 1, 1, 1, 3, 1, 7, 2 },
91+
{ 4, 4, 4, 3, 1, 4, 4, 7, 1, 1, 1, 3, 1, 7 },
8992
// UInt64 ->
90-
{ 4, 4, 4, 4, 3, 4, 4, 4, 7, 1, 1, 3, 7, 7, 2 },
93+
{ 4, 4, 4, 4, 3, 4, 4, 4, 7, 1, 1, 3, 7, 7 },
9194
// Flt32 ->
92-
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 1, 5, 5, 2, 2 },
95+
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 1, 5, 5, 2 },
9396
// Flt64 ->
94-
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 0, 5, 5, 2, 2 },
97+
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 0, 5, 5, 2 },
9598
// ISize ->
96-
{ 4, 4, 4, 4, 7, 4, 4, 4, 3, 1, 1, 0, 3, 7, 2 },
99+
{ 4, 4, 4, 4, 7, 4, 4, 4, 3, 1, 1, 0, 3, 7 },
97100
// USize ->
98-
{ 4, 4, 4, 4, 3, 4, 4, 4, 7, 1, 1, 3, 0, 7, 2 },
101+
{ 4, 4, 4, 4, 3, 4, 4, 4, 7, 1, 1, 3, 0, 7 },
99102
// Bool ->
100-
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2 },
101-
// Void ->
102-
{ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0 },
103+
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
103104
}
104105

105106
public type Checker struct {
@@ -210,6 +211,8 @@ fn bool Checker.checkTypes(Checker* c, const Type* lcanon, const Type* rcanon) {
210211
return c.conversionError("invalid type conversion from");
211212
case 16: // Function -> Builtin
212213
return c.checkFunc2Builtin(lcanon, rcanon, false);
214+
case 17: // Anything -> Void
215+
return true;
213216
default:
214217
c.diags.note(c.loc, "TODO CONVERSION %d)", res);
215218
return false;
@@ -622,38 +625,36 @@ fn bool Checker.checkPointer2BuiltinCast(Checker* c, const Type* lcanon, const T
622625
// Just takes smallest type, dont promote both sides to i32
623626
// No need to adjust for 32-bit as ISize and USize are converted before the lookup
624627
const u8[elemsof(BuiltinKind)][elemsof(BuiltinKind)] ConditionalOperatorResult = {
625-
// Char Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Flt32 Flt64 ISize USize Bool Void
626-
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
628+
// Char Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Flt32 Flt64 ISize USize Bool
629+
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
627630
// Char ->
628-
{ 0, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 14 },
631+
{ 0, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0 },
629632
// Int8 ->
630-
{ 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 14 },
633+
{ 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1 },
631634
// Int16 ->
632-
{ 2, 2, 2, 3, 4, 2, 6, 7, 8, 9, 10, 11, 12, 2, 14 },
635+
{ 2, 2, 2, 3, 4, 2, 6, 7, 8, 9, 10, 11, 12, 2 },
633636
// Int32 ->
634-
{ 3, 3, 3, 3, 4, 3, 3, 7, 8, 9, 10, 11, 12, 3, 14 },
637+
{ 3, 3, 3, 3, 4, 3, 3, 7, 8, 9, 10, 11, 12, 3 },
635638
// Int64 ->
636-
{ 4, 4, 4, 4, 4, 4, 4, 4, 8, 9, 10, 11, 12, 4, 14 },
639+
{ 4, 4, 4, 4, 4, 4, 4, 4, 8, 9, 10, 11, 12, 4 },
637640
// UInt8 ->
638-
{ 5, 5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 14 },
641+
{ 5, 5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5 },
639642
// UInt16 ->
640-
{ 6, 6, 6, 3, 4, 6, 6, 7, 8, 9, 10, 11, 12, 6, 14 },
643+
{ 6, 6, 6, 3, 4, 6, 6, 7, 8, 9, 10, 11, 12, 6 },
641644
// UInt32 ->
642-
{ 7, 7, 7, 7, 7, 7, 7, 7, 8, 9, 10, 11, 12, 7, 14 },
645+
{ 7, 7, 7, 7, 7, 7, 7, 7, 8, 9, 10, 11, 12, 7 },
643646
// UInt64 ->
644-
{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 8, 14 },
647+
{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 8 },
645648
// Flt32 ->
646-
{ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 9, 9, 9, 14 },
649+
{ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 9, 9, 9 },
647650
// Flt64 ->
648-
{ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 14 },
651+
{ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 },
649652
// ISize ->
650-
{ 11, 11, 11, 11, 11, 11, 11, 11, 8, 9, 10, 11, 12, 11, 14 },
653+
{ 11, 11, 11, 11, 11, 11, 11, 11, 8, 9, 10, 11, 12, 11 },
651654
// USize ->
652-
{ 12, 12, 12, 12, 12, 12, 12, 12, 8, 9, 10, 12, 12, 12, 14 },
655+
{ 12, 12, 12, 12, 12, 12, 12, 12, 8, 9, 10, 12, 12, 12 },
653656
// Bool ->
654-
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 },
655-
// Void ->
656-
{ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 },
657+
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
657658
}
658659
public fn QualType get_common_arithmetic_type(BuiltinType* bi1, BuiltinType* bi2) {
659660
BuiltinKind kind = (BuiltinKind)ConditionalOperatorResult[bi2.getBaseKind()][bi1.getBaseKind()];
@@ -673,38 +674,36 @@ public fn QualType get_common_arithmetic_type(BuiltinType* bi1, BuiltinType* bi2
673674
// See ISO/IEC 9899:201x 6.3.1
674675
// No need to adjust for 32-bit as ISize and USize are converted before the lookup
675676
const u8[elemsof(BuiltinKind)][elemsof(BuiltinKind)] UsualArithmeticConversions = {
676-
// Char Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Flt32 Flt64 ISize USize Bool Void
677-
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
677+
// Char Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Flt32 Flt64 ISize USize Bool
678+
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
678679
// Char ->
679-
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0, 6 },
680+
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0 },
680681
// Int8 ->
681-
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0, 6 },
682+
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0 },
682683
// Int16 ->
683-
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0, 6 },
684+
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0 },
684685
// Int32 ->
685-
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0, 6 },
686+
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0 },
686687
// Int64 ->
687-
{ 2, 2, 2, 3, 2, 2, 2, 2, 3, 4, 5, 6, 6, 2, 6 },
688+
{ 2, 2, 2, 3, 2, 2, 2, 2, 3, 4, 5, 6, 6, 2 },
688689
// UInt8 ->
689-
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0, 6 },
690+
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0 },
690691
// UInt16 ->
691-
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0, 6 },
692+
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0 },
692693
// UInt32 ->
693-
{ 1, 1, 1, 1, 3, 1, 1, 1, 3, 4, 5, 6, 6, 1, 6 },
694+
{ 1, 1, 1, 1, 3, 1, 1, 1, 3, 4, 5, 6, 6, 1 },
694695
// UInt64 ->
695-
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 6, 3, 6 },
696+
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 6, 3 },
696697
// Flt32 ->
697-
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 6 },
698+
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4 },
698699
// Flt64 ->
699-
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6 },
700+
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
700701
// ISize ->
701-
{ 6, 6, 6, 6, 6, 6, 6, 6, 3, 4, 5, 6, 6, 6, 6 },
702+
{ 6, 6, 6, 6, 6, 6, 6, 6, 3, 4, 5, 6, 6, 6 },
702703
// USize ->
703-
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6 },
704+
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 6, 6, 6 },
704705
// Bool ->
705-
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0, 6 },
706-
// Void ->
707-
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
706+
{ 0, 0, 0, 0, 2, 0, 0, 1, 3, 4, 5, 6, 6, 0 },
708707
}
709708

710709
public fn QualType usual_arithmetic_conversion(const BuiltinType* b1, const BuiltinType* b2) {

analyser/ctv_analyser.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public fn bool checkTypeRange(diagnostics.Diags* diags, QualType qt, Value* valu
7575

7676
BuiltinType* bi = canon.getBuiltin();
7777
// TODO: check float32 range
78-
if (bi.getKind() == BuiltinKind.Float32 || bi.getKind() == BuiltinKind.Float64) return true;
78+
if (bi.isFloatingPoint()) return true;
7979

8080
Limit limit.init(bi.getWidth(), bi.isSigned());
8181

0 commit comments

Comments
 (0)