new opcode: state.f. same as state, but takes a 3rd float operand to

specify the step for calculating nextthink. accessed using
[frame, think, step] (state is [frame, think])
This commit is contained in:
Bill Currie 2004-02-11 01:43:33 +00:00
parent 1fc517f7db
commit c3f41e3e69
9 changed files with 94 additions and 23 deletions

View file

@ -287,6 +287,7 @@ typedef enum {
OP_CONV_IU, OP_CONV_IU,
OP_CONV_UI, OP_CONV_UI,
OP_STATE_F,
} pr_opcode_e; } pr_opcode_e;
typedef struct opcode_s { typedef struct opcode_s {

View file

@ -733,6 +733,13 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
ed->v[pr->fields.frame].float_var = OPA.float_var; ed->v[pr->fields.frame].float_var = OPA.float_var;
ed->v[pr->fields.think].func_var = OPB.func_var; ed->v[pr->fields.think].func_var = OPB.func_var;
break; break;
case OP_STATE_F:
ed = PROG_TO_EDICT (pr, *pr->globals.self);
ed->v[pr->fields.nextthink].float_var = *pr->globals.time +
OPC.float_var;
ed->v[pr->fields.frame].float_var = OPA.float_var;
ed->v[pr->fields.think].func_var = OPB.func_var;
break;
case OP_ADD_I: case OP_ADD_I:
OPC.integer_var = OPA.integer_var + OPB.integer_var; OPC.integer_var = OPA.integer_var + OPB.integer_var;
break; break;

View file

@ -746,11 +746,17 @@ opcode_t pr_opcodes[] = {
}, },
{"<STATE>", "state", OP_STATE, false, {"<STATE>", "state", OP_STATE, false,
ev_float, ev_float, ev_void, ev_float, ev_func, ev_void,
PROG_ID_VERSION, PROG_ID_VERSION,
"%Ga, %Gb", "%Ga, %Gb",
}, },
{"<STATE>", "state.f", OP_STATE_F, false,
ev_float, ev_func, ev_float,
PROG_ID_VERSION,
"%Ga, %Gb, %Gc",
},
{"<GOTO>", "goto", OP_GOTO, false, {"<GOTO>", "goto", OP_GOTO, false,
ev_integer, ev_void, ev_void, ev_integer, ev_void, ev_void,
PROG_ID_VERSION, PROG_ID_VERSION,
@ -1118,7 +1124,7 @@ PR_Check_Opcodes (progs_t *pr)
"statement %ld", st->op, "statement %ld", st->op,
(long)(st - pr->pr_statements)); (long)(st - pr->pr_statements));
} }
if (st->op == OP_STATE && !state_ok) { if ((st->op == OP_STATE || st->op == OP_STATE_F) && !state_ok) {
PR_Error (pr, "PR_Check_Opcodes: %s used with missing fields " PR_Error (pr, "PR_Check_Opcodes: %s used with missing fields "
"or globals", op->opname); "or globals", op->opname);
} }
@ -1148,12 +1154,14 @@ PR_Check_Opcodes (progs_t *pr)
check_global (pr, st, op, ev_void, st->c); check_global (pr, st, op, ev_void, st->c);
break; break;
case OP_STATE: case OP_STATE:
case OP_STATE_F:
if (!state_ok) { if (!state_ok) {
PR_Error (pr, "PR_Check_Opcodes: %s used with missing " PR_Error (pr, "PR_Check_Opcodes: %s used with missing "
"fields or globals", op->opname); "fields or globals", op->opname);
} }
check_global (pr, st, op, op->type_a, st->a); check_global (pr, st, op, op->type_a, st->a);
check_global (pr, st, op, op->type_b, st->b); check_global (pr, st, op, op->type_b, st->b);
check_global (pr, st, op, op->type_c, st->c);
break; break;
default: default:
check_global (pr, st, op, op->type_a, st->a); check_global (pr, st, op, op->type_a, st->a);

View file

