got a few new operators for qc :)

<< >> % which all act like their C counterparts
+= -= *= /= &= ^= |= <<= >>= %= which just expand into the obvious,
also like the C versions.
This commit is contained in:
Adam Olsen 2001-08-10 16:17:00 +00:00
parent ca4d4791c9
commit 6414897dae
10 changed files with 151 additions and 6 deletions

View File

@ -164,6 +164,14 @@ typedef enum {
OP_BITXOR_I,
OP_BITNOT_F,
OP_BITNOT_I,
OP_SHL_F,
OP_SHR_F,
OP_SHL_I,
OP_SHR_I,
OP_MOD_F,
OP_MOD_I,
} pr_opcode_e;
typedef struct

View File

@ -1239,6 +1239,8 @@ PR_LoadProgs (progs_t * pr, const char *progsname)
case OP_SUB_I:
case OP_MUL_I:
case OP_DIV_I:
case OP_MOD_I:
case OP_MOD_F:
case OP_BITAND_I:
case OP_BITOR_I:
case OP_GE_I:
@ -1257,6 +1259,10 @@ PR_LoadProgs (progs_t * pr, const char *progsname)
case OP_BITXOR_I:
case OP_BITNOT_F:
case OP_BITNOT_I:
case OP_SHL_F:
case OP_SHR_F:
case OP_SHL_I:
case OP_SHR_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

@ -369,6 +369,18 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_BITNOT_F:
OPC.float_var = ~ (int) OPA.float_var;
break;
case OP_SHL_F:
OPC.float_var = (int) OPA.float_var << (int) OPB.float_var;
break;
case OP_SHR_F:
OPC.float_var = (int) OPA.float_var >> (int) OPB.float_var;
break;
case OP_SHL_I:
OPC.integer_var = OPA.integer_var << OPB.integer_var;
break;
case OP_SHR_I:
OPC.integer_var = OPA.integer_var >> OPB.integer_var;
break;
case OP_GE:
OPC.float_var = OPA.float_var >= OPB.float_var;
break;
@ -657,6 +669,12 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_DIV_I:
OPC.integer_var = OPA.integer_var / OPB.integer_var;
break;
case OP_MOD_I:
OPC.integer_var = OPA.integer_var % OPB.integer_var;
break;
case OP_MOD_F:
OPC.float_var = (int) OPA.float_var % (int) OPB.float_var;
break;
case OP_CONV_IF:
OPC.float_var = OPA.integer_var;
break;

View File

@ -123,6 +123,11 @@ opcode_t pr_opcodes[] = {
{"&&", "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},
{"<<", "shl.f", OP_SHL_F, 2, false, ev_float, ev_float, ev_float, PROG_VERSION},
{">>", "shr.f", OP_SHR_F, 2, false, ev_float, ev_float, ev_float, PROG_VERSION},
{"<<", "shl.i", OP_SHL_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{">>", "shr.i", OP_SHR_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_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},
@ -130,6 +135,8 @@ opcode_t pr_opcodes[] = {
{"-", "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},
{"%", "mod_i", OP_MOD_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"%", "mod.f", OP_MOD_F, 2, false, ev_float, ev_float, ev_float, 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},

View File

@ -76,6 +76,7 @@ void convert_int (expr_t *e);
expr_t *test_expr (expr_t *e, int test);
expr_t *binary_expr (int op, expr_t *e1, expr_t *e2);
expr_t *asx_expr (int op, expr_t *e1, expr_t *e2);
expr_t *unary_expr (int op, expr_t *e);
expr_t *function_expr (expr_t *e1, expr_t *e2);
expr_t *return_expr (function_t *f, expr_t *e);

View File

@ -232,6 +232,18 @@ emit_sub_expr (expr_t *e, def_t *dest)
operator = "|";
priority = 2;
break;
case '%':
operator = "%";
priority = 2;
break;
case SHL:
operator = "<<";
priority = 2;
break;
case SHR:
operator = ">>";
priority = 2;
break;
case '.':
operator = ".";
priority = 1;

View File

@ -169,6 +169,8 @@ get_op_string (int op)
case '^': return "^";
case '~': return "~";
case '!': return "!";
case SHL: return "<<";
case SHR: return ">>";
case '(': return "(";
case '.': return ".";
case 'i': return "<if>";
@ -412,6 +414,15 @@ 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 SHL:
e1->e.float_val = (int)f1 << (int)f2;
break;
case SHR:
e1->e.float_val = (int)f1 >> (int)f2;
break;
case AND:
e1->type = ex_integer;
e1->e.integer_val = f1 && f2;
@ -518,6 +529,15 @@ 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 SHL:
e1->e.integer_val = i1 << i2;
break;
case SHR:
e1->e.integer_val = i1 >> i2;
break;
case AND:
e1->e.integer_val = i1 && i2;
break;
@ -763,6 +783,36 @@ type_mismatch:
return e;
}
expr_t *
asx_expr (int op, expr_t *e1, expr_t *e2)
{
switch (op) {
case ASADD:
return binary_expr ('=', e1, binary_expr ('+', e1, e2));
case ASSUB:
return binary_expr ('=', e1, binary_expr ('-', e1, e2));
case ASMUL:
return binary_expr ('=', e1, binary_expr ('*', e1, e2));
case ASDIV:
return binary_expr ('=', e1, binary_expr ('/', e1, e2));
case ASAND:
return binary_expr ('=', e1, binary_expr ('&', e1, e2));
case ASOR:
return binary_expr ('=', e1, binary_expr ('|', e1, e2));
case ASXOR:
return binary_expr ('=', e1, binary_expr ('^', e1, e2));
case ASMOD:
return binary_expr ('=', e1, binary_expr ('%', e1, e2));
case ASSHL:
return binary_expr ('=', e1, binary_expr (SHL, e1, e2));
case ASSHR:
return binary_expr ('=', e1, binary_expr (SHR, e1, e2));
default:
error (e1, "invalid operand for asx");
}
return 0;
}
expr_t *
unary_expr (int op, expr_t *e)
{

View File

@ -95,10 +95,24 @@ m ([\-+]?)
s_file = ReuseString (pr_immediate_string);
}
[!(){}.*/&|^~+\-=\[\];,#] return yytext[0];
[!(){}.*/&|^~+\-=\[\];,#%] return yytext[0];
"..." return ELIPSIS;
"+=" return ASADD;
"-=" return ASSUB;
"*=" return ASMUL;
"/=" return ASDIV;
"&=" return ASAND;
"|=" return ASOR;
"^=" return ASXOR;
"%=" return ASMOD;
"<<=" return ASSHL;
">>=" return ASSHR;
"<<" return SHL;
">>" return SHR;
"&&" return AND;
"||" return OR;
"==" return EQ;

View File

@ -45,11 +45,12 @@ typedef struct {
function_t *function;
}
%right '='
%right '=' ASADD ASSUB ASMUL ASDIV ASAND ASOR ASXOR ASMOD ASSHL ASSHR
%left OR AND
%left EQ NE LE GE LT GT
%left SHL SHR
%left '+' '-'
%left '*' '/' '&' '|' '^'
%left '*' '/' '&' '|' '^' '%'
%left '!' '~'
%right '('
%left '.'
@ -440,6 +441,18 @@ opt_expr
expr
: expr '=' expr { $$ = binary_expr ('=', $1, $3); }
| expr ASADD expr { $$ = asx_expr (ASADD, $1, $3); }
| expr ASSUB expr { $$ = asx_expr (ASSUB, $1, $3); }
| expr ASMUL expr { $$ = asx_expr (ASMUL, $1, $3); }
| expr ASDIV expr { $$ = asx_expr (ASDIV, $1, $3); }
| expr ASAND expr { $$ = asx_expr (ASAND, $1, $3); }
| expr ASOR expr { $$ = asx_expr (ASOR, $1, $3); }
| expr ASXOR expr { $$ = asx_expr (ASXOR, $1, $3); }
| expr ASMOD expr { $$ = asx_expr (ASMOD, $1, $3); }
| expr ASSHL expr { $$ = asx_expr (ASSHL, $1, $3); }
| expr ASSHR expr { $$ = asx_expr (ASSHR, $1, $3); }
| expr SHL expr { $$ = binary_expr (SHL, $1, $3); }
| expr SHR expr { $$ = binary_expr (SHR, $1, $3); }
| expr AND expr { $$ = binary_expr (AND, $1, $3); }
| expr OR expr { $$ = binary_expr (OR, $1, $3); }
| expr EQ expr { $$ = binary_expr (EQ, $1, $3); }
@ -455,6 +468,7 @@ 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); }

View File

@ -12,7 +12,7 @@ float negative = -------2;
void () eek;
float () main =
{
{/*
local float messed_or;
local integer handle;
local string buffer;
@ -33,8 +33,23 @@ float () main =
print (buffer);
} while (read_result == 1024);
close (handle);
eek ();
return 0;
eek ();*/
traceon();
local float foo = 0;
foo += 1;
foo *= 3;
foo -= 5;
foo &= 11;
foo /= 3;
foo ^= 1;
foo |= 7;
foo <<= 3;
foo >>= 1;
local integer bar;
bar = 12 % 5;
bar %= 3;
foo %= 5;
return foo;
};
float () baz =