mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-25 22:01:33 +00:00
integer() and float() casts seem to work
This commit is contained in:
parent
d05e3c0afc
commit
d69762facd
6 changed files with 104 additions and 63 deletions
|
@ -1,9 +1,17 @@
|
|||
void (integer x, integer y, string text) Menu_Begin = #0;
|
||||
void (integer x, integer y, string name) Menu_Pic = #0;
|
||||
void (integer x, integer y, string name) Menu_CenterPic = #0;
|
||||
void (integer x, integer y, string text, void (string text, integer key) func) Menu_Item = #0;
|
||||
void (void (integer x, integer y) func) Menu_Cursor = #0;
|
||||
void () Menu_End = #0;
|
||||
void (integer x, integer y, string text) Menu_Begin = #1;
|
||||
void (integer x, integer y, string name) Menu_Pic = #1;
|
||||
void (integer x, integer y, string name) Menu_CenterPic = #1;
|
||||
void (integer x, integer y, string text, void (string text, integer key) func) Menu_Item = #1;
|
||||
void (void (integer x, integer y) func) Menu_Cursor = #1;
|
||||
void () Menu_End = #1;
|
||||
|
||||
void (integer x, integer y, string name) Draw_Pic = #1;
|
||||
|
||||
float time;
|
||||
entity self;
|
||||
.float nextthink;
|
||||
.float frame;
|
||||
.void () think;
|
||||
|
||||
string [6] dot;/* = {
|
||||
"gfx/menudot0.lpm",
|
||||
|
@ -16,7 +24,7 @@ string [6] dot;/* = {
|
|||
|
||||
void (integer x, integer y) spinner =
|
||||
{
|
||||
//Draw_Pic (x, y, dot[integer(time * 10) % 6]);
|
||||
Draw_Pic (x, y, dot[integer(time * 10) % 6]);
|
||||
};
|
||||
|
||||
void (string text, integer key) quit =
|
||||
|
|
|
@ -126,6 +126,10 @@ opcode_t pr_opcodes[] = {
|
|||
{"&", "lea", OP_LEA, false, ev_pointer, ev_integer, ev_pointer, PROG_VERSION},
|
||||
{"&", "leai", OP_LEAI, false, ev_pointer, ev_short, ev_pointer, PROG_VERSION},
|
||||
|
||||
{"=", "conv.if", OP_CONV_IF, false, ev_integer, ev_void, ev_float, PROG_VERSION},
|
||||
{"=", "conv.fi", OP_CONV_FI, false, ev_float, ev_void, ev_integer, PROG_VERSION},
|
||||
|
||||
|
||||
{"=", "store.f", OP_STORE_F, true, ev_float, ev_float, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.v", OP_STORE_V, true, ev_vector, ev_vector, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.s", OP_STORE_S, true, ev_string, ev_string, ev_void, PROG_ID_VERSION},
|
||||
|
|
|
@ -148,6 +148,7 @@ expr_t *incop_expr (int op, expr_t *e, int postop);
|
|||
expr_t *array_expr (expr_t *array, expr_t *index);
|
||||
expr_t *address_expr (expr_t *e1, expr_t *e2, type_t *t);
|
||||
expr_t *assign_expr (expr_t *e1, expr_t *e2);
|
||||
expr_t *cast_expr (type_t *t, expr_t *e);
|
||||
|
||||
def_t *emit_statement (int line, opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_c);
|
||||
void emit_expr (expr_t *e);
|
||||
|
|
|
@ -247,6 +247,8 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
opcode_t *op;
|
||||
const char *operator;
|
||||
def_t *def_a, *def_b, *d = 0;
|
||||
static expr_t zero;
|
||||
def_t *tmp = 0;
|
||||
|
||||
switch (e->type) {
|
||||
case ex_block:
|
||||
|
@ -289,63 +291,72 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
d = emit_statement (e->line, op, def_a, def_b, dest);
|
||||
break;
|
||||
case ex_uexpr:
|
||||
if (e->e.expr.op == '!') {
|
||||
operator = "!";
|
||||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||
def_b = &def_void;
|
||||
} else if (e->e.expr.op == '~') {
|
||||
operator = "~";
|
||||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||
def_b = &def_void;
|
||||
} else if (e->e.expr.op == '-') {
|
||||
static expr_t zero;
|
||||
|
||||
zero.type = expr_types[extract_type (e->e.expr.e1)];
|
||||
|
||||
operator = "-";
|
||||
def_a = PR_ReuseConstant (&zero, 0);
|
||||
def_b = emit_sub_expr (e->e.expr.e1, 0);
|
||||
if (!dest) {
|
||||
dest = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||
dest->users += 2;
|
||||
}
|
||||
} else if (e->e.expr.op == '&') {
|
||||
static expr_t zero;
|
||||
def_t *tmp = 0;
|
||||
|
||||
zero.type = ex_short;
|
||||
|
||||
operator = "&";
|
||||
if (e->e.expr.e1->type == ex_expr
|
||||
&& e->e.expr.e1->e.expr.op == '.') {
|
||||
tmp = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||
tmp->users += 2;
|
||||
def_b = emit_sub_expr (&zero, 0);
|
||||
} else {
|
||||
switch (e->e.expr.op) {
|
||||
case '!':
|
||||
operator = "!";
|
||||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||
def_b = &def_void;
|
||||
}
|
||||
def_a = emit_sub_expr (e->e.expr.e1, tmp);
|
||||
if (!dest) {
|
||||
dest = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||
dest->users += 2;
|
||||
}
|
||||
} else if (e->e.expr.op == '.') {
|
||||
if (!dest
|
||||
&& (e->e.expr.e1->type != ex_pointer
|
||||
|| !(e->e.expr.e1->e.pointer.val > 0
|
||||
&& e->e.expr.e1->e.pointer.val < 65536))) {
|
||||
dest = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||
dest->users += 2;
|
||||
}
|
||||
if (e->e.expr.e1->type == ex_expr
|
||||
&& e->e.expr.e1->e.expr.op == '&')
|
||||
e->e.expr.e1->e.expr.op = '.';
|
||||
d = emit_sub_expr (e->e.expr.e1, dest);
|
||||
if (!d->name)
|
||||
d->type = e->e.expr.type;
|
||||
return d;
|
||||
} else {
|
||||
abort ();
|
||||
break;
|
||||
case '~':
|
||||
operator = "~";
|
||||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||
def_b = &def_void;
|
||||
break;
|
||||
case '-':
|
||||
zero.type = expr_types[extract_type (e->e.expr.e1)];
|
||||
|
||||
operator = "-";
|
||||
def_a = PR_ReuseConstant (&zero, 0);
|
||||
def_b = emit_sub_expr (e->e.expr.e1, 0);
|
||||
if (!dest) {
|
||||
dest = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||
dest->users += 2;
|
||||
}
|
||||
break;
|
||||
case '&':
|
||||
zero.type = ex_short;
|
||||
|
||||
operator = "&";
|
||||
if (e->e.expr.e1->type == ex_expr
|
||||
&& e->e.expr.e1->e.expr.op == '.') {
|
||||
tmp = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||
tmp->users += 2;
|
||||
def_b = emit_sub_expr (&zero, 0);
|
||||
} else {
|
||||
def_b = &def_void;
|
||||
}
|
||||
def_a = emit_sub_expr (e->e.expr.e1, tmp);
|
||||
if (!dest) {
|
||||
dest = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||
dest->users += 2;
|
||||
}
|
||||
break;
|
||||
case '.':
|
||||
if (!dest
|
||||
&& (e->e.expr.e1->type != ex_pointer
|
||||
|| !(e->e.expr.e1->e.pointer.val > 0
|
||||
&& e->e.expr.e1->e.pointer.val < 65536))) {
|
||||
dest = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||
dest->users += 2;
|
||||
}
|
||||
if (e->e.expr.e1->type == ex_expr
|
||||
&& e->e.expr.e1->e.expr.op == '&')
|
||||
e->e.expr.e1->e.expr.op = '.';
|
||||
d = emit_sub_expr (e->e.expr.e1, dest);
|
||||
if (!d->name)
|
||||
d->type = e->e.expr.type;
|
||||
return d;
|
||||
case 'C':
|
||||
if (!dest) {
|
||||
dest = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||
dest->users = 2;
|
||||
}
|
||||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||
def_b = &def_void;
|
||||
operator = "=";
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
op = PR_Opcode_Find (operator, def_a, def_b, dest);
|
||||
d = emit_statement (e->line, op, def_a, def_b, dest);
|
||||
|
|
|
@ -1750,3 +1750,19 @@ assign_expr (expr_t *e1, expr_t *e2)
|
|||
e->e.expr.type = type;
|
||||
return e;
|
||||
}
|
||||
|
||||
expr_t *
|
||||
cast_expr (type_t *t, expr_t *e)
|
||||
{
|
||||
expr_t *c;
|
||||
|
||||
if ((t != &type_integer && t != &type_uinteger
|
||||
&& get_type (e) != &type_float)
|
||||
&& (t != &type_float && get_type (e) != &type_integer)) {
|
||||
return error (e, "can not cast from %s to %s",
|
||||
pr_type_name[extract_type (e)], pr_type_name[t->type]);
|
||||
}
|
||||
c = new_unary_expr ('C', e);
|
||||
c->e.expr.type = t;
|
||||
return c;
|
||||
}
|
||||
|
|
|
@ -695,6 +695,7 @@ expr
|
|||
| expr '%' expr { $$ = binary_expr ('%', $1, $3); }
|
||||
| expr '(' arg_list ')' { $$ = function_expr ($1, $3); }
|
||||
| expr '(' ')' { $$ = function_expr ($1, 0); }
|
||||
| TYPE '(' expr ')' { $$ = cast_expr ($1, $3); }
|
||||
| expr '[' expr ']' { $$ = array_expr ($1, $3); }
|
||||
| expr '.' expr { $$ = binary_expr ('.', $1, $3); }
|
||||
| '+' expr %prec UNARY { $$ = $2; }
|
||||
|
|
Loading…
Reference in a new issue