Skip to content

Commit 84255f3

Browse files
committed
work on bool types
1 parent 6d0513c commit 84255f3

File tree

8 files changed

+110
-53
lines changed

8 files changed

+110
-53
lines changed

ast.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,9 @@ static const char *astnames[] = {
862862
"expect",
863863
"print_debug",
864864
"error_holder",
865+
866+
"signed_booltype",
867+
"unsigned_booltype",
865868
};
866869

867870
//

ast.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,9 @@ enum astkind {
243243
AST_EXPECT = 174,
244244
AST_PRINTDEBUG = 175,
245245
AST_ERRHOLDER = 176,
246-
246+
247+
AST_SIGNED_BOOLTYPE = 177,
248+
AST_UNS_BOOLTYPE = 178,
247249
};
248250

249251
/* forward reference */

expr.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,6 +2231,8 @@ IsArrayType(AST *ast)
22312231
case AST_OBJECT:
22322232
case AST_TUPLE_TYPE:
22332233
case AST_BITFIELD:
2234+
case AST_SIGNED_BOOLTYPE:
2235+
case AST_UNS_BOOLTYPE:
22342236
return 0;
22352237
case AST_TYPEOF:
22362238
return IsArrayType(ExprType(ast->left));
@@ -2316,6 +2318,8 @@ int TypeSize(AST *typ)
23162318
case AST_UNSIGNEDTYPE:
23172319
case AST_GENERICTYPE:
23182320
case AST_FLOATTYPE:
2321+
case AST_UNS_BOOLTYPE:
2322+
case AST_SIGNED_BOOLTYPE:
23192323
return EvalConstExpr(typ->left);
23202324
case AST_PTRTYPE:
23212325
case AST_REFTYPE:
@@ -2610,17 +2614,33 @@ IsIntType(AST *type)
26102614
{
26112615
type = RemoveTypeModifiers(type);
26122616
if (!type) return 0;
2613-
if (type->kind == AST_INTTYPE || type->kind == AST_UNSIGNEDTYPE)
2617+
switch (type->kind) {
2618+
case AST_INTTYPE:
2619+
case AST_UNSIGNEDTYPE:
2620+
case AST_UNS_BOOLTYPE:
2621+
case AST_SIGNED_BOOLTYPE:
26142622
return 1;
2615-
return 0;
2623+
default:
2624+
return 0;
2625+
}
26162626
}
26172627

26182628
int
26192629
IsUnsignedType(AST *type)
26202630
{
26212631
type = RemoveTypeModifiers(type);
26222632
if (!type) return 0;
2623-
if (type->kind == AST_UNSIGNEDTYPE)
2633+
if (type->kind == AST_UNSIGNEDTYPE || type->kind == AST_UNS_BOOLTYPE)
2634+
return 1;
2635+
return 0;
2636+
}
2637+
2638+
int
2639+
IsBoolType(AST *type)
2640+
{
2641+
type = RemoveTypeModifiers(type);
2642+
if (!type) return 0;
2643+
if (type->kind == AST_UNS_BOOLTYPE || type->kind == AST_SIGNED_BOOLTYPE)
26242644
return 1;
26252645
return 0;
26262646
}
@@ -2656,6 +2676,8 @@ IsBoolCompatibleType(AST *type)
26562676
case AST_UNSIGNEDTYPE:
26572677
case AST_PTRTYPE:
26582678
case AST_GENERICTYPE:
2679+
case AST_UNS_BOOLTYPE:
2680+
case AST_SIGNED_BOOLTYPE:
26592681
return 1;
26602682
default:
26612683
return 0;
@@ -3360,8 +3382,8 @@ CompatibleTypes(AST *A, AST *B)
33603382
return CompatibleTypes(B->left, A);
33613383
}
33623384

