From ebb3ec592ab8337941607488ccece12aa8bc4942 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 15 Nov 2024 12:36:08 +0900 Subject: [PATCH] [qfcc] Implement bool and lbool types Since spir-v needs actual bools for its conditional instructions, the time to do bool properly finally came. As expected, the changes caused quite a mess, but Ruamoko now does bool/true/false. --- libs/video/renderer/vulkan/vkgen/vkgen.r | 2 +- libs/video/renderer/vulkan/vkgen/vkstruct.r | 16 +- ruamoko/cl_menu/MenuGroup.r | 8 +- ruamoko/cl_menu/ProxyView.r | 2 +- ruamoko/cl_menu/client_menu.r | 58 ++--- ruamoko/cl_menu/menu.h | 2 +- ruamoko/cl_menu/menu.r | 2 +- ruamoko/cl_menu/options.r | 12 +- ruamoko/gatest/main.r | 2 +- ruamoko/gui/View.r | 4 +- ruamoko/include/gui/Slider.h | 2 +- ruamoko/include/gui/View.h | 2 +- ruamoko/qwaq/debugger/views/pointerview.h | 2 +- ruamoko/qwaq/debugger/views/pointerview.r | 2 +- ruamoko/qwaq/ui/scrollbar.h | 2 +- tools/qfcc/include/expr.h | 7 +- tools/qfcc/include/struct.h | 4 +- tools/qfcc/include/type.h | 2 + tools/qfcc/source/expr.c | 31 ++- tools/qfcc/source/expr_binary.c | 242 +++++++++++--------- tools/qfcc/source/expr_bool.c | 21 +- tools/qfcc/source/expr_cast.c | 18 ++ tools/qfcc/source/expr_unary.c | 31 ++- tools/qfcc/source/qc-lex.l | 1 + tools/qfcc/source/qc-parse.y | 17 ++ tools/qfcc/source/qp-parse.y | 5 +- tools/qfcc/source/struct.c | 8 +- tools/qfcc/source/switch.c | 2 +- tools/qfcc/source/type.c | 58 ++++- tools/qfcc/test/const-fold-int.r | 2 +- tools/qfcc/test/double.r | 18 +- tools/qfcc/test/structstruct.r | 2 +- 32 files changed, 381 insertions(+), 206 deletions(-) diff --git a/libs/video/renderer/vulkan/vkgen/vkgen.r b/libs/video/renderer/vulkan/vkgen/vkgen.r index 0f4800195..8b2c609bc 100644 --- a/libs/video/renderer/vulkan/vkgen/vkgen.r +++ b/libs/video/renderer/vulkan/vkgen/vkgen.r @@ -53,7 +53,7 @@ next_type (qfot_type_t *type) return (qfot_type_t *) ((int *) type + size); } -int +bool type_is_null (qfot_type_t *type) { return type.size == 0; diff --git a/libs/video/renderer/vulkan/vkgen/vkstruct.r b/libs/video/renderer/vulkan/vkgen/vkstruct.r index 364bcf96d..ea1c4c72a 100644 --- a/libs/video/renderer/vulkan/vkgen/vkstruct.r +++ b/libs/video/renderer/vulkan/vkgen/vkstruct.r @@ -43,7 +43,7 @@ { qfot_struct_t *strct =&type.strct; PLItem *field_dict = [parse getObjectForKey:[self name]]; - int readonly = [field_dict string] == "readonly"; + bool readonly = [field_dict string] == "readonly"; if (readonly) { return; @@ -103,7 +103,7 @@ -(void) writeForward { PLItem *field_dict = [parse getObjectForKey:[self name]]; - int readonly = [field_dict string] == "readonly"; + bool readonly = [field_dict string] == "readonly"; if (!readonly) { fprintf (output_file, "static int %s (const plfield_t *field," " const plitem_t *item, void *data, plitem_t *messages," @@ -255,7 +255,7 @@ write_type (Struct *self, PLItem *field_dict, string type) } static void -write_parser (Struct *self, int have_sType, PLItem *only) +write_parser (Struct *self, bool have_sType, PLItem *only) { write_function_head (self); if (have_sType) { @@ -342,17 +342,17 @@ write_table (Struct *self, PLItem *field_dict, Array *field_defs, PLItem *only, int need_parser) { qfot_type_t *type = self.type; - int have_sType = 0; - int have_pNext = 0; - int readonly = [field_dict string] == "readonly"; + bool have_sType = false; + bool have_pNext = false; + bool readonly = [field_dict string] == "readonly"; for (int i = 0; i < type.strct.num_fields; i++) { qfot_var_t *field = &type.strct.fields[i]; if (field.name == "sType") { - have_sType = 1; + have_sType = true; } if (field.name == "pNext") { - have_pNext = 1; + have_pNext = true; self.write_symtab = 1; } } diff --git a/ruamoko/cl_menu/MenuGroup.r b/ruamoko/cl_menu/MenuGroup.r index 246108610..6733e6b06 100644 --- a/ruamoko/cl_menu/MenuGroup.r +++ b/ruamoko/cl_menu/MenuGroup.r @@ -23,20 +23,20 @@ current = base = b; } -- (int) keyEvent:(int)key unicode:(int)unicode down:(int)down +- (bool) keyEvent:(int)key unicode:(int)unicode down:(bool)down { View *cur = [views objectAtIndex: current]; - int ret = [cur keyEvent: key unicode: unicode down: down]; + bool ret = [cur keyEvent: key unicode: unicode down: down]; if (!ret) { switch (key) { case QFK_DOWN: //case QFM_WHEEL_DOWN: [self next]; - return 1; + return true; case QFK_UP: //case QFM_WHEEL_UP: [self prev]; - return 1; + return true; } } return ret; diff --git a/ruamoko/cl_menu/ProxyView.r b/ruamoko/cl_menu/ProxyView.r index 327629fb7..546738163 100644 --- a/ruamoko/cl_menu/ProxyView.r +++ b/ruamoko/cl_menu/ProxyView.r @@ -13,7 +13,7 @@ return self; } -- (int) keyEvent:(int)key unicode:(int)unicode down:(int)down +- (bool) keyEvent:(int)key unicode:(int)unicode down:(bool)down { return [view keyEvent:key unicode:unicode down:down]; } diff --git a/ruamoko/cl_menu/client_menu.r b/ruamoko/cl_menu/client_menu.r index 591d1d4ec..1c7296553 100644 --- a/ruamoko/cl_menu/client_menu.r +++ b/ruamoko/cl_menu/client_menu.r @@ -42,7 +42,7 @@ menu_leave_sound = S_LocalSound ("misc/menu2.wav"); } -int (int key, int unicode, int down) +bool (int key, int unicode, bool down) menu_key_sound = { switch (key) { @@ -55,7 +55,7 @@ menu_key_sound = S_LocalSound ("misc/menu1.wav"); break; } - return 0; + return false; } void (int x, int y) spinner = @@ -227,7 +227,7 @@ int (int x, int y) save_draw = return 1; }; -int (int key, int unicode, int down) load_quickbup_keyevent = +bool (int key, int unicode, bool down) load_quickbup_keyevent = { switch (key) { case QFK_DOWN: @@ -235,13 +235,13 @@ int (int key, int unicode, int down) load_quickbup_keyevent = S_LocalSound ("misc/menu1.wav"); load_cursor++; load_cursor %= MAX_QUICK; - return 1; + return true; case QFK_UP: //case QFM_WHEEL_UP: S_LocalSound ("misc/menu1.wav"); load_cursor += MAX_QUICK - 1; load_cursor %= MAX_QUICK; - return 1; + return true; case QFK_RETURN: //case QFM_BUTTON1: if (loadable[load_cursor]) { @@ -250,12 +250,12 @@ int (int key, int unicode, int down) load_quickbup_keyevent = Cbuf_AddText (nil, sprintf ("load quick%i.sav\n", load_cursor)); load_cursor = MAX_SAVEGAMES; } - return 1; + return true; } - return 0; + return false; }; -int (int key, int unicode, int down) load_keyevent = +bool (int key, int unicode, bool down) load_keyevent = { switch (key) { case QFK_DOWN: @@ -263,13 +263,13 @@ int (int key, int unicode, int down) load_keyevent = S_LocalSound ("misc/menu1.wav"); load_cursor++; load_cursor %= MAX_SAVEGAMES + 1; - return 1; + return true; case QFK_UP: //case QFM_WHEEL_UP: S_LocalSound ("misc/menu1.wav"); load_cursor += MAX_SAVEGAMES; load_cursor %= MAX_SAVEGAMES + 1; - return 1; + return true; case QFK_RETURN: //case QFM_BUTTON1: if (load_cursor == MAX_SAVEGAMES) { @@ -281,12 +281,12 @@ int (int key, int unicode, int down) load_keyevent = Menu_SelectMenu (nil); Cbuf_AddText (nil, sprintf ("load s%i.sav\n", load_cursor)); } - return 1; + return true; } - return 0; + return false; }; -int (int key, int unicode, int down) save_keyevent = +bool (int key, int unicode, bool down) save_keyevent = { switch (key) { case QFK_DOWN: @@ -294,20 +294,20 @@ int (int key, int unicode, int down) save_keyevent = S_LocalSound ("misc/menu1.wav"); save_cursor++; save_cursor %= MAX_SAVEGAMES; - return 1; + return true; case QFK_UP: //case QFM_WHEEL_UP: S_LocalSound ("misc/menu1.wav"); save_cursor += MAX_SAVEGAMES - 1; save_cursor %= MAX_SAVEGAMES; - return 1; + return true; case QFK_RETURN: //case QFM_BUTTON1: Menu_SelectMenu (nil); Cbuf_AddText (nil, sprintf ("save s%i.sav\n", save_cursor)); - return 1; + return true; } - return 0; + return false; }; void () load_quickbup_menu = @@ -361,17 +361,17 @@ int (string text, int key) quit_f = return 0; }; -int (int key, int unicode, int down) quit_keyevent = +bool (int key, int unicode, bool down) quit_keyevent = { if (key == 'y') { Menu_Quit (); - return 1; + return true; } if (key == 'n') { Menu_SelectMenu (nil); - return 1; + return true; } - return 0; + return false; }; int (int x, int y) quit_draw = @@ -429,7 +429,7 @@ void () single_player_menu = // ********* MULTIPLAYER -int JoiningGame; +bool JoiningGame; int lanConfig_cursor; string my_tcpip_address; string lanConfig_portname; @@ -488,7 +488,7 @@ int (int x, int y) lanconfig_draw = return 0; }; -int (int key, int unicode, int down) lanconfig_keyevent = +bool (int key, int unicode, bool down) lanconfig_keyevent = { if (input_active) [input_active processInput:(key >= 256 ? key : unicode)]; @@ -500,7 +500,7 @@ int (int key, int unicode, int down) lanconfig_keyevent = lanConfig_cursor ++; lanConfig_cursor %= NUM_LANCONFIG_CMDS; } - return 1; + return true; case QFK_UP: //case QFM_WHEEL_UP: if (!input_active) { @@ -508,7 +508,7 @@ int (int key, int unicode, int down) lanconfig_keyevent = lanConfig_cursor += NUM_LANCONFIG_CMDS - 1; lanConfig_cursor %= NUM_LANCONFIG_CMDS; } - return 1; + return true; case QFK_RETURN: if (input_active) { input_active = nil; @@ -521,9 +521,9 @@ int (int key, int unicode, int down) lanconfig_keyevent = } } } - return 1; + return true; } - return 0; + return false; }; void () lanconfig_menu = @@ -558,12 +558,12 @@ void () join_menu = Menu_End (); }; -int (int key, int unicode, int down) multi_player_keyevent = +bool (int key, int unicode, bool down) multi_player_keyevent = { if (key == QFK_RETURN) { JoiningGame = (Menu_GetIndex () == 0); } - return 0; + return false; }; void () multi_player_menu = diff --git a/ruamoko/cl_menu/menu.h b/ruamoko/cl_menu/menu.h index 7746fb922..d2a0c501c 100644 --- a/ruamoko/cl_menu/menu.h +++ b/ruamoko/cl_menu/menu.h @@ -16,7 +16,7 @@ int (func)(string text, int key), int allkeys); @extern void Menu_Cursor (void (func)(int x, int y)); -@extern void Menu_KeyEvent (int (func)(int key, int unicode, int down)); +@extern void Menu_KeyEvent (bool (func)(int key, int unicode, bool down)); @extern void Menu_End (void); @extern void Menu_TopMenu (string name); @extern void Menu_SelectMenu (string name); diff --git a/ruamoko/cl_menu/menu.r b/ruamoko/cl_menu/menu.r index a47650a42..cf11866e9 100644 --- a/ruamoko/cl_menu/menu.r +++ b/ruamoko/cl_menu/menu.r @@ -11,7 +11,7 @@ void (int x, int y, string name) Menu_CenterPic = #0; void (int x, int y, string name, int srcx, int srcy, int width, int height) Menu_CenterSubPic = #0; void (int x, int y, string text, int (string text, int key) func, int allkeys) Menu_Item = #0; void (void (int x, int y) func) Menu_Cursor = #0; -void (int (int key, int unicode, int down) func) Menu_KeyEvent = #0; +void (bool (int key, int unicode, bool down) func) Menu_KeyEvent = #0; void () Menu_End = #0; void (string name) Menu_TopMenu = #0; void (string name) Menu_SelectMenu = #0; diff --git a/ruamoko/cl_menu/options.r b/ruamoko/cl_menu/options.r index 2becb89e1..095a1a0db 100644 --- a/ruamoko/cl_menu/options.r +++ b/ruamoko/cl_menu/options.r @@ -107,7 +107,7 @@ DRAW_video_options = return 1; }; -int (int key, int unicode, int down) +bool (int key, int unicode, bool down) KEY_video_options = { return [video_options keyEvent:key unicode:unicode down:down]; @@ -154,7 +154,7 @@ DRAW_audio_options = return 1; }; -int (int key, int unicode, int down) +bool (int key, int unicode, bool down) KEY_audio_options = { return [audio_options keyEvent:key unicode:unicode down:down]; @@ -201,7 +201,7 @@ DRAW_control_options = return 0; }; -int (int key, int unicode, int down) +bool (int key, int unicode, bool down) KEY_control_options = { return [control_options keyEvent:key unicode:unicode down:down]; @@ -251,7 +251,7 @@ DRAW_feature_options = return 1; }; -int (int key, int unicode, int down) +bool (int key, int unicode, bool down) KEY_feature_options = { return [feature_options keyEvent:key unicode:unicode down:down]; @@ -313,7 +313,7 @@ string player_config_vals[NUM_PLAYERCONFIG_CMDS] = { }; -int (int key, int unicode, int down) +bool (int key, int unicode, bool down) KEY_player_options = { return [player_options keyEvent:key unicode:unicode down:down]; @@ -390,7 +390,7 @@ string network_config_vals[NUM_NETWORKCONFIG_CMDS] = { }; -int (int key, int unicode, int down) +bool (int key, int unicode, bool down) KEY_network_options = { return [network_options keyEvent:key unicode:unicode down:down]; diff --git a/ruamoko/gatest/main.r b/ruamoko/gatest/main.r index e46e36500..436abbb1a 100644 --- a/ruamoko/gatest/main.r +++ b/ruamoko/gatest/main.r @@ -208,7 +208,7 @@ syntax_error () Script_GetLine (script)); } -static int +static bool match (token_e token) { if (lookahead == -1) { diff --git a/ruamoko/gui/View.r b/ruamoko/gui/View.r index a83ebeb33..52eaa111b 100644 --- a/ruamoko/gui/View.r +++ b/ruamoko/gui/View.r @@ -61,9 +61,9 @@ { } -- (int) keyEvent:(int)key unicode:(int)unicode down:(int)down +- (bool) keyEvent:(int)key unicode:(int)unicode down:(bool)down { - return 0; + return false; } @end diff --git a/ruamoko/include/gui/Slider.h b/ruamoko/include/gui/Slider.h index 99840af7e..24099fd15 100644 --- a/ruamoko/include/gui/Slider.h +++ b/ruamoko/include/gui/Slider.h @@ -10,7 +10,7 @@ { int index; int size; - int dir; + bool dir; } - (id) initWithBounds: (Rect)aRect size: (int) aSize; diff --git a/ruamoko/include/gui/View.h b/ruamoko/include/gui/View.h index 3cb51ee67..b1f467106 100644 --- a/ruamoko/include/gui/View.h +++ b/ruamoko/include/gui/View.h @@ -31,7 +31,7 @@ - (void) setBasePosFromView: (View*)view; - (void) draw; -- (int) keyEvent:(int)key unicode:(int)unicode down:(int)down; +- (bool) keyEvent:(int)key unicode:(int)unicode down:(bool)down; @end ///@} diff --git a/ruamoko/qwaq/debugger/views/pointerview.h b/ruamoko/qwaq/debugger/views/pointerview.h index 2e314a735..ccf49c22c 100644 --- a/ruamoko/qwaq/debugger/views/pointerview.h +++ b/ruamoko/qwaq/debugger/views/pointerview.h @@ -6,7 +6,7 @@ @interface PointerView : DefView { unsigned *data; - int invalid; + bool invalid; unsigned ptr; qfot_type_t *ptr_type; int ptr_size; diff --git a/ruamoko/qwaq/debugger/views/pointerview.r b/ruamoko/qwaq/debugger/views/pointerview.r index f82c099e3..b2c8e30c1 100644 --- a/ruamoko/qwaq/debugger/views/pointerview.r +++ b/ruamoko/qwaq/debugger/views/pointerview.r @@ -49,7 +49,7 @@ in:ptr_data target:target] retain]; } - invalid = 1; + invalid = true; if (!ptr_view || ptr != (unsigned) data[0]) { invalid = qdb_get_data (target, data[0], ptr_size, ptr_data) < 0; } diff --git a/ruamoko/qwaq/ui/scrollbar.h b/ruamoko/qwaq/ui/scrollbar.h index c1ed0d47a..10abafd2d 100644 --- a/ruamoko/qwaq/ui/scrollbar.h +++ b/ruamoko/qwaq/ui/scrollbar.h @@ -10,7 +10,7 @@ @interface ScrollBar : View { - int vertical; + bool vertical; int bgchar; double mouseTime; Point mouseStart; diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 747a90592..f3b786300 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -521,8 +521,8 @@ expr_t *new_label_ref (const ex_label_t *label); expr_t *new_state_expr (const expr_t *frame, const expr_t *think, const expr_t *step); -expr_t *new_bool_expr (ex_boollist_t *true_list, ex_boollist_t *false_list, - const expr_t *e); +expr_t *new_boolean_expr (ex_boollist_t *true_list, ex_boollist_t *false_list, + const expr_t *e); /** Create a new statement block expression node. @@ -759,6 +759,9 @@ const expr_t *new_pointer_expr (int val, const type_t *type, struct def_s *def); const expr_t *new_quaternion_expr (const float *quaternion_val); const float *expr_quaternion (const expr_t *e) __attribute__((pure)); +const expr_t *new_bool_expr (bool bool_val); +const expr_t *new_lbool_expr (bool lbool_val); + /** Create a new itn constant expression node. \param int_val The int constant being represented. diff --git a/tools/qfcc/include/struct.h b/tools/qfcc/include/struct.h index 255bd430e..01a00ccf5 100644 --- a/tools/qfcc/include/struct.h +++ b/tools/qfcc/include/struct.h @@ -57,8 +57,8 @@ struct symtab_s *start_enum (struct symbol_s *enm); struct symbol_s *finish_enum (struct symbol_s *sym); void add_enum (struct symbol_s *enm, struct symbol_s *name, const struct expr_s *val); -int enum_as_bool (const type_t *enm, struct expr_s **zero, - struct expr_s **one); +bool enum_as_bool (const type_t *enm, struct expr_s **zero, + struct expr_s **one); struct symbol_s *make_structure (const char *name, int su, struct_def_t *defs, const type_t *type); diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index 56894dbe9..89aeb6303 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -233,6 +233,8 @@ bool is_pointer (const type_t *type) __attribute__((pure)); bool is_reference (const type_t *type) __attribute__((pure)); bool is_enum (const type_t *type) __attribute__((pure)); bool is_bool (const type_t *type) __attribute__((pure)); +bool is_lbool (const type_t *type) __attribute__((pure)); +bool is_boolean (const type_t *type) __attribute__((pure)); bool is_signed (const type_t *type) __attribute__((pure)); bool is_unsigned (const type_t *type) __attribute__((pure)); bool is_integral (const type_t *type) __attribute__((pure)); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index b3e6146cc..6c5a3611f 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -493,7 +493,8 @@ new_state_expr (const expr_t *frame, const expr_t *think, const expr_t *step) } expr_t * -new_bool_expr (ex_boollist_t *true_list, ex_boollist_t *false_list, const expr_t *e) +new_boolean_expr (ex_boollist_t *true_list, ex_boollist_t *false_list, + const expr_t *e) { expr_t *b = new_expr (); @@ -640,7 +641,8 @@ new_horizontal_expr (int op, const expr_t *vec, type_t *type) return (expr_t *) vec; } auto vec_type = get_type (vec); - if (!is_math (vec_type) || is_scalar (vec_type)) { + if (!(is_math (vec_type) || is_boolean (vec_type)) + || is_scalar (vec_type)) { internal_error (vec, "horizontal operand not a vector type"); } if (!is_scalar (type)) { @@ -864,6 +866,25 @@ new_quaternion_expr (const float *quaternion_val) return new_value_expr (new_quaternion_val (quaternion_val), false); } +const expr_t * +new_bool_expr (bool bool_val) +{ + pr_type_t data = { .value = -bool_val }; + auto val = new_type_value (&type_bool, &data); + return new_value_expr (val, false); +} + +const expr_t * +new_lbool_expr (bool lbool_val) +{ + pr_type_t data[2] = { + { .value = -lbool_val }, + { .value = -lbool_val }, + }; + auto val = new_type_value (&type_lbool, data); + return new_value_expr (val, false); +} + const expr_t * new_int_expr (int int_val, bool implicit) { @@ -1827,6 +1848,12 @@ convert_from_bool (const expr_t *e, const type_t *type) } else if (is_int (type)) { one = new_int_expr (1, false); zero = new_int_expr (0, false); + } else if (is_bool (type)) { + one = new_bool_expr (1); + zero = new_bool_expr (0); + } else if (is_lbool (type)) { + one = new_lbool_expr (1); + zero = new_lbool_expr (0); } else if (is_enum (type) && enum_as_bool (type, &enum_zero, &enum_one)) { zero = enum_zero; one = enum_one; diff --git a/tools/qfcc/source/expr_binary.c b/tools/qfcc/source/expr_binary.c index 293bee684..5494b7c92 100644 --- a/tools/qfcc/source/expr_binary.c +++ b/tools/qfcc/source/expr_binary.c @@ -110,12 +110,12 @@ static bool fp_ass_mul (void) static expr_type_t string_string[] = { {'+', &type_string}, - {QC_EQ, &type_int}, - {QC_NE, &type_int}, - {QC_LE, &type_int}, - {QC_GE, &type_int}, - {QC_LT, &type_int}, - {QC_GT, &type_int}, + {QC_EQ, &type_bool}, + {QC_NE, &type_bool}, + {QC_LE, &type_bool}, + {QC_GE, &type_bool}, + {QC_LT, &type_bool}, + {QC_GT, &type_bool}, {0, 0} }; @@ -137,14 +137,14 @@ static expr_type_t float_float[] = { {QC_MOD, &type_float}, {QC_SHL, &type_float}, {QC_SHR, &type_float}, - {QC_AND, &type_int}, - {QC_OR, &type_int}, - {QC_EQ, &type_int}, - {QC_NE, &type_int}, - {QC_LE, &type_int}, - {QC_GE, &type_int}, - {QC_LT, &type_int}, - {QC_GT, &type_int}, + {QC_AND, &type_bool}, + {QC_OR, &type_bool}, + {QC_EQ, &type_bool}, + {QC_NE, &type_bool}, + {QC_LE, &type_bool}, + {QC_GE, &type_bool}, + {QC_LT, &type_bool}, + {QC_GT, &type_bool}, {0, 0} }; @@ -176,12 +176,12 @@ static expr_type_t float_int[] = { {QC_MOD, &type_float, 0, &type_float}, {QC_SHL, &type_float, 0, &type_float}, {QC_SHR, &type_float, 0, &type_float}, - {QC_EQ, &type_int, 0, &type_float}, - {QC_NE, &type_int, 0, &type_float}, - {QC_LE, &type_int, 0, &type_float}, - {QC_GE, &type_int, 0, &type_float}, - {QC_LT, &type_int, 0, &type_float}, - {QC_GT, &type_int, 0, &type_float}, + {QC_EQ, &type_bool, 0, &type_float}, + {QC_NE, &type_bool, 0, &type_float}, + {QC_LE, &type_bool, 0, &type_float}, + {QC_GE, &type_bool, 0, &type_float}, + {QC_LT, &type_bool, 0, &type_float}, + {QC_GT, &type_bool, 0, &type_float}, {0, 0} }; #define float_uint float_int @@ -240,14 +240,14 @@ static expr_type_t vector_double[] = { }; static expr_type_t entity_entity[] = { - {QC_EQ, &type_int, 0, 0, entity_compare}, - {QC_NE, &type_int, 0, 0, entity_compare}, + {QC_EQ, &type_bool, 0, 0, entity_compare}, + {QC_NE, &type_bool, 0, 0, entity_compare}, {0, 0} }; static expr_type_t field_field[] = { - {QC_EQ, &type_int}, - {QC_NE, &type_int}, + {QC_EQ, &type_bool}, + {QC_NE, &type_bool}, {0, 0} }; @@ -335,12 +335,12 @@ static expr_type_t int_float[] = { {QC_MOD, &type_float, &type_float, 0}, {QC_SHL, &type_int, 0, &type_int}, //FIXME? {QC_SHR, &type_int, 0, &type_int}, //FIXME? - {QC_EQ, &type_int, &type_float, 0}, - {QC_NE, &type_int, &type_float, 0}, - {QC_LE, &type_int, &type_float, 0}, - {QC_GE, &type_int, &type_float, 0}, - {QC_LT, &type_int, &type_float, 0}, - {QC_GT, &type_int, &type_float, 0}, + {QC_EQ, &type_bool, &type_float, 0}, + {QC_NE, &type_bool, &type_float, 0}, + {QC_LE, &type_bool, &type_float, 0}, + {QC_GE, &type_bool, &type_float, 0}, + {QC_LT, &type_bool, &type_float, 0}, + {QC_GT, &type_bool, &type_float, 0}, {0, 0} }; @@ -377,14 +377,14 @@ static expr_type_t int_int[] = { {QC_MOD, &type_int}, {QC_SHL, &type_int}, {QC_SHR, &type_int}, - {QC_AND, &type_int}, - {QC_OR, &type_int}, - {QC_EQ, &type_int}, - {QC_NE, &type_int}, - {QC_LE, &type_int}, - {QC_GE, &type_int}, - {QC_LT, &type_int}, - {QC_GT, &type_int}, + {QC_AND, &type_bool}, + {QC_OR, &type_bool}, + {QC_EQ, &type_bool}, + {QC_NE, &type_bool}, + {QC_LE, &type_bool}, + {QC_GE, &type_bool}, + {QC_LT, &type_bool}, + {QC_GT, &type_bool}, {0, 0} }; @@ -406,8 +406,8 @@ static expr_type_t int_uint[] = { {QC_MOD, &type_int, 0, &type_int}, {QC_SHL, &type_int, 0, &type_int}, {QC_SHR, &type_int, 0, &type_int}, - {QC_EQ, &type_int, 0, &type_int}, - {QC_NE, &type_int, 0, &type_int}, + {QC_EQ, &type_bool, 0, &type_int}, + {QC_NE, &type_bool, 0, &type_int}, {QC_LE, .process = uint_compare}, {QC_GE, .process = uint_compare}, {QC_LT, .process = uint_compare}, @@ -433,12 +433,12 @@ static expr_type_t int_short[] = { {QC_MOD, &type_int, 0, &type_int}, {QC_SHL, &type_int, 0, &type_int}, {QC_SHR, &type_int, 0, &type_int}, - {QC_EQ, &type_int, 0, &type_int}, - {QC_NE, &type_int, 0, &type_int}, - {QC_LE, &type_int, 0, &type_int}, - {QC_GE, &type_int, 0, &type_int}, - {QC_LT, &type_int, 0, &type_int}, - {QC_GT, &type_int, 0, &type_int}, + {QC_EQ, &type_bool, 0, &type_int}, + {QC_NE, &type_bool, 0, &type_int}, + {QC_LE, &type_bool, 0, &type_int}, + {QC_GE, &type_bool, 0, &type_int}, + {QC_LT, &type_bool, 0, &type_int}, + {QC_GT, &type_bool, 0, &type_int}, {0, 0} }; @@ -452,12 +452,12 @@ static expr_type_t int_double[] = { {'/', &type_double, &type_double, 0}, {'%', &type_double, &type_double, 0}, {QC_MOD, &type_double, &type_double, 0}, - {QC_EQ, &type_long, &type_double, 0}, - {QC_NE, &type_long, &type_double, 0}, - {QC_LE, &type_long, &type_double, 0}, - {QC_GE, &type_long, &type_double, 0}, - {QC_LT, &type_long, &type_double, 0}, - {QC_GT, &type_long, &type_double, 0}, + {QC_EQ, &type_lbool, &type_double, 0}, + {QC_NE, &type_lbool, &type_double, 0}, + {QC_LE, &type_lbool, &type_double, 0}, + {QC_GE, &type_lbool, &type_double, 0}, + {QC_LT, &type_lbool, &type_double, 0}, + {QC_GT, &type_lbool, &type_double, 0}, {0, 0} }; @@ -484,8 +484,8 @@ static expr_type_t uint_int[] = { {QC_MOD, &type_int, &type_int, &type_int }, {QC_SHL, &type_uint, &type_int, &type_int }, {QC_SHR, &type_uint, 0, &type_int }, - {QC_EQ, &type_int, &type_int, &type_int }, - {QC_NE, &type_int, &type_int, &type_int }, + {QC_EQ, &type_bool, &type_int, &type_int }, + {QC_NE, &type_bool, &type_int, &type_int }, {QC_LE, .process = uint_compare}, {QC_GE, .process = uint_compare}, {QC_LT, .process = uint_compare}, @@ -511,8 +511,8 @@ static expr_type_t uint_uint[] = { {QC_MOD, &type_uint}, {QC_SHL, &type_uint}, {QC_SHR, &type_uint}, - {QC_EQ, &type_int, &type_int, &type_int}, - {QC_NE, &type_int, &type_int, &type_int}, + {QC_EQ, &type_bool, &type_int, &type_int}, + {QC_NE, &type_bool, &type_int, &type_int}, {QC_LE, &type_int}, {QC_GE, &type_int}, {QC_LT, &type_int}, @@ -545,12 +545,12 @@ static expr_type_t short_int[] = { {QC_MOD, &type_int, &type_int, 0}, {QC_SHL, &type_short}, {QC_SHR, &type_short}, - {QC_EQ, &type_int, &type_int, 0}, - {QC_NE, &type_int, &type_int, 0}, - {QC_LE, &type_int, &type_int, 0}, - {QC_GE, &type_int, &type_int, 0}, - {QC_LT, &type_int, &type_int, 0}, - {QC_GT, &type_int, &type_int, 0}, + {QC_EQ, &type_bool, &type_int, 0}, + {QC_NE, &type_bool, &type_int, 0}, + {QC_LE, &type_bool, &type_int, 0}, + {QC_GE, &type_bool, &type_int, 0}, + {QC_LT, &type_bool, &type_int, 0}, + {QC_GT, &type_bool, &type_int, 0}, {0, 0} }; @@ -572,12 +572,12 @@ static expr_type_t short_uint[] = { {QC_MOD, &type_uint, &type_uint, 0}, {QC_SHL, &type_short}, {QC_SHR, &type_short}, - {QC_EQ, &type_int, &type_uint, 0}, - {QC_NE, &type_int, &type_uint, 0}, - {QC_LE, &type_int, &type_uint, 0}, - {QC_GE, &type_int, &type_uint, 0}, - {QC_LT, &type_int, &type_uint, 0}, - {QC_GT, &type_int, &type_uint, 0}, + {QC_EQ, &type_bool, &type_uint, 0}, + {QC_NE, &type_bool, &type_uint, 0}, + {QC_LE, &type_bool, &type_uint, 0}, + {QC_GE, &type_bool, &type_uint, 0}, + {QC_LT, &type_bool, &type_uint, 0}, + {QC_GT, &type_bool, &type_uint, 0}, {0, 0} }; @@ -593,12 +593,12 @@ static expr_type_t short_short[] = { {QC_MOD, &type_short}, {QC_SHL, &type_short}, {QC_SHR, &type_short}, - {QC_EQ, &type_int}, - {QC_NE, &type_int}, - {QC_LE, &type_int}, - {QC_GE, &type_int}, - {QC_LT, &type_int}, - {QC_GT, &type_int}, + {QC_EQ, &type_bool}, + {QC_NE, &type_bool}, + {QC_LE, &type_bool}, + {QC_GE, &type_bool}, + {QC_LT, &type_bool}, + {QC_GT, &type_bool}, {0, 0} }; #define short_double int_double @@ -663,12 +663,12 @@ static expr_type_t double_double[] = { {'/', &type_double}, {'%', &type_double}, {QC_MOD, &type_double}, - {QC_EQ, &type_long}, - {QC_NE, &type_long}, - {QC_LE, &type_long}, - {QC_GE, &type_long}, - {QC_LT, &type_long}, - {QC_GT, &type_long}, + {QC_EQ, &type_lbool}, + {QC_NE, &type_lbool}, + {QC_LE, &type_lbool}, + {QC_GE, &type_lbool}, + {QC_LT, &type_lbool}, + {QC_GT, &type_lbool}, {0, 0} }; @@ -690,12 +690,12 @@ static expr_type_t long_long[] = { {QC_MOD, &type_long}, {QC_SHL, &type_long}, {QC_SHR, &type_long}, - {QC_EQ, &type_long}, - {QC_NE, &type_long}, - {QC_LE, &type_long}, - {QC_GE, &type_long}, - {QC_LT, &type_long}, - {QC_GT, &type_long}, + {QC_EQ, &type_lbool}, + {QC_NE, &type_lbool}, + {QC_LE, &type_lbool}, + {QC_GE, &type_lbool}, + {QC_LT, &type_lbool}, + {QC_GT, &type_lbool}, {0, 0} }; @@ -717,12 +717,12 @@ static expr_type_t ulong_ulong[] = { {QC_MOD, &type_ulong}, {QC_SHL, &type_ulong}, {QC_SHR, &type_ulong}, - {QC_EQ, &type_long}, - {QC_NE, &type_long}, - {QC_LE, &type_long}, - {QC_GE, &type_long}, - {QC_LT, &type_long}, - {QC_GT, &type_long}, + {QC_EQ, &type_lbool}, + {QC_NE, &type_lbool}, + {QC_LE, &type_lbool}, + {QC_GE, &type_lbool}, + {QC_LT, &type_lbool}, + {QC_GT, &type_lbool}, {0, 0} }; @@ -848,15 +848,15 @@ static expr_type_t **binary_expr_types[ev_type_count] = { }; static expr_type_t int_handle[] = { - {QC_EQ, &type_int}, - {QC_NE, &type_int}, + {QC_EQ, &type_bool}, + {QC_NE, &type_bool}, {0, 0} }; static expr_type_t long_handle[] = { - {QC_EQ, &type_int}, - {QC_NE, &type_int}, + {QC_EQ, &type_bool}, + {QC_NE, &type_bool}, {0, 0} }; @@ -874,11 +874,45 @@ static expr_type_t **binary_expr_handle[ev_type_count] = { [ev_long] = long_handle_x, }; +static expr_type_t int_bool[] = { + {'|', &type_bool}, + {'&', &type_bool}, + {'^', &type_bool}, + {QC_EQ, &type_bool}, + {QC_NE, &type_bool}, + + {0, 0} +}; + +static expr_type_t long_bool[] = { + {'|', &type_lbool}, + {'&', &type_lbool}, + {'^', &type_lbool}, + {QC_EQ, &type_lbool}, + {QC_NE, &type_lbool}, + + {0, 0} +}; + +static expr_type_t *int_bool_x[ev_type_count] = { + [ev_int] = int_bool, +}; + +static expr_type_t *long_bool_x[ev_type_count] = { + [ev_long] = long_bool, +}; + +static expr_type_t **binary_expr_bool[ev_type_count] = { + [ev_int] = int_bool_x, + [ev_long] = long_bool_x, +}; + static expr_type_t ***binary_expr_meta[ty_meta_count] = { [ty_basic] = binary_expr_types, [ty_enum] = binary_expr_types, [ty_alias] = binary_expr_types, [ty_handle] = binary_expr_handle, + [ty_bool] = binary_expr_bool, }; // supported operators for scalar-vector expressions @@ -968,7 +1002,7 @@ pointer_compare (int op, const expr_t *e1, const expr_t *e2) e = new_binary_expr (op, cast_expr (&type_int, e1), cast_expr (&type_int, e2)); } - e->expr.type = &type_int; + e->expr.type = &type_bool; return e; } @@ -983,7 +1017,7 @@ func_compare (int op, const expr_t *e1, const expr_t *e2) e = new_binary_expr (op, new_alias_expr (&type_int, e1), new_alias_expr (&type_int, e2)); } - e->expr.type = &type_int; + e->expr.type = &type_bool; if (options.code.progsversion == PROG_ID_VERSION) { e->expr.type = &type_float; } @@ -1014,7 +1048,7 @@ vector_compare (int op, const expr_t *e1, const expr_t *e2) e1 = new_alias_expr (&type_vec3, e1); e2 = new_alias_expr (&type_vec3, e2); expr_t *e = new_binary_expr (op, e1, e2); - e->expr.type = &type_ivec3; + e->expr.type = &type_bvec3; return new_horizontal_expr (hop, e, &type_int); } @@ -1023,14 +1057,14 @@ quat_compare (int op, const expr_t *e1, const expr_t *e2) { if (options.code.progsversion < PROG_VERSION) { expr_t *e = new_binary_expr (op, e1, e2); - e->expr.type = &type_int; + e->expr.type = &type_bool; return e; } int hop = op == QC_EQ ? '&' : '|'; e1 = new_alias_expr (&type_vec4, e1); e2 = new_alias_expr (&type_vec4, e2); expr_t *e = new_binary_expr (op, e1, e2); - e->expr.type = &type_ivec4; + e->expr.type = &type_bvec4; return new_horizontal_expr (hop, e, &type_int); } @@ -1102,7 +1136,7 @@ double_compare (int op, const expr_t *e1, const expr_t *e2) e1 = cast_expr (&type_double, e1); } e = new_binary_expr (op, e1, e2); - e->expr.type = &type_long; + e->expr.type = &type_lbool; return e; } @@ -1130,7 +1164,7 @@ uint_compare (int op, const expr_t *e1, const expr_t *e2) } } e = new_binary_expr (op, e1, e2); - e->expr.type = &type_int; + e->expr.type = &type_bool; return e; } @@ -1142,7 +1176,7 @@ entity_compare (int op, const expr_t *e1, const expr_t *e2) e2 = new_alias_expr (&type_int, e2); } expr_t *e = new_binary_expr (op, e1, e2); - e->expr.type = &type_int; + e->expr.type = &type_bool; if (options.code.progsversion == PROG_ID_VERSION) { e->expr.type = &type_float; } diff --git a/tools/qfcc/source/expr_bool.c b/tools/qfcc/source/expr_bool.c index 058ab2f28..540fbdf91 100644 --- a/tools/qfcc/source/expr_bool.c +++ b/tools/qfcc/source/expr_bool.c @@ -234,15 +234,15 @@ bool_expr (int op, const expr_t *label, const expr_t *e1, const expr_t *e2) switch (op) { case QC_OR: backpatch (e1->boolean.false_list, label); - return new_bool_expr (merge (e1->boolean.true_list, - e2->boolean.true_list), - e2->boolean.false_list, block); + return new_boolean_expr (merge (e1->boolean.true_list, + e2->boolean.true_list), + e2->boolean.false_list, block); break; case QC_AND: backpatch (e1->boolean.true_list, label); - return new_bool_expr (e2->boolean.true_list, - merge (e1->boolean.false_list, - e2->boolean.false_list), block); + return new_boolean_expr (e2->boolean.true_list, + merge (e1->boolean.false_list, + e2->boolean.false_list), block); break; } internal_error (e1, 0); @@ -301,15 +301,16 @@ convert_bool (const expr_t *e, int block) val = expr_float (e) != 0; } if (val) - e = new_bool_expr (make_list (b), 0, b); + e = new_boolean_expr (make_list (b), 0, b); else - e = new_bool_expr (0, make_list (b), b); + e = new_boolean_expr (0, make_list (b), b); } else { auto b = new_block_expr (0); append_expr (b, branch_expr (QC_NE, e, 0)); append_expr (b, goto_expr (0)); - e = new_bool_expr (make_list (b->block.list.head->expr), - make_list (b->block.list.head->next->expr), b); + e = new_boolean_expr (make_list (b->block.list.head->expr), + make_list (b->block.list.head->next->expr), + b); } } if (block && e->boolean.e->type != ex_block) { diff --git a/tools/qfcc/source/expr_cast.c b/tools/qfcc/source/expr_cast.c index bcc2d0c49..aa03ff728 100644 --- a/tools/qfcc/source/expr_cast.c +++ b/tools/qfcc/source/expr_cast.c @@ -41,6 +41,7 @@ #include "tools/qfcc/include/def.h" #include "tools/qfcc/include/diagnostic.h" #include "tools/qfcc/include/expr.h" +#include "tools/qfcc/include/struct.h" #include "tools/qfcc/include/type.h" #include "tools/qfcc/include/value.h" @@ -115,6 +116,23 @@ cast_expr (const type_t *dstType, const expr_t *e) || (is_string (dstType) && is_pointer (srcType))) { return new_alias_expr (dstType, e); } + if (is_enum (dstType) && is_boolean (srcType)) { + expr_t *enum_zero, *enum_one; + if (enum_as_bool (dstType, &enum_zero, &enum_one)) { + return conditional_expr (e, enum_one, enum_zero); + } + } + if (is_integral (dstType) && is_boolean (srcType)) { + auto type = dstType; + if (type_size (dstType) != type_size (srcType)) { + type = ev_types[srcType->type]; + } + e = new_alias_expr (type, e); + if (type != dstType) { + e = cast_expr (dstType, e); + } + return e; + } if (is_algebra (dstType) || is_algebra (srcType)) { const expr_t *c; if ((c = algebra_cast_expr (dstType, e))) { diff --git a/tools/qfcc/source/expr_unary.c b/tools/qfcc/source/expr_unary.c index a22895f04..ee42da9f5 100644 --- a/tools/qfcc/source/expr_unary.c +++ b/tools/qfcc/source/expr_unary.c @@ -269,6 +269,18 @@ ulong_bitnot (const expr_t *e) return new_ulong_expr (~expr_ulong (e)); } +static const expr_t * +bool_not (const expr_t *e) +{ + return new_bool_expr (expr_int (e)); +} + +static const expr_t * +lbool_not (const expr_t *e) +{ + return new_lbool_expr (expr_long (e)); +} + static unary_type_t string_u[] = { { .op = '!', .result_type = &type_bool, .constant = string_not, }, @@ -414,6 +426,18 @@ static unary_type_t algebra_u[] = { {} }; +static unary_type_t bool_u[] = { + { .op = '!', .result_type = &type_bool, .constant = bool_not, }, + + {} +}; + +static unary_type_t lbool_u[] = { + { .op = '!', .result_type = &type_lbool, .constant = lbool_not, }, + + {} +}; + static unary_type_t *unary_expr_types[ev_type_count] = { [ev_string] = string_u, [ev_float] = float_u, @@ -448,7 +472,8 @@ unary_expr (int op, const expr_t *e) auto t = get_type (e); if (op == '!' && e->type == ex_bool) { - return new_bool_expr (e->boolean.false_list, e->boolean.true_list, e); + return new_boolean_expr (e->boolean.false_list, + e->boolean.true_list, e); } if (op == '+' && is_math (t)) { @@ -459,6 +484,10 @@ unary_expr (int op, const expr_t *e) unary_type = algebra_u; } else if (is_enum (t)) { unary_type = int_u; + } else if (is_bool (t)) { + unary_type = bool_u; + } else if (is_lbool (t)) { + unary_type = lbool_u; } else if (t->meta == ty_basic || is_handle (t)) { unary_type = unary_expr_types[t->type]; } diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index d296b4a3f..316e163ae 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -324,6 +324,7 @@ pp_vnumber '({s}*{m}?{pp_number}){2,4}{s}*'{ULFD}? "&&" { return QC_AND; } "||" { return QC_OR; } +"^^" { return QC_XOR; } "==" { return QC_EQ; } "!=" { return QC_NE; } "<=" { return QC_LE; } diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index bd2bda035..596f24857 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -145,6 +145,7 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc); %left '.' '(' '[' %token VALUE STRING TOKEN +%token TRUE FALSE %token ELLIPSIS %token RESERVED // end of common tokens @@ -2117,6 +2118,18 @@ arg_expr const : VALUE + | TRUE + { + pr_type_t data = { .value = 1 }; + auto val = new_type_value (&type_bool, &data); + $$ = new_value_expr (val, false); + } + | FALSE + { + pr_type_t data = { .value = 0 }; + auto val = new_type_value (&type_bool, &data); + $$ = new_value_expr (val, false); + } | NIL { $$ = new_nil_expr (); } | string ; @@ -2864,11 +2877,15 @@ static keyword_t qf_keywords[] = { {"double", QC_TYPE_SPEC, .spec = { .type = &type_double } }, {"int", QC_TYPE_SPEC, .spec = { .type = &type_int } }, {"bool", QC_TYPE_SPEC, .spec = { .type = &type_bool } }, + {"lbool", QC_TYPE_SPEC, .spec = { .type = &type_lbool } }, {"unsigned", QC_TYPE_SPEC, .spec = { .is_unsigned = true } }, {"signed", QC_TYPE_SPEC, .spec = { .is_signed = true } }, {"long", QC_TYPE_SPEC, .spec = { .is_long = true } }, {"short", QC_TYPE_SPEC, .spec = { .is_short = true } }, + {"true", QC_TRUE }, + {"false", QC_FALSE}, + {"@args", QC_ARGS, }, {"@va_list", QC_TYPE_SPEC, .spec = { .type = &type_va_list } }, {"@param", QC_TYPE_SPEC, .spec = { .type = &type_param } }, diff --git a/tools/qfcc/source/qp-parse.y b/tools/qfcc/source/qp-parse.y index e2cdf7929..3a1a2be81 100644 --- a/tools/qfcc/source/qp-parse.y +++ b/tools/qfcc/source/qp-parse.y @@ -141,9 +141,12 @@ int yylex (void); %token TYPE TYPE_NAME %token ID %token VALUE +%token TRUE FALSE +%token ELLIPSIS +%token RESERVED %token PROGRAM VAR ARRAY OF FUNCTION PROCEDURE PBEGIN END IF THEN ELSE -%token WHILE DO RANGE ASSIGNOP NOT ELLIPSIS +%token WHILE DO RANGE ASSIGNOP NOT %token RETURN %type type standard_type diff --git a/tools/qfcc/source/struct.c b/tools/qfcc/source/struct.c index c0da58af1..01c1a54c1 100644 --- a/tools/qfcc/source/struct.c +++ b/tools/qfcc/source/struct.c @@ -308,7 +308,7 @@ add_enum (symbol_t *enm, symbol_t *name, const expr_t *val) symtab_addsymbol (enum_tab, name); } -int +bool enum_as_bool (const type_t *enm, expr_t **zero, expr_t **one) { symtab_t *symtab = enm->symtab; @@ -318,7 +318,7 @@ enum_as_bool (const type_t *enm, expr_t **zero, expr_t **one) int val, v; if (!symtab) - return 0; + return false; for (sym = symtab->symbols; sym; sym = sym->next) { if (sym->sy_type != sy_const) continue; @@ -336,10 +336,10 @@ enum_as_bool (const type_t *enm, expr_t **zero, expr_t **one) } if (!zero_sym || !one_sym) - return 0; + return false; *zero = new_symbol_expr (zero_sym); *one = new_symbol_expr (one_sym); - return 1; + return true; } symbol_t * diff --git a/tools/qfcc/source/switch.c b/tools/qfcc/source/switch.c index dd26d7155..8d86e1a67 100644 --- a/tools/qfcc/source/switch.c +++ b/tools/qfcc/source/switch.c @@ -445,7 +445,7 @@ switch_expr (switch_block_t *switch_block, const expr_t *break_label, case_node_t *case_tree; if (is_string(type)) - temp = new_temp_def_expr (&type_int); + temp = new_temp_def_expr (&type_bool); else temp = new_temp_def_expr (type); case_tree = build_case_tree (labels, num_labels, is_integral (type)); diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index e52aec3b3..c576b4036 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -746,10 +746,16 @@ reference_type (const type_t *aux) const type_t * matrix_type (const type_t *ele_type, int cols, int rows) { - if (!is_bool (ele_type) && !is_scalar (ele_type)) { + if (!is_boolean (ele_type) && !is_scalar (ele_type)) { return nullptr; } if (rows == 1 && cols == 1) { + if (is_bool (ele_type)) { + return &type_bool; + } + if (is_lbool (ele_type)) { + return &type_lbool; + } for (auto t = ev_types; t - ev_types < ev_type_count; t++) { if ((*t)->type == ele_type->type && (*t)->width == 1) { return *t; @@ -1376,7 +1382,23 @@ is_bool (const type_t *type) if (type->meta != ty_bool) { return false; } - return type->type == ev_int || type->type == ev_long; + return type->type == ev_int; +} + +bool +is_lbool (const type_t *type) +{ + type = unalias_type (type); + if (type->meta != ty_bool) { + return false; + } + return type->type == ev_long; +} + +bool +is_boolean (const type_t *type) +{ + return is_bool (type) || is_lbool (type); } bool @@ -1425,7 +1447,7 @@ is_scalar (const type_t *type) if (type->width != 1) { return false; } - return is_real (type) || is_integral (type); + return is_real (type) || is_integral (type) || is_boolean (type); } bool @@ -1563,6 +1585,20 @@ type_assignable (const type_t *dst, const type_t *src) && type_width (dst) == type_width (src)) { return true; } + if ((is_int (dst) || is_uint (dst) || is_float (dst)) + && is_bool (src)) { + return true; + } + if (is_enum (dst) && is_bool (src)) { + return true; + } + if ((is_long (dst) || is_ulong (dst) || is_double (dst)) + && is_boolean (src)) { + return true; + } + if (is_lbool (dst) && is_bool (src)) { + return true; + } return false; } @@ -1599,26 +1635,30 @@ type_promotes (const type_t *dst, const type_t *src) || type_cols (dst) != type_cols (src)) { return false; } - // nothing promotes to int - if (is_int (dst)) { + + if (is_int (dst) && is_bool (src)) { return true; } if (is_uint (dst) && is_int (src)) { return true; } - if (is_long (dst) && (is_int (src) || is_uint (src))) { + if (is_long (dst) && (is_int (src) || is_uint (src) || is_boolean (src))) { return true; } - if (is_ulong (dst) && (is_int (src) || is_uint (src) || is_long (src))) { + if (is_ulong (dst) && (is_int (src) || is_uint (src) || is_long (src) + || is_boolean (src))) { return true; } - if (is_float (dst) && (is_int (src) || is_uint (src))) { + if (is_float (dst) && (is_int (src) || is_uint (src) || is_bool (src))) { return true; } //XXX what to do with (u)long<->float? if (is_double (dst) && (is_int (src) || is_uint (src) || is_long (src) || is_ulong (src) - || is_float (src))) { + || is_float (src) || is_boolean (src))) { + return true; + } + if (is_lbool (dst) && is_bool (src)) { return true; } return false; diff --git a/tools/qfcc/test/const-fold-int.r b/tools/qfcc/test/const-fold-int.r index d7fa31920..540d00588 100644 --- a/tools/qfcc/test/const-fold-int.r +++ b/tools/qfcc/test/const-fold-int.r @@ -36,7 +36,7 @@ int subsub_c_t_c_e (int x) { return 6 - (7 - x); } int main () { - int fail = 0; + bool fail = false; fail |= mul_e_c_t_c (10) != 420; fail |= mul_c_e_t_c (10) != 420; diff --git a/tools/qfcc/test/double.r b/tools/qfcc/test/double.r index d3bd39307..a0a6d2434 100644 --- a/tools/qfcc/test/double.r +++ b/tools/qfcc/test/double.r @@ -6,10 +6,10 @@ union { int i[2]; } type_pun; -long +bool test_format () { - int fail = 0; + bool fail; type_pun.d = M_PI; printf ("%.17g %08x%08x\n", type_pun.d, type_pun.i[1], type_pun.i[0]); // this will fail on big-endian systems @@ -17,10 +17,10 @@ test_format () return fail; } -long +lbool test_constant () { - long fail = 0; + lbool fail = false; double a, b, c, d, e; a = 1; b = 2.0; @@ -43,7 +43,7 @@ double greater = 5; long test_copare () { - long fail = 0; + lbool fail = 0; fail |= !(less < greater); fail |= (less > greater); @@ -75,10 +75,10 @@ test_copare () return fail; } -long +lbool test_ops () { - long fail = 0; + lbool fail = 0; double a = 6.25, b = 2.375; double c; @@ -98,8 +98,8 @@ test_ops () int main () { - long fail = 0; - fail |= test_format (); + lbool fail = false; + fail |= (lbool) test_format (); fail |= test_constant (); fail |= test_ops (); return fail; diff --git a/tools/qfcc/test/structstruct.r b/tools/qfcc/test/structstruct.r index c8ef25fad..891720ad7 100644 --- a/tools/qfcc/test/structstruct.r +++ b/tools/qfcc/test/structstruct.r @@ -46,7 +46,7 @@ test_struct_4(Rect rect) int main() { - int ret = 0; + bool ret = false; ret |= test_struct_1(rect) != 1; ret |= test_struct_2(rect) != 2; ret |= test_struct_3(rect) != 3;