@ -36,6 +36,7 @@
typedef enum { typedef enum {
ex_error, ex_error,
ex_state,
ex_bool, ex_bool,
ex_label, ex_label,
ex_block, ex_block,
@ -97,6 +98,12 @@ typedef struct {
struct expr_s *e; struct expr_s *e;
} ex_bool_t; } ex_bool_t;
typedef struct {
struct expr_s *frame;
struct expr_s *think;
struct expr_s *step;
} ex_state_t;
#define POINTER_VAL(p) (((p).def ? (p).def->ofs : 0) + (p).val) #define POINTER_VAL(p) (((p).def ? (p).def->ofs : 0) + (p).val)
typedef struct expr_s { typedef struct expr_s {
@ -108,6 +115,7 @@ typedef struct expr_s {
unsigned rvalue:1; unsigned rvalue:1;
union { union {
ex_label_t label; ex_label_t label;
ex_state_t state;
ex_bool_t bool; ex_bool_t bool;
ex_block_t block; ex_block_t block;
struct { struct {
@ -149,6 +157,7 @@ expr_t *new_expr (void);
const char *new_label_name (void); const char *new_label_name (void);
expr_t *new_label_expr (void); expr_t *new_label_expr (void);
expr_t *new_state_expr (expr_t *frame, expr_t *think, expr_t *step);
expr_t *new_bool_expr (ex_list_t *true_list, ex_list_t *false_list, expr_t *e); expr_t *new_bool_expr (ex_list_t *true_list, ex_list_t *false_list, expr_t *e);
expr_t *new_block_expr (void); expr_t *new_block_expr (void);
expr_t *new_binary_expr (int op, expr_t *e1, expr_t *e2); expr_t *new_binary_expr (int op, expr_t *e1, expr_t *e2);

View file

@ -41,6 +41,7 @@ extern struct opcode_s *op_ifb;
extern struct opcode_s *op_ifae; extern struct opcode_s *op_ifae;
extern struct opcode_s *op_ifa; extern struct opcode_s *op_ifa;
extern struct opcode_s *op_state; extern struct opcode_s *op_state;
extern struct opcode_s *op_state_f;
extern struct opcode_s *op_goto; extern struct opcode_s *op_goto;
extern struct opcode_s *op_jump; extern struct opcode_s *op_jump;
extern struct opcode_s *op_jumpb; extern struct opcode_s *op_jumpb;

View file

@ -577,6 +577,7 @@ emit_sub_expr (expr_t *e, def_t *dest)
d = emit_sub_expr (res, dest); d = emit_sub_expr (res, dest);
} }
break; break;
case ex_state:
case ex_bool: case ex_bool:
case ex_name: case ex_name:
case ex_nil: case ex_nil:
@ -764,7 +765,9 @@ emit_expr (expr_t *e)
def_t *def; def_t *def;
def_t *def_a; def_t *def_a;
def_t *def_b; def_t *def_b;
def_t *def_c;
ex_label_t *label; ex_label_t *label;
opcode_t *op;
//printf ("%d ", e->line); //printf ("%d ", e->line);
//print_expr (e); //print_expr (e);
@ -772,14 +775,26 @@ emit_expr (expr_t *e)
switch (e->type) { switch (e->type) {
case ex_error: case ex_error:
break; break;
case ex_state:
def_a = emit_sub_expr (e->e.state.frame, 0);
def_b = emit_sub_expr (e->e.state.think, 0);
if (e->e.state.step) {
def_c = emit_sub_expr (e->e.state.step, 0);
op = op_state_f;
} else {
def_c = 0;
op = op_state;
}
emit_statement (e, op, def_a, def_b, def_c);
break;
case ex_bool:
emit_bool_expr (e);
break;
case ex_label: case ex_label:
label = &e->e.label; label = &e->e.label;
label->ofs = pr.code->size; label->ofs = pr.code->size;
relocate_refs (label->refs, label->ofs); relocate_refs (label->refs, label->ofs);
break; break;
case ex_bool:
emit_bool_expr (e);
break;
case ex_block: case ex_block:
for (e = e->e.block.head; e; e = e->next) for (e = e->e.block.head; e; e = e->next)
emit_expr (e); emit_expr (e);
@ -814,11 +829,6 @@ emit_expr (expr_t *e)
case 'c': case 'c':
emit_function_call (e, 0); emit_function_call (e, 0);
break; break;
case 's':
def_a = emit_sub_expr (e->e.expr.e1, 0);
def_b = emit_sub_expr (e->e.expr.e2, 0);
emit_statement (e, op_state, def_a, def_b, 0);
break;
case 'b': case 'b':
emit_bind_expr (e->e.expr.e1, e->e.expr.e2); emit_bind_expr (e->e.expr.e1, e->e.expr.e2);
break; break;

View file

@ -68,8 +68,9 @@ int lineno_base;
etype_t qc_types[] = { etype_t qc_types[] = {
ev_void, // ex_error ev_void, // ex_error
ev_void, // ex_label ev_void, // ex_state
ev_void, // ex_bool ev_void, // ex_bool
ev_void, // ex_label
ev_void, // ex_block ev_void, // ex_block
ev_void, // ex_expr ev_void, // ex_expr
ev_void, // ex_uexpr ev_void, // ex_uexpr
@ -185,6 +186,7 @@ get_type (expr_t *e)
return &type_float; return &type_float;
return &type_integer; return &type_integer;
case ex_nil: case ex_nil:
case ex_state:
return &type_void; return &type_void;
case ex_block: case ex_block:
if (e->e.block.result) if (e->e.block.result)
@ -345,16 +347,15 @@ new_error_expr (void)
} }
expr_t * expr_t *
new_label_expr (void) new_state_expr (expr_t *frame, expr_t *think, expr_t *step)
{ {
expr_t *s = new_expr ();
expr_t *l = new_expr (); s->type = ex_state;
s->e.state.frame = frame;
l->type = ex_label; s->e.state.think = think;
l->e.label.name = new_label_name (); s->e.state.step = step;
l->e.label.next = pr.labels; return s;
pr.labels = &l->e.label;
return l;
} }
expr_t * expr_t *
@ -369,6 +370,19 @@ new_bool_expr (ex_list_t *true_list, ex_list_t *false_list, expr_t *e)
return b; return b;
} }
expr_t *
new_label_expr (void)
{
expr_t *l = new_expr ();
l->type = ex_label;
l->e.label.name = new_label_name ();
l->e.label.next = pr.labels;
pr.labels = &l->e.label;
return l;
}
expr_t * expr_t *
new_block_expr (void) new_block_expr (void)
{ {
@ -677,6 +691,15 @@ print_expr (expr_t *e)
case ex_error: case ex_error:
printf ("(error)"); printf ("(error)");
break; break;
case ex_state:
printf ("[");
print_expr (e->e.state.frame);
printf (",");
print_expr (e->e.state.think);
printf (",");
print_expr (e->e.state.step);
printf ("]");
break;
case ex_bool: case ex_bool:
printf ("bool"); //FIXME printf ("bool"); //FIXME
break; break;
@ -1598,6 +1621,7 @@ unary_expr (int op, expr_t *e)
case ex_error: case ex_error:
case ex_label: case ex_label:
case ex_name: case ex_name:
case ex_state:
error (e, "internal error"); error (e, "internal error");
abort (); abort ();
case ex_uexpr: case ex_uexpr:
@ -1652,6 +1676,7 @@ unary_expr (int op, expr_t *e)
case ex_error: case ex_error:
case ex_label: case ex_label:
case ex_name: case ex_name:
case ex_state:
error (e, "internal error"); error (e, "internal error");
abort (); abort ();
case ex_bool: case ex_bool:
@ -1716,6 +1741,7 @@ unary_expr (int op, expr_t *e)
case ex_error: case ex_error:
case ex_label: case ex_label:
case ex_name: case ex_name:
case ex_state:
error (e, "internal error"); error (e, "internal error");
abort (); abort ();
case ex_uexpr: case ex_uexpr:

View file

@ -62,6 +62,7 @@ opcode_t *op_ifb;
opcode_t *op_ifae; opcode_t *op_ifae;
opcode_t *op_ifa; opcode_t *op_ifa;
opcode_t *op_state; opcode_t *op_state;
opcode_t *op_state_f;
opcode_t *op_goto; opcode_t *op_goto;
opcode_t *op_jump; opcode_t *op_jump;
opcode_t *op_jumpb; opcode_t *op_jumpb;
@ -164,7 +165,10 @@ opcode_init (void)
} else if (!strcmp (op->name, "<IFA>")) { } else if (!strcmp (op->name, "<IFA>")) {
op_ifa = op; op_ifa = op;
} else if (!strcmp (op->name, "<STATE>")) { } else if (!strcmp (op->name, "<STATE>")) {
op_state = op; if (op->type_c == ev_float)
op_state_f = op;
else
op_state = op;
} else if (!strcmp (op->name, "<GOTO>")) { } else if (!strcmp (op->name, "<GOTO>")) {
op_goto = op; op_goto = op;
} else if (!strcmp (op->name, "<JUMP>")) { } else if (!strcmp (op->name, "<JUMP>")) {

View file

@ -160,7 +160,7 @@ expr_t *argv_expr (void);
%type <param> param param_list %type <param> param param_list
%type <def> def_name opt_initializer methoddef var_initializer %type <def> def_name opt_initializer methoddef var_initializer
%type <expr> const opt_expr fexpr expr element_list element_list1 element %type <expr> const opt_expr fexpr expr element_list element_list1 element
%type <expr> string_val opt_state_expr array_decl %type <expr> string_val opt_state_expr opt_step array_decl
%type <expr> statement statements statement_block %type <expr> statement statements statement_block
%type <expr> label break_label continue_label enum_list enum %type <expr> label break_label continue_label enum_list enum
%type <expr> unary_expr primary cast_expr opt_arg_list arg_list %type <expr> unary_expr primary cast_expr opt_arg_list arg_list
@ -554,7 +554,7 @@ opt_state_expr
{ {
$$ = 0; $$ = 0;
} }
| '[' const ',' { $<type>$ = &type_function; } def_name ']' | '[' const ',' { $<type>$ = &type_function; } def_name opt_step ']'
{ {
if ($2->type == ex_integer) if ($2->type == ex_integer)
convert_int ($2); convert_int ($2);
@ -565,10 +565,15 @@ opt_state_expr
if ($5->type->type != ev_func) if ($5->type->type != ev_func)
error ($2, "invalid type for think"); error ($2, "invalid type for think");
$$ = new_binary_expr ('s', $2, new_def_expr ($5)); $$ = new_state_expr ($2, new_def_expr ($5), $6);
} }
; ;
opt_step
: ',' fexpr { $$ = $2; }
| /* empty */ { $$ = 0; }
;
element_list element_list
: /* empty */ : /* empty */
{ {