Initial integer type support. qfcc /is/ partially broken when it comes to

integer constants and float function args/return values.

pr_comp.h:
	o  add the integer opcodes to pr_opcode_e
pr_edict.c:
	o  add "quaternion" and "integer" to type_name[]
	o  support quatnernion and integers types when printing values
	o  support the integer opcodes when bounds checking
pr_exec.c
	o  enable the integer opcodes
pr_opcode:
	o  add the integer opcodes to the opcode table
	o  logical operators all result in an integer rather than a value
expr.h:
	o  rename int_val to integer_val
qfcc.h:
	o  kill another magic number
expr.c:
	o  move the opcode to string conversion out of type_mismatch and into
	   get_op_string
	o  rename int_val to integer_val
	o  general integer type support.
	o  generate an internal comipiler error for null opcodes rather than
	   segging.
pr_imm.c:
	o  rename int_val to integer_val
	o  support integer constants, converting to float when needed.
pr_lex.c:
	o  magic number death and support quaternions and integers in type_size[]
qc-lex.l
	o  rename int_val to integer_val
	o  support quaternion and integer type keywords
qc-parse.y:
	o  rename int_val to integer_val
	o  use binary_expr instead of new_binary_expr for local initialized
	   variables
builtins.c:
	o  rename int_val to integer_val
	o  fix most (all?) of the INT related FIXMEs
defs.qc:
	o  use integer instead of float where it makes sense
main.c:
	o  read_result is now integer rather than float
main.qc:
	o  float -> integer where appropriate
	o  new test for int const to float arg
This commit is contained in:
Bill Currie 2001-07-23 01:31:22 +00:00
parent 22c9716b56
commit c248372e20
15 changed files with 349 additions and 180 deletions

View file

@ -137,6 +137,28 @@ typedef enum {
OP_GE_S,
OP_LT_S,
OP_GT_S,
OP_ADD_I,
OP_SUB_I,
OP_MUL_I,
OP_DIV_I,
OP_BITAND_I,
OP_BITOR_I,
OP_GE_I,
OP_LE_I,
OP_GT_I,
OP_LT_I,
OP_AND_I,
OP_OR_I,
OP_NOT_I,
OP_EQ_I,
OP_NE_I,
OP_STORE_I,
OP_STOREP_I,
OP_LOAD_I,
OP_CONV_IF,
OP_CONV_FI,
} pr_opcode_e;
typedef struct

View file

