-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsemantics.c
More file actions
203 lines (181 loc) · 4.22 KB
/
semantics.c
File metadata and controls
203 lines (181 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
b32
isArithmeticType(Ctype ctype) {
b32 arith = ctype.type & Type_ARITH;
return arith;
}
b32
isScalarType(Ctype ctype) {
b32 scalar = isArithmeticType(ctype) || ctype.type == Type_POINTER || ctype.type == Type_ARRAY;
return scalar;
}
b32
isRealType(Ctype* ctype) {
b32 real = ctype->type & Type_REAL;
return real;
}
b32
isIntegerType(Ctype* ctype) {
b32 integer = ctype->type & Type_PEANO;
return integer;
}
b32
isAggregateType(Ctype* ctype) {
b32 is_aggr = ctype->type == Type_AGGREGATE;
return is_aggr;
}
b32
isImmediate(RegVar* src) {
b32 imm = false;
imm = src->location.type == Location_IMMEDIATE;
return imm;
}
b32
isDerivedType(Ctype* ctype) {
b32 is_derived = ctype->type == Type_POINTER || ctype->type == Type_ARRAY;
return is_derived;
}
u64
typeBits(Ctype* ctype) {
u64 bits = 0;
switch(ctype->type) {
// 8 bits
case Type_CHAR: {
bits = 8;
} break;
// 32 bits
case Type_FLOAT:
case Type_INT: {
bits = 32;
} break;
// 64 bits
case Type_POINTER:
case Type_DOUBLE:
case Type_LONG: {
bits = 64;
} break;
// N bits
case Type_AGGREGATE: {
bits = ctype->aggr.bits;
} break;
default: {
NotImplemented("ctype size.");
}
}
return bits;
}
b32
nodeIsExpression(AstNode* node) {
b32 isExpr = false;
if (node->type == Ast_MUL || node->type == Ast_DIV ||
node->type == Ast_ADD || node->type == Ast_SUB ||
node->type == Ast_EQUALS || node->type == Ast_LESS ||
node->type == Ast_GREATER || node->type == Ast_LEQ ||
node->type == Ast_GEQ || node->type == Ast_NOT_EQUALS ||
node->type == Ast_FUNCCALL || node->type == Ast_ASSIGN_EXPR ||
node->type == Ast_NUMBER || node->type == Ast_ID ||
node->type == Ast_POSTFIX_INC || node->type == Ast_POSTFIX_DEC ||
node->type == Ast_STRUCT_MEMBER_ACCESS || node->type == Ast_ADDRESS ||
node->type == Ast_LOGICAL_AND || node->type == Ast_LOGICAL_OR ||
node->type == Ast_STRING_LITERAL) {
isExpr = true;
}
return isExpr;
}
int
pointerSizeBits() {
return 64;
}
u64
numBytesForType(Ctype ctype) {
switch (ctype.type) {
case Type_INT: {
return 4;
} break;
case Type_CHAR: {
return 1;
} break;
case Type_FUNC: {
return 8*pointerSizeBits();
} break;
default: {
NotImplemented("Handle different size of types");
}
}
return 4;
}
b32
isLiteral(AstNode* node) {
b32 result = false;
AstType t = node->type;
if (t == Ast_NUMBER ) {
result = true;
}
return result;
}
b32
ctypeEquals(Ctype a, Ctype b) {
b32 equals = (a.type == b.type);
// TODO: What about const?
return equals;
}
int
intRank(Ctype type) {
int rank = 0;
switch (type.type) {
case Type_UCHAR:
case Type_CHAR: {
rank = 1;
} break;
case Type_USHORT:
case Type_SHORT: {
rank = 2;
} break;
case Type_UINT:
case Type_INT: {
rank = 3;
} break;
case Type_ULONG:
case Type_LONG: {
rank = 4;
} break;
}
return rank;
}
Ctype
arithmeticTypeConversion(Ctype a, Ctype b) {
Ctype result = {0};
if (ctypeEquals(a, b)) {
result = a;
}
else if (isRealType(&a) && isIntegerType(&b)) {
result = a;
}
else if (isRealType(&b) && isIntegerType(&a)) {
result = b;
}
else if (isIntegerType(&a) && isIntegerType(&b)) {
Ctype* lesser = (intRank(a) > intRank(b)) ? &b : &a;
Ctype* greater = (intRank(a) > intRank(b)) ? &a : &b;
// If both are unsigned or both are signed, use the one ranked higher.
if ((lesser->type & Type_UNSIGNED) == (greater->type & Type_UNSIGNED)) {
result = *greater;
} else {
NotImplemented("Continue with integer promotion");
}
}
else if (isRealType(&a) && isRealType(&b)) {
if (typeBits(&a) > typeBits(&b)) {
result = a;
}
else {
result = b;
}
}
Assert (result.type != Type_NONE);
return result;
}
b32
hasUnalignedMembers(Tag* tag) {
// TODO: when adding alignment pragma, implement this function
return false;
}