mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-30 12:40:42 +00:00
^ and ~ operators for qc (^ from Rhamphoryncus) and clean up the punctuation
line in qc-lex.l (why didn't I think to do that in the first place?!?)
This commit is contained in:
parent
998c3405e1
commit
081d8f3c47
10 changed files with 88 additions and 5 deletions
|
@ -159,6 +159,11 @@ typedef enum {
|
||||||
|
|
||||||
OP_CONV_IF,
|
OP_CONV_IF,
|
||||||
OP_CONV_FI,
|
OP_CONV_FI,
|
||||||
|
|
||||||
|
OP_BITXOR_F,
|
||||||
|
OP_BITXOR_I,
|
||||||
|
OP_BITNOT_F,
|
||||||
|
OP_BITNOT_I,
|
||||||
} pr_opcode_e;
|
} pr_opcode_e;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
@ -1253,6 +1253,10 @@ PR_LoadProgs (progs_t * pr, const char *progsname)
|
||||||
case OP_LOAD_I:
|
case OP_LOAD_I:
|
||||||
case OP_CONV_IF:
|
case OP_CONV_IF:
|
||||||
case OP_CONV_FI:
|
case OP_CONV_FI:
|
||||||
|
case OP_BITXOR_F:
|
||||||
|
case OP_BITXOR_I:
|
||||||
|
case OP_BITNOT_F:
|
||||||
|
case OP_BITNOT_I:
|
||||||
if ((unsigned short) st->a >= pr->progs->numglobals
|
if ((unsigned short) st->a >= pr->progs->numglobals
|
||||||
|| (unsigned short) st->b >= pr->progs->numglobals
|
|| (unsigned short) st->b >= pr->progs->numglobals
|
||||||
|| (unsigned short) st->c >= pr->progs->numglobals)
|
|| (unsigned short) st->c >= pr->progs->numglobals)
|
||||||
|
|
|
@ -363,6 +363,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
case OP_BITOR:
|
case OP_BITOR:
|
||||||
OPC.float_var = (int) OPA.float_var | (int) OPB.float_var;
|
OPC.float_var = (int) OPA.float_var | (int) OPB.float_var;
|
||||||
break;
|
break;
|
||||||
|
case OP_BITXOR_F:
|
||||||
|
OPC.float_var = (int) OPA.float_var ^ (int) OPB.float_var;
|
||||||
|
break;
|
||||||
|
case OP_BITNOT_F:
|
||||||
|
OPC.float_var = ~ (int) OPA.float_var;
|
||||||
|
break;
|
||||||
case OP_GE:
|
case OP_GE:
|
||||||
OPC.float_var = OPA.float_var >= OPB.float_var;
|
OPC.float_var = OPA.float_var >= OPB.float_var;
|
||||||
break;
|
break;
|
||||||
|
@ -663,6 +669,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
||||||
case OP_BITOR_I:
|
case OP_BITOR_I:
|
||||||
OPC.integer_var = OPA.integer_var | OPB.integer_var;
|
OPC.integer_var = OPA.integer_var | OPB.integer_var;
|
||||||
break;
|
break;
|
||||||
|
case OP_BITXOR_I:
|
||||||
|
OPC.integer_var = OPA.integer_var ^ OPB.integer_var;
|
||||||
|
break;
|
||||||
|
case OP_BITNOT_I:
|
||||||
|
OPC.integer_var = ~OPA.integer_var;
|
||||||
|
break;
|
||||||
case OP_GE_I:
|
case OP_GE_I:
|
||||||
OPC.integer_var = OPA.integer_var >= OPB.integer_var;
|
OPC.integer_var = OPA.integer_var >= OPB.integer_var;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -145,6 +145,10 @@ opcode_t pr_opcodes[] = {
|
||||||
{"=", "storep.i", OP_STOREP_I, 5, true, ev_pointer, 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},
|
{".", "load.i", OP_LOAD_I, 1, false, ev_entity, ev_field, ev_integer, PROG_VERSION},
|
||||||
|
|
||||||
|
{"^", "bitxor.f", OP_BITXOR_F, 2, false, ev_float, ev_float, ev_float, PROG_VERSION},
|
||||||
|
{"^", "bitxor.i", OP_BITXOR_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||||
|
{"~", "bitnot.f", OP_BITNOT_F, -1, false, ev_float, ev_void, ev_float, PROG_VERSION},
|
||||||
|
{"~", "bitnot.i", OP_BITNOT_I, -1, false, ev_integer, ev_void, ev_integer, PROG_VERSION},
|
||||||
{0},
|
{0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -224,6 +224,10 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
||||||
operator = "&";
|
operator = "&";
|
||||||
priority = 2;
|
priority = 2;
|
||||||
break;
|
break;
|
||||||
|
case '^':
|
||||||
|
operator = "^";
|
||||||
|
priority = 2;
|
||||||
|
break;
|
||||||
case '|':
|
case '|':
|
||||||
operator = "|";
|
operator = "|";
|
||||||
priority = 2;
|
priority = 2;
|
||||||
|
@ -245,6 +249,11 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
||||||
priority = -1;
|
priority = -1;
|
||||||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||||
def_b = &def_void;
|
def_b = &def_void;
|
||||||
|
} else if (e->e.expr.op == '~') {
|
||||||
|
operator = "~";
|
||||||
|
priority = -1;
|
||||||
|
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||||
|
def_b = &def_void;
|
||||||
} else if (e->e.expr.op == '-') {
|
} else if (e->e.expr.op == '-') {
|
||||||
static expr_t zero;
|
static expr_t zero;
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,8 @@ get_op_string (int op)
|
||||||
case '/': return "/";
|
case '/': return "/";
|
||||||
case '&': return "&";
|
case '&': return "&";
|
||||||
case '|': return "|";
|
case '|': return "|";
|
||||||
|
case '^': return "^";
|
||||||
|
case '~': return "~";
|
||||||
case '!': return "!";
|
case '!': return "!";
|
||||||
case '(': return "(";
|
case '(': return "(";
|
||||||
case '.': return ".";
|
case '.': return ".";
|
||||||
|
@ -407,6 +409,9 @@ do_op_float (int op, expr_t *e1, expr_t *e2)
|
||||||
case '|':
|
case '|':
|
||||||
e1->e.float_val = (int)f1 | (int)f2;
|
e1->e.float_val = (int)f1 | (int)f2;
|
||||||
break;
|
break;
|
||||||
|
case '^':
|
||||||
|
e1->e.float_val = (int)f1 ^ (int)f2;
|
||||||
|
break;
|
||||||
case AND:
|
case AND:
|
||||||
e1->type = ex_integer;
|
e1->type = ex_integer;
|
||||||
e1->e.integer_val = f1 && f2;
|
e1->e.integer_val = f1 && f2;
|
||||||
|
@ -510,6 +515,9 @@ do_op_integer (int op, expr_t *e1, expr_t *e2)
|
||||||
case '|':
|
case '|':
|
||||||
e1->e.integer_val = i1 | i2;
|
e1->e.integer_val = i1 | i2;
|
||||||
break;
|
break;
|
||||||
|
case '^':
|
||||||
|
e1->e.integer_val = i1 ^ i2;
|
||||||
|
break;
|
||||||
case AND:
|
case AND:
|
||||||
e1->e.integer_val = i1 && i2;
|
e1->e.integer_val = i1 && i2;
|
||||||
break;
|
break;
|
||||||
|
@ -850,6 +858,42 @@ unary_expr (int op, expr_t *e)
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case '~':
|
||||||
|
switch (e->type) {
|
||||||
|
case ex_label:
|
||||||
|
case ex_block:
|
||||||
|
abort ();
|
||||||
|
case ex_uexpr:
|
||||||
|
if (e->e.expr.op == '~')
|
||||||
|
return e->e.expr.e1;
|
||||||
|
case ex_expr:
|
||||||
|
case ex_def:
|
||||||
|
{
|
||||||
|
expr_t *n = new_unary_expr (op, e);
|
||||||
|
type_t *t = e->type == ex_expr ? e->e.expr.type
|
||||||
|
: e->e.def->type;
|
||||||
|
if (t != &type_integer && t != &type_float)
|
||||||
|
return error (e, "invalid type for unary ~");
|
||||||
|
n->e.expr.type = t;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
case ex_integer:
|
||||||
|
e->e.integer_val = ~e->e.integer_val;
|
||||||
|
return e;
|
||||||
|
case ex_float:
|
||||||
|
e->e.float_val = ~(int)e->e.float_val;
|
||||||
|
e->type = ex_integer;
|
||||||
|
return e;
|
||||||
|
case ex_string:
|
||||||
|
case ex_vector:
|
||||||
|
case ex_quaternion:
|
||||||
|
case ex_entity:
|
||||||
|
case ex_field:
|
||||||
|
case ex_func:
|
||||||
|
case ex_pointer:
|
||||||
|
return error (e, "invalid type for unary ~");
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,6 +369,9 @@ PR_LexPunctuation (void)
|
||||||
p = "|";
|
p = "|";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case '^':
|
||||||
|
p = "^";
|
||||||
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
if (pr_file_p[1] == '=') {
|
if (pr_file_p[1] == '=') {
|
||||||
p = "<=";
|
p = "<=";
|
||||||
|
|
|
@ -95,7 +95,7 @@ m ([\-+]?)
|
||||||
s_file = ReuseString (pr_immediate_string);
|
s_file = ReuseString (pr_immediate_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
"!"|"("|")"|"{"|"}"|"."|"*"|"/"|"&"|"|"|"+"|"-"|"="|"["|"]"|";"|","|"#" return yytext[0];
|
[!(){}.*/&|^~+\-=\[\];,#] return yytext[0];
|
||||||
|
|
||||||
"..." return ELIPSIS;
|
"..." return ELIPSIS;
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,8 @@ typedef struct {
|
||||||
%left OR AND
|
%left OR AND
|
||||||
%left EQ NE LE GE LT GT
|
%left EQ NE LE GE LT GT
|
||||||
%left '+' '-'
|
%left '+' '-'
|
||||||
%left '*' '/' '&' '|'
|
%left '*' '/' '&' '|' '^'
|
||||||
%left '!'
|
%left '!' '~'
|
||||||
%right '('
|
%right '('
|
||||||
%left '.'
|
%left '.'
|
||||||
|
|
||||||
|
@ -454,11 +454,13 @@ expr
|
||||||
| expr '/' expr { $$ = binary_expr ('/', $1, $3); }
|
| expr '/' expr { $$ = binary_expr ('/', $1, $3); }
|
||||||
| expr '&' expr { $$ = binary_expr ('&', $1, $3); }
|
| expr '&' expr { $$ = binary_expr ('&', $1, $3); }
|
||||||
| expr '|' expr { $$ = binary_expr ('|', $1, $3); }
|
| expr '|' expr { $$ = binary_expr ('|', $1, $3); }
|
||||||
|
| expr '^' expr { $$ = binary_expr ('^', $1, $3); }
|
||||||
| expr '(' arg_list ')' { $$ = function_expr ($1, $3); }
|
| expr '(' arg_list ')' { $$ = function_expr ($1, $3); }
|
||||||
| expr '(' ')' { $$ = function_expr ($1, 0); }
|
| expr '(' ')' { $$ = function_expr ($1, 0); }
|
||||||
| expr '.' expr { $$ = binary_expr ('.', $1, $3); }
|
| expr '.' expr { $$ = binary_expr ('.', $1, $3); }
|
||||||
| '-' expr %prec '!' { $$ = unary_expr ('-', $2); }
|
| '-' expr %prec '!' { $$ = unary_expr ('-', $2); }
|
||||||
| '!' expr { $$ = unary_expr ('!', $2); }
|
| '!' expr { $$ = unary_expr ('!', $2); }
|
||||||
|
| '~' expr { $$ = unary_expr ('~', $2); }
|
||||||
| NAME
|
| NAME
|
||||||
{
|
{
|
||||||
$$ = new_expr ();
|
$$ = new_expr ();
|
||||||
|
|
|
@ -94,9 +94,9 @@ void () eek =
|
||||||
if (bop)
|
if (bop)
|
||||||
traceoff();
|
traceoff();
|
||||||
printf ("%v\n", v);
|
printf ("%v\n", v);
|
||||||
v = 2 * v;
|
v = ~2 * v;
|
||||||
printf ("%v\n", v);
|
printf ("%v\n", v);
|
||||||
v = v * 2;
|
v = v * ~2;
|
||||||
printf ("%v\n", v);
|
printf ("%v\n", v);
|
||||||
v = -v;
|
v = -v;
|
||||||
printf ("%v\n", v);
|
printf ("%v\n", v);
|
||||||
|
|
Loading…
Reference in a new issue