^ 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_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

View file

@ -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)

View file

@ -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;

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}, {"=", "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},
}; };

View file

@ -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;

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 "~";
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 ();
} }

View file

@ -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 = "<=";

View file

@ -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;

View file

@ -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 ();

View file

@ -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);