3363-
if (A->kind == AST_INTTYPE || A->kind == AST_UNSIGNEDTYPE || A->kind == AST_GENERICTYPE) {
3364-
if (B->kind == AST_INTTYPE || B->kind == AST_UNSIGNEDTYPE || B->kind == AST_GENERICTYPE) {
3385+
if (A->kind == AST_INTTYPE || A->kind == AST_UNSIGNEDTYPE || A->kind == AST_GENERICTYPE || A->kind == AST_UNS_BOOLTYPE || A->kind == AST_SIGNED_BOOLTYPE) {
3386+
if (B->kind == AST_INTTYPE || B->kind == AST_UNSIGNEDTYPE || B->kind == AST_GENERICTYPE || B->kind == AST_UNS_BOOLTYPE || B->kind == AST_SIGNED_BOOLTYPE) {
33653387
return true;
33663388
}
33673389
}

expr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ int IsUnsignedType(AST *typ);
9595
int IsGenericType(AST *typ);
9696
int IsPointerType(AST *typ);
9797
int IsRefType(AST *typ);
98+
int IsBoolType(AST *typ);
9899

99100
int IsInt64Type(AST *typ);
100101
int IsFloat64Type(AST *typ);

frontends/c/cgram.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1621,7 +1621,7 @@ type_specifier
16211621
| C_CHAR
16221622
{ $$ = ast_type_byte; }
16231623
| C_BOOL
1624-
{ $$ = ast_type_byte; }
1624+
{ $$ = ast_type_c_boolean; }
16251625
| C_SHORT
16261626
{ $$ = ast_type_signed_word; }
16271627
| C_INT

frontends/common.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ AST *ast_type_word, *ast_type_long, *ast_type_byte;
9393
AST *ast_type_signed_word, *ast_type_signed_byte;
9494
AST *ast_type_unsigned_long;
9595
AST *ast_type_float, *ast_type_string;
96+
AST *ast_type_c_boolean, *ast_type_basic_boolean;
9697
AST *ast_type_ptr_long;
9798
AST *ast_type_ptr_word;
9899
AST *ast_type_ptr_byte;
@@ -1048,6 +1049,9 @@ Init()
10481049
ast_type_signed_word = NewAST(AST_INTTYPE, AstInteger(2), NULL);
10491050
ast_type_signed_byte = NewAST(AST_INTTYPE, AstInteger(1), NULL);
10501051

1052+
ast_type_c_boolean = NewAST(AST_UNS_BOOLTYPE, AstInteger(4), NULL);
1053+
ast_type_basic_boolean = NewAST(AST_SIGNED_BOOLTYPE, AstInteger(4), NULL);
1054+
10511055
ast_type_float = NewAST(AST_FLOATTYPE, AstInteger(4), NULL);
10521056
ast_type_float64 = NewAST(AST_FLOATTYPE, AstInteger(8), NULL);
10531057

frontends/common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@ extern int gl_tab_stops;
322322
extern AST *ast_type_long;
323323
extern AST *ast_type_word;
324324
extern AST *ast_type_byte;
325+
extern AST *ast_type_c_boolean;
326+
extern AST *ast_type_basic_boolean;
325327
extern AST *ast_type_unsigned_long;
326328
extern AST *ast_type_signed_word;
327329
extern AST *ast_type_signed_byte;

frontends/types.c

Lines changed: 69 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,39 @@ bool VerifyIntegerType(AST *astForError, AST *typ, const char *opname)
135135
return false;
136136
}
137137

138+
/*
139+
* check the current boolean type
140+
*/
141+
AST *
142+
CurBoolType()
143+
{
144+
int language = GetCurrentLang();
145+
if (IsCLang(language)) {
146+
return ast_type_c_boolean;
147+
}
148+
return ast_type_basic_boolean;
149+
}
150+
151+
/*
152+
* provide a result for unordered comparisons
153+
* like NaN = NaN
154+
*/
155+
static int
156+
UnorderedResult(int op)
157+
{
158+
switch (op) {
159+
case '>':
160+
case K_GE:
161+
return -1;
162+
case '<':
163+
case K_LE:
164+
case K_EQ:
165+
case K_NE:
166+
default:
167+
return 1;
168+
}
169+
}
170+
138171
// create a call to function func with parameters ast->left, ast->right
139172
// there is an optional 3rd argument too
140173
static AST *
@@ -407,30 +440,34 @@ domakefloat(AST *typ, AST *ast)
407440
}
408441

