mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 05:01:24 +00:00
[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:
parent
ad36d2cd50
commit
ebb3ec592a
32 changed files with 381 additions and 206 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -208,7 +208,7 @@ syntax_error ()
|
|||
Script_GetLine (script));
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
match (token_e token)
|
||||
{
|
||||
if (lookahead == -1) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{
|
||||
int index;
|
||||
int size;
|
||||
int dir;
|
||||
bool dir;
|
||||
}
|
||||
|
||||
- (id) initWithBounds: (Rect)aRect size: (int) aSize;
|
||||
|
|
|
@ -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
|
||||
|
||||
///@}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
@interface PointerView : DefView
|
||||
{
|
||||
unsigned *data;
|
||||
int invalid;
|
||||
bool invalid;
|
||||
unsigned ptr;
|
||||
qfot_type_t *ptr_type;
|
||||
int ptr_size;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
@interface ScrollBar : View
|
||||
{
|
||||
int vertical;
|
||||
bool vertical;
|
||||
int bgchar;
|
||||
double mouseTime;
|
||||
Point mouseStart;
|
||||
|
|
|
@ -521,7 +521,7 @@ 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,
|
||||
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.
|
||||
|
|
|
@ -57,7 +57,7 @@ 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,
|
||||
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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -234,13 +234,13 @@ 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,
|
||||
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,
|
||||
return new_boolean_expr (e2->boolean.true_list,
|
||||
merge (e1->boolean.false_list,
|
||||
e2->boolean.false_list), block);
|
||||
break;
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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 } },
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue