bool asCParser::IsDataType(int tokenType) { if( tokenType == ttIdentifier || IsRealType(tokenType) ) return true; return false; }
asCScriptNode *asCParser::ParseRealType() { asCScriptNode *node = new asCScriptNode(snDataType); sToken t1; GetToken(&t1); if( !IsRealType(t1.type) ) { Error(TXT_EXPECTED_DATA_TYPE, &t1); return node; } node->SetToken(&t1); node->UpdateSourcePos(t1.pos, t1.length); return node; }
bool asCParser::IsFunctionCall() { sToken t1, t2; GetToken(&t1); if( t1.type != ttIdentifier && !IsRealType(t1.type) ) { RewindTo(&t1); return false; } // The name can be followed by handle and closed array brackets GetToken(&t2); while( t2.type == ttHandle || t2.type == ttOpenBracket ) { if( t2.type == ttOpenBracket ) { GetToken(&t2); if( t2.type != ttCloseBracket ) { RewindTo(&t1); return false; } } GetToken(&t2); } if( t2.type == ttOpenParanthesis ) { RewindTo(&t1); return true; } RewindTo(&t1); return false; }
asCScriptNode *asCParser::ParseExprValue() { asCScriptNode *node = new asCScriptNode(snExprValue); sToken t1; GetToken(&t1); RewindTo(&t1); if( t1.type == ttIdentifier || IsRealType(t1.type) ) { if( IsFunctionCall() ) node->AddChildLast(ParseFunctionCall()); else node->AddChildLast(ParseIdentifier()); } else if( t1.type == ttCast ) node->AddChildLast(ParseCast()); else if( IsConstant(t1.type) ) node->AddChildLast(ParseConstant()); else if( t1.type == ttOpenParanthesis ) { GetToken(&t1); node->UpdateSourcePos(t1.pos, t1.length); node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t1); if( t1.type != ttCloseParanthesis ) Error(ExpectedToken(")").AddressOf(), &t1); node->UpdateSourcePos(t1.pos, t1.length); } else Error(TXT_EXPECTED_EXPRESSION_VALUE, &t1); return node; }
/** * Perform algebraic simplification and strenth reduction */ Symbol Simplify(Type ty, int opcode, Symbol src1, Symbol src2) { VariableSymbol t; Symbol p1, p2; int c1, c2; if (IsRealType(ty)) goto add_value; if (src2 == NULL || (src2->kind != SK_Constant && opcode != SUB)) goto add_value; switch (opcode) { case ADD: // a + 0 = a if (src2->val.i[0] == 0) return src1; // a + c1 + c2 = a + (c1 + c2) // a - c1 + c2 = a + (-c1 + c2) p1 = src1; c1 = 0; if (src1->kind == SK_Temp) { t = AsVar(src1); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p1 = t->def->src1; c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } if (c1 != 0) { src1 = p1; src2 = IntConstant(c1 + src2->val.i[0]); } break; case SUB: // a - 0 = a if (src2->kind == SK_Constant && src2->val.i[0] == 0) return src1; // put source operand into v + c format (v maybe NULL, c maybe 0) p1 = src1; c1 = 0; if (src1->kind == SK_Temp) { t = AsVar(src1); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p1 = t->def->src1; c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } else if (src1->kind == SK_Constant) { p1 = NULL; c1 = src1->val.i[0]; } p2 = src2; c2 = 0; if (src2->kind == SK_Temp) { t = AsVar(src2); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p2 = t->def->src1; c2 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } else if (src2->kind == SK_Constant) { p2 = NULL; c2 = src2->val.i[0]; } if (p1 == p2) { // (a + c1) - (a + c2) = c1 - c2 return IntConstant(c1 - c2); } else if (p1 == NULL) { // c1 - (a + c2) = (c1 - c2) - a src1 = IntConstant(c1 - c2); src2 = p2; } else if (p2 == NULL) { // (a + c1) - c2 = a + (c1 - c2) src1 = p1; opcode = ADD; src2 = IntConstant(c1 - c2); } break; case MUL: case DIV: // a * 1 = a; a / 1 = a; if (src2->val.i[0] == 1) return src1; // a * 2 power of n = a >> n c1 = Power2(src2->val.i[0]); if (c1 != 0) { src2 = IntConstant(c1); opcode = opcode == MUL ? LSH : RSH; } break; case MOD: // a % 1 = 0 if (src2->val.i[0] == 1) return IntConstant(0); // a % 2 power of n = a & (2 power of n - 1) c1 = Power2(src2->val.i[0]); if (c1 != 0) { src2 = IntConstant(src2->val.i[0] - 1); opcode = BAND; } break; case LSH: case RSH: // a >> 0 = a << 0 = a if (src2->val.i[0] == 0) return src1; break; case BOR: // a | 0 = a; a | -1 = -1 if (src2->val.i[0] == 0) return src1; if (src2->val.i[0] == -1) return src2; break; case BXOR: // a ^ 0 = a if (src2->val.i[0] == 0) return src1; break; case BAND: // a & 0 = 0, a & -1 = a if (src2->val.i[0] == 0) return IntConstant(0); if (src2->val.i[0] == -1) return src1; break; default: break; } add_value: return TryAddValue(ty, opcode, src1, src2); }
/* 算数优化 */ Symbol Simplify (Type ty, int opcode, Symbol src1, Symbol src2) { VariableSymbol t; Symbol p1, p2; int c1, c2; /* 浮点 */ if (IsRealType (ty)) goto add_value; if (src2 == NULL || (src2->kind != SK_Constant && opcode != SUB)) goto add_value; /* 以下是 加, 减, 乘, 除, 取余, 左移, 右移, 按位操作的优化 */ switch (opcode) { case ADD: { /* a + 0 = a */ if (src2->val.i[0] == 0) return src1; /* a + c1 + c2 = a + (c1 + c2) */ /* a - c1 + c2 = a + (-c1 + c2) */ p1 = src1; c1 = 0; if (src1->kind == SK_Temp) { t = AsVar(src1); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p1 = t->def->src1; c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } if (c1 != 0) { src1 = p1; /* 合并c1, c2 */ src2 = IntConstant (c1 + src2->val.i[0]); } }break; case SUB: { /* a - 0 = a */ if (src2->kind == SK_Constant && src2->val.i[0] == 0) return src1; // put source operand into v + c format (v maybe NULL, c maybe 0) p1 = src1; c1 = 0; if (src1->kind == SK_Temp) { t = AsVar(src1); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p1 = t->def->src1; c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } else if (src1->kind == SK_Constant) { p1 = NULL; c1 = src1->val.i[0]; } p2 = src2; c2 = 0; if (src2->kind == SK_Temp) { t = AsVar(src2); if (t->def->src2 && t->def->src2->kind == SK_Constant && (t->def->op == ADD || t->def->op == SUB)) { p2 = t->def->src1; c2 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0]; } } else if (src2->kind == SK_Constant) { p2 = NULL; c2 = src2->val.i[0]; } if (p1 == p2) { /* (a + c1) - (a + c2) = c1 - c2 */ return IntConstant (c1 - c2); } else if (p1 == NULL) { /* c1 - (a + c2) = (c1 - c2) - a */ src1 = IntConstant (c1 - c2); src2 = p2; } else if (p2 == NULL) { /* (a + c1) - c2 = a + (c1 - c2) */ src1 = p1; opcode = ADD; src2 = IntConstant(c1 - c2); } }break; case MUL: case DIV: { /* a * 1 = a; a / 1 = a; */ if (src2->val.i[0] == 1) return src1; /* a * 2 power of n = a >> n */ c1 = Power2 (src2->val.i[0]); if (c1 != 0) { /* 转换乘除为位移操作 */ src2 = IntConstant (c1); opcode = opcode == MUL ? LSH : RSH; } }break; case MOD: { /* a % 1 = 0 */ if (src2->val.i[0] == 1) return IntConstant (0); /* a % 2 power of n = a & (2 power of n - 1) */ c1 = Power2 (src2->val.i[0]); if (c1 != 0) { src2 = IntConstant (src2->val.i[0] - 1); opcode = BAND; } }break; case LSH: case RSH: { /* a >> 0 = a << 0 = a */ if (src2->val.i[0] == 0) return src1; }break; case BOR: { /* a | 0 = a; a | -1 = -1 */ if (src2->val.i[0] == 0) return src1; if (src2->val.i[0] == -1) return src2; }break; case BXOR: { /* a ^ 0 = a */ if (src2->val.i[0] == 0) return src1; }break; case BAND: { /* a & 0 = 0, a & -1 = a */ if (src2->val.i[0] == 0) return IntConstant(0); if (src2->val.i[0] == -1) return src1; }break; default: break; } add_value: /* 构造值添加到符号表中,并返回 */ return TryAddValue (ty, opcode, src1, src2); }