@ -66,7 +66,7 @@ int type_size[8] = {
sizeof (void *) / 4
};
char *type_name[8] = {
char *type_name[ev_type_count] = {
"void",
"string",
"float",
@ -75,6 +75,8 @@ char *type_name[8] = {
"field",
"function",
"pointer",
"quaternion",
"integer",
};
ddef_t *ED_FieldAtOfs (progs_t * pr, int ofs);
@ -376,11 +378,20 @@ PR_ValueString (progs_t * pr, etype_t type, pr_type_t *val)
break;
case ev_vector:
snprintf (line, sizeof (line), "'%5.1f %5.1f %5.1f'",
val->vector_var[0], val->vector_var[1], val->vector_var[2]);
val->vector_var[0], val->vector_var[1],
val->vector_var[2]);
break;
case ev_pointer:
strcpy (line, "pointer");
break;
case ev_quaternion:
snprintf (line, sizeof (line), "'%5.1f %5.1f %5.1f %5.1f'",
val->vector_var[0], val->vector_var[1],
val->vector_var[2], val->vector_var[3]);
break;
case ev_integer:
snprintf (line, sizeof (line), "%d", val->integer_var);
break;
default:
snprintf (line, sizeof (line), "bad type %i", type);
break;
@ -1224,6 +1235,24 @@ PR_LoadProgs (progs_t * pr, const char *progsname)
case OP_LOAD_S:
case OP_LOAD_FNC:
case OP_LOAD_V:
case OP_ADD_I:
case OP_SUB_I:
case OP_MUL_I:
case OP_DIV_I:
case OP_BITAND_I:
case OP_BITOR_I:
case OP_GE_I:
case OP_LE_I:
case OP_GT_I:
case OP_LT_I:
case OP_AND_I:
case OP_OR_I:
case OP_NOT_I:
case OP_EQ_I:
case OP_NE_I:
case OP_LOAD_I:
case OP_CONV_IF:
case OP_CONV_FI:
if ((unsigned short) st->a >= pr->progs->numglobals
|| (unsigned short) st->b >= pr->progs->numglobals
|| (unsigned short) st->c >= pr->progs->numglobals)
@ -1257,6 +1286,8 @@ PR_LoadProgs (progs_t * pr, const char *progsname)
case OP_STATE:
case OP_STOREP_V:
case OP_STORE_V:
case OP_STORE_I:
case OP_STOREP_I:
if ((unsigned short) st->a >= pr->progs->numglobals
|| (unsigned short) st->b >= pr->progs->numglobals)
PR_Error

View file

@ -621,8 +621,6 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
ed->v[pr->fields.frame].float_var = OPA.float_var;
ed->v[pr->fields.think].func_var = OPB.func_var;
break;
// LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
/*
case OP_ADD_I:
OPC.integer_var = OPA.integer_var + OPB.integer_var;
break;
@ -632,6 +630,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_MUL_I:
OPC.integer_var = OPA.integer_var * OPB.integer_var;
break;
/*
case OP_DIV_VF:
{
float temp = 1.0f / OPB.float_var;
@ -641,6 +640,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
OPC.vector_var[2] = temp * OPA.vector_var[2];
}
break;
*/
case OP_DIV_I:
OPC.integer_var = OPA.integer_var / OPB.integer_var;
break;
@ -657,31 +657,31 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
OPC.integer_var = OPA.integer_var | OPB.integer_var;
break;
case OP_GE_I:
OPC.float_var = OPA.integer_var >= OPB.integer_var;
OPC.integer_var = OPA.integer_var >= OPB.integer_var;
break;
case OP_LE_I:
OPC.float_var = OPA.integer_var <= OPB.integer_var;
OPC.integer_var = OPA.integer_var <= OPB.integer_var;
break;
case OP_GT_I:
OPC.float_var = OPA.integer_var > OPB.integer_var;
OPC.integer_var = OPA.integer_var > OPB.integer_var;
break;
case OP_LT_I:
OPC.float_var = OPA.integer_var < OPB.integer_var;
OPC.integer_var = OPA.integer_var < OPB.integer_var;
break;
case OP_AND_I:
OPC.float_var = OPA.integer_var && OPB.integer_var;
OPC.integer_var = OPA.integer_var && OPB.integer_var;
break;
case OP_OR_I:
OPC.float_var = OPA.integer_var || OPB.integer_var;
OPC.integer_var = OPA.integer_var || OPB.integer_var;
break;
case OP_NOT_I:
OPC.float_var = !OPA.integer_var;
OPC.integer_var = !OPA.integer_var;
break;
case OP_EQ_I:
OPC.float_var = OPA.integer_var == OPB.integer_var;
OPC.integer_var = OPA.integer_var == OPB.integer_var;
break;
case OP_NE_I:
OPC.float_var = OPA.integer_var != OPB.integer_var;
OPC.integer_var = OPA.integer_var != OPB.integer_var;
break;
case OP_STORE_I:
OPB.integer_var = OPA.integer_var;
@ -702,7 +702,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
(pr, "Progs attempted to write to an engine edict field\n");
return;
}
ptr = (eval_t *) ((byte *) *pr->edicts + OPB.integer_var);
ptr = (pr_type_t*)((int)*pr->edicts + OPB.integer_var);
ptr->integer_var = OPA.integer_var;
break;
case OP_LOAD_I:
@ -721,9 +721,11 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
return;
}
ed = PROG_TO_EDICT (pr, OPA.entity_var);
OPC.integer_var = ((eval_t *) ((int *) &ed->v + OPB.integer_var))->integer_var;
OPC.integer_var = ed->v[OPB.integer_var].integer_var;
break;
// LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
/*
case OP_GSTOREP_I:
case OP_GSTOREP_F:
case OP_GSTOREP_ENT:

View file

@ -50,26 +50,26 @@ opcode_t pr_opcodes[] = {
{"-", "sub.f", OP_SUB_F, 3, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{"-", "sub.v", OP_SUB_V, 3, false, ev_vector, ev_vector, ev_vector, PROG_ID_VERSION},
{"==", "eq.f", OP_EQ_F, 4, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{"==", "eq.v", OP_EQ_V, 4, false, ev_vector, ev_vector, ev_float, PROG_ID_VERSION},
{"==", "eq.s", OP_EQ_S, 4, false, ev_string, ev_string, ev_float, PROG_ID_VERSION},
{"==", "eq.e", OP_EQ_E, 4, false, ev_entity, ev_entity, ev_float, PROG_ID_VERSION},
{"==", "eq.fnc", OP_EQ_FNC, 4, false, ev_func, ev_func, ev_float, PROG_ID_VERSION},
{"==", "eq.f", OP_EQ_F, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{"==", "eq.v", OP_EQ_V, 4, false, ev_vector, ev_vector, ev_integer, PROG_ID_VERSION},
{"==", "eq.s", OP_EQ_S, 4, false, ev_string, ev_string, ev_integer, PROG_ID_VERSION},
{"==", "eq.e", OP_EQ_E, 4, false, ev_entity, ev_entity, ev_integer, PROG_ID_VERSION},
{"==", "eq.fnc", OP_EQ_FNC, 4, false, ev_func, ev_func, ev_integer, PROG_ID_VERSION},
{"!=", "ne.f", OP_NE_F, 4, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{"!=", "ne.v", OP_NE_V, 4, false, ev_vector, ev_vector, ev_float, PROG_ID_VERSION},
{"!=", "ne.s", OP_NE_S, 4, false, ev_string, ev_string, ev_float, PROG_ID_VERSION},
{"!=", "ne.e", OP_NE_E, 4, false, ev_entity, ev_entity, ev_float, PROG_ID_VERSION},
{"!=", "ne.fnc", OP_NE_FNC, 4, false, ev_func, ev_func, ev_float, PROG_ID_VERSION},
{"!=", "ne.f", OP_NE_F, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{"!=", "ne.v", OP_NE_V, 4, false, ev_vector, ev_vector, ev_integer, PROG_ID_VERSION},
{"!=", "ne.s", OP_NE_S, 4, false, ev_string, ev_string, ev_integer, PROG_ID_VERSION},
{"!=", "ne.e", OP_NE_E, 4, false, ev_entity, ev_entity, ev_integer, PROG_ID_VERSION},
{"!=", "ne.fnc", OP_NE_FNC, 4, false, ev_func, ev_func, ev_integer, PROG_ID_VERSION},
{"<=", "le", OP_LE, 4, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{">=", "ge", OP_GE, 4, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{"<=", "le.s", OP_LE_S, 4, false, ev_string, ev_string, ev_float, PROG_VERSION},
{">=", "ge.s", OP_GE_S, 4, false, ev_string, ev_string, ev_float, PROG_VERSION},
{"<", "lt", OP_LT, 4, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{">", "gt", OP_GT, 4, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{"<", "lt.s", OP_LT_S, 4, false, ev_string, ev_string, ev_float, PROG_VERSION},
{">", "gt.s", OP_GT_S, 4, false, ev_string, ev_string, ev_float, PROG_VERSION},
{"<=", "le", OP_LE, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{">=", "ge", OP_GE, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{"<=", "le.s", OP_LE_S, 4, false, ev_string, ev_string, ev_integer, PROG_VERSION},
{">=", "ge.s", OP_GE_S, 4, false, ev_string, ev_string, ev_integer, PROG_VERSION},
{"<", "lt", OP_LT, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{">", "gt", OP_GT, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{"<", "lt.s", OP_LT_S, 4, false, ev_string, ev_string, ev_integer, PROG_VERSION},
{">", "gt.s", OP_GT_S, 4, false, ev_string, ev_string, ev_integer, PROG_VERSION},
{".", "load.f", OP_LOAD_F, 1, false, ev_entity, ev_field, ev_float, PROG_ID_VERSION},
{".", "load.v", OP_LOAD_V, 1, false, ev_entity, ev_field, ev_vector, PROG_ID_VERSION},
@ -96,14 +96,14 @@ opcode_t pr_opcodes[] = {
{"<RETURN>", "return", OP_RETURN, -1, false, ev_void, ev_void, ev_void, PROG_ID_VERSION},
{"!", "not.f", OP_NOT_F, -1, false, ev_float, ev_void, ev_float, PROG_ID_VERSION},
{"!", "not.v", OP_NOT_V, -1, false, ev_vector, ev_void, ev_float, PROG_ID_VERSION},
{"!", "not.s", OP_NOT_S, -1, false, ev_string, ev_void, ev_float, PROG_ID_VERSION},
{"!", "not.ent", OP_NOT_ENT, -1, false, ev_entity, ev_void, ev_float, PROG_ID_VERSION},
{"!", "not.fnc", OP_NOT_FNC, -1, false, ev_func, ev_void, ev_float, PROG_ID_VERSION},
{"!", "not.f", OP_NOT_F, -1, false, ev_float, ev_void, ev_integer, PROG_ID_VERSION},
{"!", "not.v", OP_NOT_V, -1, false, ev_vector, ev_void, ev_integer, PROG_ID_VERSION},
{"!", "not.s", OP_NOT_S, -1, false, ev_string, ev_void, ev_integer, PROG_ID_VERSION},
{"!", "not.ent", OP_NOT_ENT, -1, false, ev_entity, ev_void, ev_integer, PROG_ID_VERSION},
{"!", "not.fnc", OP_NOT_FNC, -1, false, ev_func, ev_void, ev_integer, PROG_ID_VERSION},
{"<IF>", "if", OP_IF, -1, false, ev_float, ev_float, ev_void, PROG_ID_VERSION},
{"<IFNOT>", "ifnot", OP_IFNOT, -1, false, ev_float, ev_float, ev_void, PROG_ID_VERSION},
{"<IF>", "if", OP_IF, -1, false, ev_integer, ev_integer, ev_void, PROG_ID_VERSION},
{"<IFNOT>", "ifnot", OP_IFNOT, -1, false, ev_integer, ev_integer, ev_void, PROG_ID_VERSION},
// calls returns REG_RETURN
{"<CALL0>", "call0", OP_CALL0, -1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
@ -120,11 +120,31 @@ opcode_t pr_opcodes[] = {
{"<GOTO>", "goto", OP_GOTO, -1, false, ev_float, ev_void, ev_void, PROG_ID_VERSION},
{"&&", "and", OP_AND, 6, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{"||", "or", OP_OR, 6, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{"&&", "and", OP_AND, 6, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{"||", "or", OP_OR, 6, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{"&", "bitand", OP_BITAND, 2, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{"|", "bitor", OP_BITOR, 2, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{"+", "add.i", OP_ADD_I, 3, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"-", "sub.i", OP_SUB_I, 3, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"*", "mul.i", OP_MUL_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"/", "div.i", OP_DIV_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"&", "bitand.i", OP_BITAND_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"|", "bitor.i", OP_BITOR_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{">=", "ge.i", OP_GE_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"<=", "le.i", OP_LE_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{">", "gt.i", OP_GT_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"<", "lt.i", OP_LT_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"&&", "and.i", OP_AND_I, 6, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"||", "or.i", OP_OR_I, 6, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"!", "not.i", OP_NOT_I, -1, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"==", "eq.i", OP_EQ_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"!=", "ne.i", OP_NE_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"=", "store.i", OP_STORE_I, 5, true, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"=", "storep.i", OP_STOREP_I, 5, true, ev_pointer, ev_integer, ev_integer, PROG_VERSION},
{".", "load.i", OP_LOAD_I, 1, false, ev_entity, ev_field, ev_integer, PROG_VERSION},
{0},
};

View file

@ -52,7 +52,7 @@ typedef struct expr_s {
int func_val;
int pointer_val;
float quaternion_val[4];
int int_val;
int integer_val;
} e;
} expr_t;

View file

@ -318,7 +318,7 @@ typedef union eval_s
union eval_s *ptr;
} eval_t;
extern int type_size[8];
extern int type_size[ev_type_count];
extern def_t *def_for_type[8];
extern type_t type_void;

View file

@ -88,11 +88,8 @@ get_type (expr_t *e)
case ex_func:
case ex_pointer:
case ex_quaternion:
case ex_integer:
return qc_types[e->type];
case ex_integer: //FIXME int should stay int, at least until code generation
e->type = ex_float;
e->e.float_val = e->e.int_val;
return ev_float;
}
return ev_void;
}
@ -144,62 +141,62 @@ warning (expr_t *e, const char *fmt, ...)
va_end (args);
}
const char *
get_op_string (int op)
{
switch (op) {
case OR:
return "||";
case AND:
return "&&";
case EQ:
return "==";
case NE:
return "!=";
case LE:
return "<=";
case GE:
return ">=";
case LT:
return "<";
case GT:
return ">";
case '=':
return "=";
case '+':
return "+";
case '-':
return "-";
case '*':
return "*";
case '/':
return "/";
case '&':
return "&";
case '|':
return "|";
case '!':
return "!";
case '(':
return "(";
case '.':
return ".";
default:
return "unknown";
}
}
expr_t *
type_mismatch (expr_t *e1, expr_t *e2, int op)
{
etype_t t1, t2;
char opname[4];
t1 = get_type (e1);
t2 = get_type (e2);
switch (op) {
case OR:
opname[0] = '|';
opname[1] = '|';
opname[2] = 0;
break;
case AND:
opname[0] = '&';
opname[1] = '&';
opname[2] = 0;
break;
case EQ:
opname[0] = '=';
opname[1] = '=';
opname[2] = 0;
break;
case NE:
opname[0] = '!';
opname[1] = '=';
opname[2] = 0;
break;
case LE:
opname[0] = '<';
opname[1] = '=';
opname[2] = 0;
break;
case GE:
opname[0] = '>';
opname[1] = '=';
opname[2] = 0;
break;
case LT:
opname[0] = '<';
opname[1] = 0;
break;
case GT:
opname[0] = '>';
opname[1] = 0;
break;
default:
opname[0] = op;
opname[1] = 0;
break;
}
return error (e1, "type mismatch: %s %s %s",
type_names[t1], opname, type_names[t2]);
type_names[t1], get_op_string (op), type_names[t2]);
}
expr_t *
@ -348,7 +345,7 @@ print_expr (expr_t *e)
case ex_func:
case ex_pointer:
case ex_integer:
printf ("%d", e->e.int_val);
printf ("%d", e->e.integer_val);
break;
}
}
@ -373,27 +370,27 @@ do_op_string (int op, expr_t *e1, expr_t *e2)
break;
case LT:
e1->type = ex_integer;
e1->e.int_val = strcmp (s1, s2) < 0;
e1->e.integer_val = strcmp (s1, s2) < 0;
break;
case GT:
e1->type = ex_integer;
e1->e.int_val = strcmp (s1, s2) > 0;
e1->e.integer_val = strcmp (s1, s2) > 0;
break;
case LE:
e1->type = ex_integer;
e1->e.int_val = strcmp (s1, s2) <= 0;
e1->e.integer_val = strcmp (s1, s2) <= 0;
break;
case GE:
e1->type = ex_integer;
e1->e.int_val = strcmp (s1, s2) >= 0;
e1->e.integer_val = strcmp (s1, s2) >= 0;
break;
case EQ:
e1->type = ex_integer;
e1->e.int_val = strcmp (s1, s2) == 0;
e1->e.integer_val = strcmp (s1, s2) == 0;
break;
case NE:
e1->type = ex_integer;
e1->e.int_val = strcmp (s1, s2) != 0;
e1->e.integer_val = strcmp (s1, s2) != 0;
break;
default:
return error (e1, "invalid operand for string");
@ -429,34 +426,36 @@ do_op_float (int op, expr_t *e1, expr_t *e2)
e1->e.float_val = (int)f1 | (int)f2;
break;
case AND:
e1->e.float_val = f1 && f2;
e1->type = ex_integer;
e1->e.integer_val = f1 && f2;
break;
case OR:
e1->e.float_val += f1 || f2;
e1->type = ex_integer;
e1->e.integer_val = f1 || f2;
break;
case LT:
e1->type = ex_integer;
e1->e.int_val = f1 < f2;
e1->e.integer_val = f1 < f2;
break;
case GT:
e1->type = ex_integer;
e1->e.int_val = f1 > f2;
e1->e.integer_val = f1 > f2;
break;
case LE:
e1->type = ex_integer;
e1->e.int_val = f1 <= f2;
e1->e.integer_val = f1 <= f2;
break;
case GE:
e1->type = ex_integer;
e1->e.int_val = f1 >= f2;
e1->e.integer_val = f1 >= f2;
break;
case EQ:
e1->type = ex_integer;
e1->e.int_val = f1 == f2;
e1->e.integer_val = f1 == f2;
break;
case NE:
e1->type = ex_integer;
e1->e.int_val = f1 != f2;
e1->e.integer_val = f1 != f2;
break;
default:
return error (e1, "invalid operand for string");
@ -485,13 +484,13 @@ do_op_vector (int op, expr_t *e1, expr_t *e2)
break;
case EQ:
e1->type = ex_integer;
e1->e.int_val = (v1[0] == v2[0])
e1->e.integer_val = (v1[0] == v2[0])
&& (v1[1] == v2[1])
&& (v1[2] == v2[2]);
break;
case NE:
e1->type = ex_integer;
e1->e.int_val = (v1[0] == v2[0])
e1->e.integer_val = (v1[0] == v2[0])
|| (v1[1] != v2[1])
|| (v1[2] != v2[2]);
break;
@ -501,6 +500,70 @@ do_op_vector (int op, expr_t *e1, expr_t *e2)
return e1;
}
static expr_t *
do_op_integer (int op, expr_t *e1, expr_t *e2)
{
int i1, i2;
i1 = e1->e.integer_val;
i2 = e2->e.integer_val;
printf ("%d %s %d\n", i1, get_op_string (op), i2);
switch (op) {
case '+':
e1->e.integer_val += i2;
break;
case '-':
e1->e.integer_val -= i2;
break;
case '*':
e1->e.integer_val *= i2;
break;
case '/':
e1->e.integer_val /= i2;
break;
case '&':
e1->e.integer_val = i1 & i2;
break;
case '|':
e1->e.integer_val = i1 | i2;
break;
case AND:
e1->e.integer_val = i1 && i2;
break;
case OR:
e1->e.integer_val = i1 || i2;
break;
case LT:
e1->type = ex_integer;
e1->e.integer_val = i1 < i2;
break;
case GT:
e1->type = ex_integer;
e1->e.integer_val = i1 > i2;
break;
case LE:
e1->type = ex_integer;
e1->e.integer_val = i1 <= i2;
break;
case GE:
e1->type = ex_integer;
e1->e.integer_val = i1 >= i2;
break;
case EQ:
e1->type = ex_integer;
e1->e.integer_val = i1 == i2;
break;
case NE:
e1->type = ex_integer;
e1->e.integer_val = i1 != i2;
break;
default:
return error (e1, "invalid operand for string");
}
return e1;
}
static expr_t *
do_op_huh (int op, expr_t *e1, expr_t *e2)
{
@ -516,6 +579,8 @@ static expr_t *(*do_op[]) (int op, expr_t *e1, expr_t *e2) = {
do_op_huh,
do_op_huh,
do_op_huh,
do_op_huh,
do_op_integer,
};
static expr_t *
@ -563,7 +628,6 @@ test_expr (expr_t *e, int test)
return unary_expr ('!', e);
switch (get_type (e)) {
case ev_integer://FIXME just return e when int opcodes are supported
case ev_type_count:
case ev_void:
error (e, "internal error");
@ -572,6 +636,7 @@ test_expr (expr_t *e, int test)
new = new_expr ();
new->type = ex_string;
break;
case ev_integer:
case ev_float:
return e;
case ev_vector:
@ -633,7 +698,7 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
if (t1 == t2) {
expr_t *e = new_binary_expr (op, e1, e2);
if ((op >= OR && op <= GT) || (op == '*' && t1 == ev_vector))
e->e.expr.type = &type_float;
e->e.expr.type = &type_integer;
else
e->e.expr.type = types[t1];
if (op == '=' && e1->type == ex_expr && e1->e.expr.op == '.') {
@ -647,6 +712,12 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
expr_t *e = new_binary_expr (op, e1, e2);
e->e.expr.type = &type_vector;
return e;
} else if (e2->type == ex_integer) {
expr_t *e = new_binary_expr (op, e1, e2);
e->e.expr.type = &type_float;
e2->type = ex_float;
e2->e.float_val = e2->e.integer_val;
return e;
} else {
goto type_mismatch;
}
@ -695,7 +766,7 @@ unary_expr (int op, expr_t *e)
return n;
}
case ex_integer:
e->e.int_val *= -1;
e->e.integer_val *= -1;
return e;
case ex_float:
e->e.float_val *= -1;
@ -733,24 +804,24 @@ unary_expr (int op, expr_t *e)
return n;
}
case ex_integer:
e->e.int_val = !e->e.int_val;
e->e.integer_val = !e->e.integer_val;
return e;
case ex_float:
e->e.int_val = !e->e.float_val;
e->e.integer_val = !e->e.float_val;
e->type = ex_integer;
return e;
case ex_string:
e->e.int_val = !e->e.string_val || !e->e.string_val[0];
e->e.integer_val = !e->e.string_val || !e->e.string_val[0];
e->type = ex_integer;
return e;
case ex_vector:
e->e.int_val = !e->e.vector_val[0]
e->e.integer_val = !e->e.vector_val[0]
&& !e->e.vector_val[1]
&& !e->e.vector_val[2];
e->type = ex_integer;
return e;
case ex_quaternion:
e->e.int_val = !e->e.quaternion_val[0]
e->e.integer_val = !e->e.quaternion_val[0]
&& !e->e.quaternion_val[1]
&& !e->e.quaternion_val[2]
&& !e->e.quaternion_val[3];
@ -830,6 +901,13 @@ emit_statement (int sline, opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_
dstatement_t *statement;
def_t *ret;
if (!op) {
expr_t e;
e.line = sline;
e.file = s_file;
error (&e, "ice ice baby\n");
abort ();
}
if (options.debug) {
int line = sline - lineno_base;

View file

@ -32,6 +32,7 @@ static hashtab_t *field_imm_defs;
static hashtab_t *func_imm_defs;
static hashtab_t *pointer_imm_defs;
static hashtab_t *quaternion_imm_defs;
static hashtab_t *integer_imm_defs;
static const char *
string_imm_get_key (void *_def, void *unused)
@ -176,32 +177,39 @@ PR_ReuseConstant (expr_t *expr, def_t *def)
func_imm_defs = Hash_NewTable (16381, int_imm_get_key, 0, "func");
pointer_imm_defs = Hash_NewTable (16381, int_imm_get_key, 0, "pointer");
quaternion_imm_defs = Hash_NewTable (16381, quaternion_imm_get_key, 0, 0);
integer_imm_defs = Hash_NewTable (16381, int_imm_get_key, 0, "integer");
}
switch (e.type) {
case ex_entity:
sprintf (rep, "\001entity:%08X\001", e.e.int_val);
sprintf (rep, "\001entity:%08X\001", e.e.integer_val);
tab = float_imm_defs;
type = &type_entity;
break;
case ex_field:
sprintf (rep, "\001field:%08X\001", e.e.int_val);
sprintf (rep, "\001field:%08X\001", e.e.integer_val);
tab = float_imm_defs;
type = &type_field;
break;
case ex_func:
sprintf (rep, "\001func:%08X\001", e.e.int_val);
sprintf (rep, "\001func:%08X\001", e.e.integer_val);
tab = float_imm_defs;
type = &type_function;
break;
case ex_pointer:
sprintf (rep, "\001pointer:%08X\001", e.e.int_val);
sprintf (rep, "\001pointer:%08X\001", e.e.integer_val);
tab = pointer_imm_defs;
type = &type_pointer;
break;
case ex_integer:
e.e.float_val = e.e.int_val; //FIXME want ints rather than floats
if (!def || def->type != &type_float) {
sprintf (rep, "\001integer:%08X\001", e.e.integer_val);
tab = integer_imm_defs;
type = &type_integer;
break;
}
e.e.float_val = e.e.integer_val;
case ex_float:
sprintf (rep, "\001float:%08X\001", e.e.int_val);
sprintf (rep, "\001float:%08X\001", e.e.integer_val);
tab = float_imm_defs;
type = &type_float;
break;
@ -258,7 +266,7 @@ PR_ReuseConstant (expr_t *expr, def_t *def)
cn->initialized = 1;
// copy the immediate to the global area
if (e.type == ex_string)
e.e.int_val = CopyString (e.e.string_val);
e.e.integer_val = CopyString (e.e.string_val);
memcpy (pr_globals + cn->ofs, &e.e, 4 * type_size[type->type]);

View file

@ -65,7 +65,7 @@ type_t type_integer = { ev_integer, &def_integer };
type_t type_floatfield = { ev_field, &def_field, NULL, &type_float };
int type_size[8] = { 1, 1, 1, 3, 1, 1, 1, 1 };
int type_size[ev_type_count] = { 1, 1, 1, 3, 1, 1, 1, 1, 4, 1 };
def_t def_void = { &type_void, "temp" };
def_t def_string = { &type_string, "temp" };

View file

@ -47,7 +47,7 @@ m ([\-+]?)
"//".* /* nothing to do */
{DIGIT}+ {
yylval.int_val = atoi (yytext);
yylval.integer_val = atoi (yytext);
return INT_VAL;
}
@ -144,18 +144,20 @@ typedef struct {
} keyword_t;
static keyword_t keywords[] = {
{"float", TYPE, &type_float },
{"vector", TYPE, &type_vector},
{"entity", TYPE, &type_entity},
{"string", TYPE, &type_string},
{"void", TYPE, &type_void },
{"local", LOCAL, 0 },
{"return", RETURN, 0 },
{"while", WHILE, 0 },
{"do", DO, 0 },
{"if", IF, 0 },
{"else", ELSE, 0 },
{"for", FOR, 0 },
{"void", TYPE, &type_void },
{"float", TYPE, &type_float },
{"string", TYPE, &type_string },
{"vector", TYPE, &type_vector },
{"entity", TYPE, &type_entity },
{"quaternion", TYPE, &type_quaternion},
{"integer", TYPE, &type_integer },
{"local", LOCAL, 0 },
{"return", RETURN, 0 },
{"while", WHILE, 0 },
{"do", DO, 0 },
{"if", IF, 0 },
{"else", ELSE, 0 },
{"for", FOR, 0 },
};
static const char *
@ -240,7 +242,7 @@ do_grab (char *token)
return -grab_other;
frame = Hash_Find (frame_tab, token);
if (frame) {
yylval.int_val = frame->num;
yylval.integer_val = frame->num;
return INT_VAL;
}
return 0;

