mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
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:
parent
ca4d4791c9
commit
6414897dae
10 changed files with 151 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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 =
|
||||
|
|
Loading…
Reference in a new issue