From 9d2d33fa50acd65a5ec59edc2a1e740b7f33bad3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 16 Feb 2020 11:57:58 +0900 Subject: [PATCH] Implement %% (true modulo) support in qfcc However, it's not quite working yet --- tools/qfcc/source/dot_expr.c | 1 + tools/qfcc/source/expr_binary.c | 16 ++++++++++++++++ tools/qfcc/source/qc-lex.l | 10 ++++++++++ tools/qfcc/source/qc-parse.y | 3 ++- tools/qfcc/test/modulo.r | 15 +++++++++++++++ 5 files changed, 44 insertions(+), 1 deletion(-) diff --git a/tools/qfcc/source/dot_expr.c b/tools/qfcc/source/dot_expr.c index 675488e93..081dbecec 100644 --- a/tools/qfcc/source/dot_expr.c +++ b/tools/qfcc/source/dot_expr.c @@ -88,6 +88,7 @@ get_op_string (int op) case '*': return "*"; case '/': return "/"; case '%': return "%"; + case MOD: return "%%"; case '&': return "&"; case '|': return "|"; case '^': return "^"; diff --git a/tools/qfcc/source/expr_binary.c b/tools/qfcc/source/expr_binary.c index 0f2a1e256..2e31116f3 100644 --- a/tools/qfcc/source/expr_binary.c +++ b/tools/qfcc/source/expr_binary.c @@ -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}, diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 5b97a0938..58b661220 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -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; diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index eba38584d..c34efd0a0 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -135,7 +135,7 @@ int yylex (void); %left SHL SHR %left '+' '-' -%left '*' '/' '%' +%left '*' '/' '%' MOD %right 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 diff --git a/tools/qfcc/test/modulo.r b/tools/qfcc/test/modulo.r index 81366c134..9d529a0b8 100644 --- a/tools/qfcc/test/modulo.r +++ b/tools/qfcc/test/modulo.r @@ -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) {