^ 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:
Bill Currie 2001-08-09 16:34:46 +00:00
parent 998c3405e1
commit 081d8f3c47
10 changed files with 88 additions and 5 deletions

View file

@ -159,6 +159,11 @@ typedef enum {
OP_CONV_IF,
OP_CONV_FI,
OP_BITXOR_F,
OP_BITXOR_I,
OP_BITNOT_F,
OP_BITNOT_I,
} pr_opcode_e;
typedef struct

View file

@ -1253,6 +1253,10 @@ PR_LoadProgs (progs_t * pr, const char *progsname)
case OP_LOAD_I:
case OP_CONV_IF:
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
|| (unsigned short) st->b >= pr->progs->numglobals
|| (unsigned short) st->c >= pr->progs->numglobals)

View file

@ -363,6 +363,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_BITOR:
OPC.float_var = (int) OPA.float_var | (int) OPB.float_var;
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:
OPC.float_var = OPA.float_var >= OPB.float_var;
break;
@ -663,6 +669,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_BITOR_I:
OPC.integer_var = OPA.integer_var | OPB.integer_var;
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:
OPC.integer_var = OPA.integer_var >= OPB.integer_var;
break;

View file

@ -145,6 +145,10 @@ opcode_t pr_opcodes[] = {
{"=", "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},
{"^", "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},
};

View file

@ -224,6 +224,10 @@ emit_sub_expr (expr_t *e, def_t *dest)
operator = "&";
priority = 2;
break;
case '^':
operator = "^";
priority = 2;
break;
case '|':
operator = "|";
priority = 2;
@ -245,6 +249,11 @@ emit_sub_expr (expr_t *e, def_t *dest)
priority = -1;
def_a = emit_sub_expr (e->e.expr.e1, 0);
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 == '-') {
static expr_t zero;

View file

@ -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 ".";
@ -407,6 +409,9 @@ do_op_float (int op, expr_t *e1, expr_t *e2)
case '|':
e1->e.float_val = (int)f1 | (int)f2;
break;
case '^':
e1->e.float_val = (int)f1 ^ (int)f2;
break;
case AND:
e1->type = ex_integer;
e1->e.integer_val = f1 && f2;
@ -510,6 +515,9 @@ do_op_integer (int op, expr_t *e1, expr_t *e2)
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;
@ -850,6 +858,42 @@ unary_expr (int op, expr_t *e)
abort ();
}
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:
abort ();
}

View file

@ -369,6 +369,9 @@ PR_LexPunctuation (void)
p = "|";
}
break;
case '^':
p = "^";
break;
case '<':
if (pr_file_p[1] == '=') {
p = "<=";

View file

@ -95,7 +95,7 @@ m ([\-+]?)
s_file = ReuseString (pr_immediate_string);
}
"!"|"("|")"|"{"|"}"|"."|"*"|"/"|"&"|"|"|"+"|"-"|"="|"["|"]"|";"|","|"#" return yytext[0];
[!(){}.*/&|^~+\-=\[\];,#] return yytext[0];
"..." return ELIPSIS;

View file

@ -49,8 +49,8 @@ typedef struct {
%left OR AND
%left EQ NE LE GE LT GT
%left '+' '-'
%left '*' '/' '&' '|'
%left '!'
%left '*' '/' '&' '|' '^'
%left '!' '~'
%right '('
%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 '(' arg_list ')' { $$ = function_expr ($1, $3); }
| expr '(' ')' { $$ = function_expr ($1, 0); }
| expr '.' expr { $$ = binary_expr ('.', $1, $3); }
| '-' expr %prec '!' { $$ = unary_expr ('-', $2); }
| '!' expr { $$ = unary_expr ('!', $2); }
| '~' expr { $$ = unary_expr ('~', $2); }
| NAME
{
$$ = new_expr ();

View file

@ -94,9 +94,9 @@ void () eek =
if (bop)
traceoff();
printf ("%v\n", v);
v = 2 * v;
v = ~2 * v;
printf ("%v\n", v);
v = v * 2;
v = v * ~2;
printf ("%v\n", v);
v = -v;
printf ("%v\n", v);