[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.
This commit is contained in:
Bill Currie 2024-11-15 12:36:08 +09:00
parent ad36d2cd50
commit ebb3ec592a
32 changed files with 381 additions and 206 deletions

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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];
}

View file

@ -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 =

View file

@ -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);

View file

@ -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;

View file

@ -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];

View file

@ -208,7 +208,7 @@ syntax_error ()
Script_GetLine (script));
}
static int
static bool
match (token_e token)
{
if (lookahead == -1) {

View file

@ -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

View file

@ -10,7 +10,7 @@
{
int index;
int size;
int dir;
bool dir;
}
- (id) initWithBounds: (Rect)aRect size: (int) aSize;

View file

@ -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
///@}

View file

@ -6,7 +6,7 @@
@interface PointerView : DefView
{
unsigned *data;
int invalid;
bool invalid;
unsigned ptr;
qfot_type_t *ptr_type;
int ptr_size;

View file

@ -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;
}

View file

@ -10,7 +10,7 @@
@interface ScrollBar : View
{
int vertical;
bool vertical;
int bgchar;
double mouseTime;
Point mouseStart;

View file

@ -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.

View file

@ -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);

View file

@ -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));

View file

@ -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;

View file

@ -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;
}

View file

@ -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) {

View file

@ -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))) {

View file

@ -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];
}

View file

@ -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; }

View file

@ -145,6 +145,7 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc);
%left '.' '(' '['
%token <expr> 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 } },

View file

@ -141,9 +141,12 @@ int yylex (void);
%token <type> TYPE TYPE_NAME
%token <symbol> ID
%token <expr> 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> type standard_type

View file

@ -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 *

View file

@ -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));

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;