Implement %% (true modulo) support in qfcc

However, it's not quite working yet
This commit is contained in:
Bill Currie 2020-02-16 11:57:58 +09:00
parent b4fd804e4e
commit 9d2d33fa50
5 changed files with 44 additions and 1 deletions

View file

@ -88,6 +88,7 @@ get_op_string (int op)
case '*': return "*";
case '/': return "/";
case '%': return "%";
case MOD: return "%%";
case '&': return "&";
case '|': return "|";
case '^': return "^";

View file

@ -69,6 +69,7 @@ static expr_type_t float_float[] = {
{'|', &type_float},
{'^', &type_float},
{'%', &type_float},
{MOD, &type_float},
{SHL, &type_float},
{SHR, &type_float},
{EQ, &type_integer},
@ -99,6 +100,7 @@ static expr_type_t float_integer[] = {
{'|', &type_float, 0, &type_float},
{'^', &type_float, 0, &type_float},
{'%', &type_float, 0, &type_float},
{MOD, &type_float, 0, &type_float},
{SHL, &type_float, 0, &type_float},
{SHR, &type_float, 0, &type_float},
{EQ, &type_integer, 0, &type_float},
@ -118,6 +120,7 @@ static expr_type_t float_double[] = {
{'*', &type_double, &type_double, 0},
{'/', &type_double, &type_double, 0},
{'%', &type_double, &type_double, 0},
{MOD, &type_double, &type_double, 0},
{EQ, 0, 0, 0, double_compare},
{NE, 0, 0, 0, double_compare},
{LE, 0, 0, 0, double_compare},
@ -232,6 +235,7 @@ static expr_type_t integer_float[] = {
{'|', &type_float, &type_float, 0},
{'^', &type_float, &type_float, 0},
{'%', &type_float, &type_float, 0},
{MOD, &type_float, &type_float, 0},
{SHL, &type_integer, 0, &type_integer}, //FIXME?
{SHR, &type_integer, 0, &type_integer}, //FIXME?
{EQ, &type_integer, &type_float, 0},
@ -267,6 +271,7 @@ static expr_type_t integer_integer[] = {
{'|', &type_integer},
{'^', &type_integer},
{'%', &type_integer},
{MOD, &type_integer},
{SHL, &type_integer},
{SHR, &type_integer},
{EQ, &type_integer},
@ -287,6 +292,7 @@ static expr_type_t integer_uinteger[] = {
{'|', &type_integer},
{'^', &type_integer},
{'%', &type_integer},
{MOD, &type_integer},
{SHL, &type_integer},
{SHR, &type_integer},
{EQ, &type_integer},
@ -307,6 +313,7 @@ static expr_type_t integer_short[] = {
{'|', &type_integer, 0, &type_integer},
{'^', &type_integer, 0, &type_integer},
{'%', &type_integer, 0, &type_integer},
{MOD, &type_integer, 0, &type_integer},
{SHL, &type_integer, 0, &type_integer},
{SHR, &type_integer, 0, &type_integer},
{EQ, &type_integer, 0, &type_integer},
@ -324,6 +331,7 @@ static expr_type_t integer_double[] = {
{'*', &type_double, &type_double, 0},
{'/', &type_double, &type_double, 0},
{'%', &type_double, &type_double, 0},
{MOD, &type_double, &type_double, 0},
{EQ, &type_integer, &type_double, 0},
{NE, &type_integer, &type_double, 0},
{LE, &type_integer, &type_double, 0},
@ -347,6 +355,7 @@ static expr_type_t uinteger_integer[] = {
{'|', &type_integer},
{'^', &type_integer},
{'%', &type_integer},
{MOD, &type_integer},
{SHL, &type_uinteger},
{SHR, &type_uinteger},
{EQ, &type_integer},
@ -367,6 +376,7 @@ static expr_type_t uinteger_uinteger[] = {
{'|', &type_uinteger},
{'^', &type_uinteger},
{'%', &type_uinteger},
{MOD, &type_uinteger},
{SHL, &type_uinteger},
{SHR, &type_uinteger},
{EQ, &type_integer},
@ -394,6 +404,7 @@ static expr_type_t short_integer[] = {
{'|', &type_integer, &type_integer, 0},
{'^', &type_integer, &type_integer, 0},
{'%', &type_integer, &type_integer, 0},
{MOD, &type_integer, &type_integer, 0},
{SHL, &type_short},
{SHR, &type_short},
{EQ, &type_integer, &type_integer, 0},
@ -414,6 +425,7 @@ static expr_type_t short_uinteger[] = {
{'|', &type_uinteger, &type_uinteger, 0},
{'^', &type_uinteger, &type_uinteger, 0},
{'%', &type_uinteger, &type_uinteger, 0},
{MOD, &type_uinteger, &type_uinteger, 0},
{SHL, &type_short},
{SHR, &type_short},
{EQ, &type_integer, &type_uinteger, 0},
@ -434,6 +446,7 @@ static expr_type_t short_short[] = {
{'|', &type_short},
{'^', &type_short},
{'%', &type_short},
{MOD, &type_short},
{SHL, &type_short},
{SHR, &type_short},
{EQ, &type_integer},
@ -452,6 +465,7 @@ static expr_type_t double_float[] = {
{'*', &type_double, 0, &type_double},
{'/', &type_double, 0, &type_double},
{'%', &type_double, 0, &type_double},
{MOD, &type_double, 0, &type_double},
{EQ, 0, 0, 0, double_compare},
{NE, 0, 0, 0, double_compare},
{LE, 0, 0, 0, double_compare},
@ -477,6 +491,7 @@ static expr_type_t double_integer[] = {
{'*', &type_double, 0, &type_double},
{'/', &type_double, 0, &type_double},
{'%', &type_double, 0, &type_double},
{MOD, &type_double, 0, &type_double},
{EQ, 0, 0, 0, double_compare},
{NE, 0, 0, 0, double_compare},
{LE, 0, 0, 0, double_compare},
@ -494,6 +509,7 @@ static expr_type_t double_double[] = {
{'*', &type_double},
{'/', &type_double},
{'%', &type_double},
{MOD, &type_double},
{EQ, &type_integer},
{NE, &type_integer},
{LE, &type_integer},

View file

@ -216,6 +216,11 @@ STRING \"(\\.|[^"\\])*\"
return ASX;
}
"%%=" {
qc_yylval.op = MOD;
return ASX;
}
"<<=" {
qc_yylval.op = SHL;
return ASX;
@ -231,6 +236,11 @@ STRING \"(\\.|[^"\\])*\"
return yytext[0];
}
"%%" {
qc_yylval.pointer = 0; // ensure pointer vals are null
return MOD;
}
{ELLIPSIS} return ELLIPSIS;
"<<" return SHL;

View file

@ -135,7 +135,7 @@ int yylex (void);
%left SHL SHR
%left '+' '-'
%left '*' '/' '%'
%left '*' '/' '%' MOD
%right <op> SIZEOF UNARY INCOP
%left HYPERUNARY
%left '.' '(' '['
@ -1335,6 +1335,7 @@ expr
| expr '|' expr { $$ = binary_expr ('|', $1, $3); }
| expr '^' expr { $$ = binary_expr ('^', $1, $3); }
| expr '%' expr { $$ = binary_expr ('%', $1, $3); }
| expr MOD expr { $$ = binary_expr (MOD, $1, $3); }
;
texpr

View file

@ -6,6 +6,21 @@ float snafu (float a, float b)
return c;
}
@overload int modulo (int a, int b)
{
return a %% b;
}
@overload float modulo (float a, float b)
{
return a %% b;
}
@overload double modulo (double a, double b)
{
return a %% b;
}
#pragma traditional
float foo (float a, float b)
{