View file

@ -37,7 +37,7 @@ typedef struct {
def_t *def;
type_t *type;
expr_t *expr;
int int_val;
int integer_val;
float float_val;
char *string_val;
float vector_val[3];
@ -55,7 +55,7 @@ typedef struct {
%left '.'
%token <string_val> NAME STRING_VAL
%token <int_val> INT_VAL
%token <integer_val> INT_VAL
%token <float_val> FLOAT_VAL
%token <vector_val> VECTOR_VAL
%token <quaternion_val> QUATERNION_VAL
@ -206,7 +206,7 @@ opt_initializer
expr_t *e = new_expr ();
e->type = ex_def;
e->e.def = current_def;
append_expr (local_expr, new_binary_expr ('=', e, $2));
append_expr (local_expr, binary_expr ('=', e, $2));
} else {
current_def = PR_ReuseConstant ($2, current_def);
}
@ -223,7 +223,7 @@ opt_initializer
f = new_function ();
f->builtin = $3->type == ex_integer
? $3->e.int_val : (int)$3->e.float_val;
? $3->e.integer_val : (int)$3->e.float_val;
f->def = current_def;
build_function (f);
finish_function (f);
@ -501,7 +501,7 @@ const
{
$$ = new_expr ();
$$->type = ex_integer;
$$->e.int_val = $1;
$$->e.integer_val = $1;
}
;

View file

@ -8,10 +8,10 @@
#include <QF/progs.h>
#include <QF/zone.h>
#define RETURN_EDICT(p, e) ((p)->pr_globals[OFS_RETURN].int_var = EDICT_TO_PROG(p, e))
#define RETURN_STRING(p, s) ((p)->pr_globals[OFS_RETURN].int_var = PR_SetString((p), s))
#define RETURN_EDICT(p, e) ((p)->pr_globals[OFS_RETURN].integer_var = EDICT_TO_PROG(p, e))
#define RETURN_STRING(p, s) ((p)->pr_globals[OFS_RETURN].integer_var = PR_SetString((p), s))
float *read_result; //FIXME: eww
int *read_result; //FIXME: eww
static void
bi_fixme (progs_t *pr)
@ -37,37 +37,37 @@ bi_GarbageCollect (progs_t *pr)
static void
bi_errno (progs_t *pr)
{
G_FLOAT (pr, OFS_RETURN) = errno;
G_INT (pr, OFS_RETURN) = errno;
}
static void
bi_strerror (progs_t *pr) // FIXME: make INT when qc int
bi_strerror (progs_t *pr)
{
int err = G_FLOAT (pr, OFS_PARM0);
int err = G_INT (pr, OFS_PARM0);
RETURN_STRING (pr, strerror (err));
}
static void
bi_open (progs_t *pr) // FIXME: make INT when qc int
bi_open (progs_t *pr)
{
char *path = G_STRING (pr, OFS_PARM0);
int flags = G_FLOAT (pr, OFS_PARM1);
int mode = G_FLOAT (pr, OFS_PARM2);
int flags = G_INT (pr, OFS_PARM1);
int mode = G_INT (pr, OFS_PARM2);
G_INT (pr, OFS_RETURN) = open (path, flags, mode);
}
static void
bi_close (progs_t *pr) // FIXME: make INT when qc int
bi_close (progs_t *pr)
{
int handle = G_INT (pr, OFS_PARM0);
G_FLOAT (pr, OFS_RETURN) = close (handle);
G_INT (pr, OFS_RETURN) = close (handle);
}
static void
bi_read (progs_t *pr) // FIXME: make INT when qc int
bi_read (progs_t *pr)
{
int handle = G_INT (pr, OFS_PARM0);
int count = G_FLOAT (pr, OFS_PARM1);
int count = G_INT (pr, OFS_PARM1);
int res;
char *buffer;
@ -81,23 +81,23 @@ bi_read (progs_t *pr) // FIXME: make INT when qc int
}
static void
bi_write (progs_t *pr) // FIXME: make INT when qc int
bi_write (progs_t *pr)
{
int handle = G_INT (pr, OFS_PARM0);
char *buffer = G_STRING (pr, OFS_PARM1);
int count = G_FLOAT (pr, OFS_PARM2);
int count = G_INT (pr, OFS_PARM2);
G_FLOAT (pr, OFS_RETURN) = write (handle, buffer, count);
G_INT (pr, OFS_RETURN) = write (handle, buffer, count);
}
static void
bi_seek (progs_t *pr) // FIXME: make INT when qc int
bi_seek (progs_t *pr)
{
int handle = G_INT (pr, OFS_PARM0);
int pos = G_FLOAT (pr, OFS_PARM1);
int whence = G_FLOAT (pr, OFS_PARM2);
int pos = G_INT (pr, OFS_PARM1);
int whence = G_INT (pr, OFS_PARM2);
G_FLOAT (pr, OFS_RETURN) = lseek (handle, pos, whence);
G_INT (pr, OFS_RETURN) = lseek (handle, pos, whence);
}
static void

View file

@ -1,12 +1,12 @@
void (string str) print = #1;
void () garbage_collect = #2;
float () errno = #3;
string (float err) strerror = #4;
float (...) open = #5; // string path, float flags[, float mode]
float (float handle) close = #6;
string (float handle, float count) read = #7; // FIXME: cf read_result
float (float handle, string buffer, float count) write = #8;
float (float handle, float pos, float whence) seek = #9;
integer () errno = #3;
string (integer err) strerror = #4;
integer (...) open = #5; // string path, float flags[, float mode]
integer (integer handle) close = #6;
string (integer handle, integer count) read = #7; // FIXME: cf read_result
integer (integer handle, string buffer, integer count) write = #8;
integer (integer handle, integer pos, integer whence) seek = #9;
void() traceon = #10; // turns statment trace on
void() traceoff = #11;
@ -14,7 +14,7 @@ void() traceoff = #11;
float time;
entity self;
float read_result; // FIXME: hacky (cf read)
integer read_result; // FIXME: hacky (cf read)
.float nextthink;
.void() think;

View file

@ -22,7 +22,7 @@ void BI_Init (progs_t *progs);
extern char *type_name[];
extern cvar_t *developer;
extern float *read_result; //FIXME: eww
extern int *read_result; //FIXME: eww
int
main ()
@ -101,7 +101,7 @@ main ()
}
printf ("\n");
#endif
read_result = (float*)PR_GetGlobalPointer (&progs, "read_result");
read_result = (int*)PR_GetGlobalPointer (&progs, "read_result");
main_func = PR_GetFunctionIndex (&progs, "main");
PR_ExecuteProgram (&progs, main_func);
return G_FLOAT (&progs, OFS_RETURN);

View file

@ -14,7 +14,7 @@ void () eek;
float () main =
{
local float messed_or;
local float handle;
local integer handle;
local string buffer;
traceon();
@ -45,7 +45,7 @@ float () baz =
void (float x) test =
{
local string str;
local float urk = 0;
local integer urk = 0;
if (urk) {
urk = foo || snafu;
@ -68,6 +68,11 @@ void () blarg =
}
};
float (float baz) test_int =
{
return baz;
};
.entity owner;
entity sent;
void () eek =
@ -76,6 +81,7 @@ void () eek =
if (sent && sent.owner != self )
self.origin = '0 0 0';
self.origin = self.origin + '1 2 3';
test_int (1);
traceoff();
};
@ -87,6 +93,6 @@ void () assign =
foo = bar;
foo = bar = 1;
foo = bar = bar + 1;
foo = self.nextthink = self.nextthink + 1;
self.frame = self.nextthink = self.nextthink + 1;
foo = self.nextthink = self.nextthink + 1.0;
self.frame = self.nextthink = self.nextthink + 1.0;
};