From 7264e9fb281767c8336d1a637906e539dd705863 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 2 Feb 2020 16:30:45 +0800 Subject: [PATCH] Added new "div" operator for unsigned integer division --- gencode.c | 7 ++++--- lex.c | 11 +++-------- opextra.h | 2 ++ optimize.c | 10 +++++++--- parse.c | 4 ++-- tokens.h | 2 ++ 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/gencode.c b/gencode.c index 9efbba3..8a29190 100644 --- a/gencode.c +++ b/gencode.c @@ -341,9 +341,10 @@ shCircuit: case '*': writeOp(O_MUL, f); i++; break; case '/': writeOp(O_DIV, f); i++; break; case '%': writeOp(O_MOD, f); i++; break; - case '^': writeOp(O_TS_POW, f); i++; break; // sfall - //case T_AND: writeOp(O_AND, f); i++; break; // pbs - removed - //case T_OR: writeOp(O_OR, f); i++; break; // pbs - removed + case '^': writeOp(O_TS_POW, f); i++; break; // sfall + case T_DIV2: writeOp(O_TS_DIV, f); i++; break; // sfall + //case T_AND: writeOp(O_AND, f); i++; break; // pbs - removed + //case T_OR: writeOp(O_OR, f); i++; break; // pbs - removed case T_BWAND: writeOp(O_BWAND, f); i++; break; case T_BWOR: writeOp(O_BWOR, f); i++; break; case T_NOT: writeOp(O_NOT, f); i++; break; diff --git a/lex.c b/lex.c index dd1b447..72b0286 100644 --- a/lex.c +++ b/lex.c @@ -191,11 +191,11 @@ void initLex(void) { if(backwardcompat == 0) { tokens[T_FOR] = "for"; tokens[T_FOREACH] = "foreach"; - //tokens[T_IN] = "in"; tokens[T_BREAK] = "break"; tokens[T_CONTINUE] = "continue"; tokens[T_AND_ALSO] = "andalso"; tokens[T_OR_ELSE] = "orelse"; + tokens[T_DIV2] = "div"; } tokens[T_INCLUDE] = "include"; tokens[T_STARTCRITICAL] = "startcritical"; @@ -291,11 +291,6 @@ static int expect(int what, int hit, int miss) { else { ungetChar(); return miss; } } -/* added for alternative assignment operator '=' */ -static int expectAssign(int what, int hit, int miss) { - return (getChar() == what) ? hit : miss; -} - static int validSymbolChar(int c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || @@ -680,12 +675,12 @@ top: break; /* added for alternative assignment operator '=' */ -#define EXPECT_ASSIGN(c, x, y, z) case x: ret = expectAssign(x, y, z); break; +#define EXPECT_ASSIGN(c, x, y, z) case c: ret = expect(x, y, z); break; EXPECT_ASSIGN('=', '=', T_EQUAL, T_ASSIGN); #define EXPECT(x, y, z) case x: ret = expect(y, z, x); break; EXPECT(':', '=', T_ASSIGN); -// EXPECT('=', '=', T_EQUAL); +// EXPECT('=', '=', T_EQUAL); // remove for single character assignment operator EXPECT('>', '=', T_GREATER_EQUAL); EXPECT('<', '=', T_LESS_EQUAL); EXPECT('!', '=', T_NOT_EQUAL); diff --git a/opextra.h b/opextra.h index 7dd1de5..626043f 100644 --- a/opextra.h +++ b/opextra.h @@ -603,6 +603,8 @@ enum { O_TS_REGISTER_HOOK_PROC2, O_TS_REG_ANIM_CALLBACK, + O_TS_DIV, // used for unsigned integer division + O_END_OP, }; diff --git a/optimize.c b/optimize.c index ec30a4d..f9a137f 100644 --- a/optimize.c +++ b/optimize.c @@ -14,6 +14,7 @@ #define F_OP(token,op) case token: out->floatData = fd1 op fd2; break; #define F_IOP(token,op) case token: out->type = V_INT; out->intData = fd1 op fd2; break; #define I_OP(token,op) case token: out->intData = in1->intData op in2->intData; break; +#define I_OPU(token,op) case token: out->intData = (unsigned int)in1->intData op (unsigned int)in2->intData; break; #define VU_FIRST_ASSIGN_IS_PURE 0x01 #define VU_FIRST_ASSIGN_IN_WHILE 0x02 @@ -164,8 +165,9 @@ static void FindVarUsage(const Node* node, VarUsage* usage, int varCount) { } static int isValidBinaryOp(int op) { - return op == '+' || op == '-' || op == '*' || op == '/' || op == T_AND || op == T_OR || op == T_BWAND || op == T_BWOR || op == T_BWXOR || - op == '>' || op == '<' || op == T_EQUAL || op == T_NOT_EQUAL || op == T_LESS_EQUAL || op == T_GREATER_EQUAL; + return op == '+' || op == '-' || op == '*' || op == '/' || op == T_DIV2 || + op == T_AND || op == T_OR || op == T_BWAND || op == T_BWOR || op == T_BWXOR || + op == '>' || op == '<' || op == T_EQUAL || op == T_NOT_EQUAL || op == T_LESS_EQUAL || op == T_GREATER_EQUAL; } //Calculate the result of a constant operation (doesn't handle strings, which would require namespace modifications) @@ -184,6 +186,7 @@ static void PerformConstOp(const Value* in1, const Value* in2, Value* out, int o F_OP('-', -) F_OP('*', *) F_OP('/', /) + F_OP(T_DIV2, /) F_IOP(T_EQUAL, ==) F_IOP(T_NOT_EQUAL, !=) F_IOP('>', >) @@ -221,6 +224,7 @@ static void PerformConstOp(const Value* in1, const Value* in2, Value* out, int o I_OP('-', -) I_OP('*', *) I_OP('/', /) + I_OPU(T_DIV2, /) I_OP(T_AND, &&) I_OP(T_OR, ||) I_OP(T_BWAND, &) @@ -299,7 +303,7 @@ static int ConstantFolding(NodeList* _nodes) { static int isValidMathOp(int op) { // 43 45 42 47 - return op == '+' || op == '-' || op == '*' || op == '/'; + return op == '+' || op == '-' || op == '*' || op == '/'; // | op == T_DIV2 } // optimizes remaining not optimized mathematical operations (except for logical operations) | added: Fakels diff --git a/parse.c b/parse.c index 5e6db35..cfa0bf7 100644 --- a/parse.c +++ b/parse.c @@ -1135,12 +1135,12 @@ static void factor(Procedure *p, NodeList *nodes) { static void term_prime(Procedure *p, NodeList *nodes) { int i = lex(); - if (i == '*' || i == '/' || i == '%' || i == '^') { // sfall: added ^ + if (i == '*' || i == '/' || i == '%' || i == T_DIV2 || i == '^') { // sfall: added '^', 'div' Node *node; // term(p, nodes); factor(p, nodes); node = &nodes->nodes[nodes->numNodes - 1]; - if ((i == '/' || i == '%') && node->token == T_CONSTANT && node->value.type != V_STRING && node->value.intData == 0) { + if ((i == '/' || i == '%' || i == T_DIV2) && node->token == T_CONSTANT && node->value.type != V_STRING && node->value.intData == 0) { parseSemanticError("Division by zero!"); } emitOp(p, nodes, i); diff --git a/tokens.h b/tokens.h index 587ae23..25e3ede 100644 --- a/tokens.h +++ b/tokens.h @@ -90,6 +90,8 @@ enum { T_PROCEDURE=256, // begin keywords T_AND_ALSO, // new T_OR_ELSE, // new + T_DIV2, + T_EOF, T_END_CORE, };