409442
static AST *
410-
dofloatToInt(AST *ast, AST *typ)
443+
dofloatToInt(AST *ast, AST *srctyp, AST *dsttyp)
411444
{
412445
AST *ret;
413446

414-
if (gl_fixedreal) {
447+
if (IsBoolType(dsttyp)) {
448+
ret = AstOperator(K_NE, NULL, NULL);
449+
if (gl_fixedreal) {
450+
ret->left = ast;
451+
} else {
452+
ret->left = MakeOperatorCall(float_cmp, ast, AstInteger(0), AstInteger(UnorderedResult(K_NE)));
453+
}
454+
ret->right = AstInteger(0);
455+
} else if (gl_fixedreal) {
415456
// FIXME: should we round here??
416457
ret = AstOperator(K_SAR, ast, AstInteger(G_FIXPOINT));
417-
return ret;
418-
}
419-
if (IsFloat64Type(typ)) {
420-
ast = MakeOperatorCall(double_toint, ast, NULL, NULL);
421-
return ast;
422-
}
423-
if (IsConstExpr(ast)) {
458+
} else if (IsFloat64Type(srctyp)) {
459+
ret = MakeOperatorCall(double_toint, ast, NULL, NULL);
460+
} else if (IsConstExpr(ast)) {
424461
union f_or_i {
425462
float floatbits;
426463
int intbits;
427464
} g;
428465
g.intbits = EvalConstExpr(ast);
429-
ast = AstInteger((int)g.floatbits);
466+
ret = AstInteger((int)g.floatbits);
430467
} else {
431-
ast = MakeOperatorCall(float_toint, ast, NULL, NULL);
468+
ret = MakeOperatorCall(float_toint, ast, NULL, NULL);
432469
}
433-
return ast;
470+
return ret;
434471
}
435472

436473
static AST *
@@ -453,11 +490,11 @@ dofloatToDouble(AST *ast, AST *typ)
453490
bool MakeBothIntegers(AST *ast, AST *ltyp, AST *rtyp, const char *opname)
454491
{
455492
if (IsFloatType(ltyp)) {
456-
ast->left = dofloatToInt(ast->left, ltyp);
493+
ast->left = dofloatToInt(ast->left, ltyp, ast_type_long);
457494
ltyp = ast_type_long;
458495
}
459496
if (IsFloatType(rtyp)) {
460-
ast->right = dofloatToInt(ast->right, rtyp);
497+
ast->right = dofloatToInt(ast->right, rtyp, ast_type_long);
461498
rtyp = ast_type_long;
462499
}
463500
return VerifyIntegerType(ast, ltyp, opname) && VerifyIntegerType(ast, rtyp, opname);
@@ -478,11 +515,11 @@ HandleTwoNumerics(int op, AST *ast, AST *lefttype, AST *righttype)
478515
if (op == K_MODULUS) {
479516
// MOD operator converts float operands to integer
480517
if (IsFloatType(lefttype)) {
481-
ast->left = dofloatToInt(ast->left, lefttype);
518+
ast->left = dofloatToInt(ast->left, lefttype, ast_type_long);
482519
lefttype = ast_type_long;
483520
}
484521
if (IsFloatType(righttype)) {
485-
ast->right = dofloatToInt(ast->right, righttype);
522+
ast->right = dofloatToInt(ast->right, righttype, ast_type_long);
486523
righttype = ast_type_long;
487524
}
488525
}
@@ -733,26 +770,6 @@ IsBasicString(AST *typ)
733770
return 0;
734771
}
735772

736-
/*
737-
* provide a result for unordered comparisons
738-
* like NaN = NaN
739-
*/
740-
static int
741-
UnorderedResult(int op)
742-
{
743-
switch (op) {
744-
case '>':
745-
case K_GE:
746-
return -1;
747-
case '<':
748-
case K_LE:
749-
case K_EQ:
750-
case K_NE:
751-
default:
752-
return 1;
753-
}
754-
}
755-
756773
void CompileComparison(int op, AST *ast, AST *lefttype, AST *righttype)
757774
{
758775
int isfloat = 0;
@@ -853,7 +870,9 @@ void CompileComparison(int op, AST *ast, AST *lefttype, AST *righttype)
853870
int lsize = TypeSize(lefttype);
854871
int rsize = TypeSize(righttype);
855872
if (lsize == 4 && rsize == 4 && op != K_EQ && op != K_NE) {
856-
WARNING(ast, "signed/unsigned comparison may not work properly");
873+
if (!IsBoolType(lefttype) && !IsBoolType(righttype)) {
874+
WARNING(ast, "signed/unsigned comparison may not work properly");
875+
}
857876
}
858877
}
859878
}
@@ -982,11 +1001,11 @@ AST *CoerceOperatorTypes(AST *ast, AST *lefttype, AST *righttype)
9821001
case K_SAR:
9831002
case K_SHL:
9841003
if (lefttype && IsFloatType(lefttype)) {
985-
ast->left = dofloatToInt(ast->left, lefttype);
1004+
ast->left = dofloatToInt(ast->left, lefttype, ast_type_long);
9861005
lefttype = ExprType(ast->left);
9871006
}
9881007
if (righttype && IsFloatType(righttype)) {
989-
ast->right = dofloatToInt(ast->right, righttype);
1008+
ast->right = dofloatToInt(ast->right, righttype, ast_type_long);
9901009
righttype = ExprType(ast->right);
9911010
}
9921011
if (ast->d.ival == K_SAR && lefttype && IsUnsignedType(lefttype)) {
@@ -1068,8 +1087,12 @@ AST *CoerceOperatorTypes(AST *ast, AST *lefttype, AST *righttype)
10681087
case K_NE:
10691088
case K_GE:
10701089
case '>':
1090+
case K_LTU:
1091+
case K_LEU:
1092+
case K_GTU:
1093+
case K_GEU:
10711094
CompileComparison(ast->d.ival, ast, lefttype, righttype);
1072-
return ast_type_long;
1095+
return CurBoolType();
10731096
case K_NEGATE:
10741097
case K_ABS:
10751098
case K_SQRT:
@@ -1179,19 +1202,19 @@ AST *CoerceOperatorTypes(AST *ast, AST *lefttype, AST *righttype)
11791202
if (IsFloatType(lefttype)) {
11801203
isfloat64 = IsFloat64Type(lefttype);
11811204
ast->left = MakeOperatorCall(isfloat64 ? double_cmp : float_cmp, ast->left, AstInteger(0), AstInteger(1));
1182-
lefttype = ast_type_long;
1205+
lefttype = CurBoolType();
11831206
}
11841207
if (IsFloatType(righttype)) {
11851208
isfloat64 = IsFloat64Type(righttype);
11861209
ast->right = MakeOperatorCall(isfloat64 ? double_cmp : float_cmp, ast->right, AstInteger(0), AstInteger(1));
1187-
righttype = ast_type_long;
1210+
righttype = CurBoolType();
11881211
}
11891212
if (lefttype && !IsBoolCompatibleType(lefttype)) {
11901213
ERROR(ast, "Expression not compatible with boolean operation");
11911214
} else if (righttype && !IsBoolCompatibleType(righttype)) {
11921215
ERROR(ast, "Expression not compatible with boolean operation");
11931216
}
1194-
return ast_type_long;
1217+
return CurBoolType();
11951218
case K_INCREMENT:
11961219
case K_DECREMENT:
11971220
if ( (lefttype && IsConstType(lefttype) )
@@ -1292,7 +1315,7 @@ AST *CoerceAssignTypes(AST *line, int kind, AST **astptr, AST *desttype, AST *sr
12921315
if (!astptr) {
12931316
ERROR(line, "Unable to convert float function result to integer");
12941317
} else {
1295-
expr = dofloatToInt(expr, srctype);
1318+
expr = dofloatToInt(expr, srctype, desttype);
12961319
*astptr = expr;
12971320
}
12981321
AstReportDone(&saveinfo);
@@ -1475,7 +1498,7 @@ doCast(AST *desttype, AST *srctype, AST *src)
14751498
}
14761499
if (IsPointerType(desttype) || IsGenericType(desttype)) {
14771500
if (IsFloatType(srctype)) {
1478-
src = dofloatToInt(src, srctype);
1501+
src = dofloatToInt(src, srctype, ast_type_long);
14791502
srctype = ast_type_long;
14801503
}
14811504
if (IsArrayType(srctype)) {
@@ -1534,7 +1557,7 @@ doCast(AST *desttype, AST *srctype, AST *src)
15341557
}
15351558
if (IsIntType(desttype)) {
15361559
if (IsFloatType(srctype)) {
1537-
src = dofloatToInt(src, srctype);
1560+
src = dofloatToInt(src, srctype, ast_type_long);
15381561
srctype = ast_type_long;
15391562
}
15401563
if (IsPointerType(srctype)) {

0 commit comments

Comments
 (0)