GXATSNode GXAnalyze::doubleCalculate()

in GaiaXHarmony/GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.cpp [489:988]


GXATSNode GXAnalyze::doubleCalculate(GXATSNode left, GXATSNode right, string op) {
    GXATSNode result = GXATSNode(left.name, left.token, left.token);
    string name;
    if ((op == "?") || (op == ":") || (op == "?:") || (op == "==") || (op == "!=")) {
        //可以返回map和array
    } else if (left.token == "map" || left.token == "array") {
        result.name = "expressionError: illegal operator '" + op + "',left operand has type of '" +
                      left.token + "'";
        result.token = "error";
        return result;
    }
    //返回值都为bool
    if (op == ">") {
        result.token = "bool";
        if ((left.token == "num" || left.token == "long") &&
            (right.token == "num" || right.token == "long")) {
            if (stof(left.name) > stof(right.name)) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else {
            result.name = "false";
        }
    }
        //返回值都为bool
    else if (op == ">=") {
        result.token = "bool";
        if ((left.token == "num" || left.token == "long") &&
            (right.token == "num" || right.token == "long")) {
            if (stof(left.name) >= stof(right.name)) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else {
            result.name = "false";
        }
    }
        //返回值都为bool
    else if (op == "<") {
        result.token = "bool";
        if ((left.token == "num" || left.token == "long") &&
            (right.token == "num" || right.token == "long")) {
            if (stof(left.name) < stof(right.name)) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else {
            result.name = "false";
        }
    }
        //返回值都为bool
    else if (op == "<=") {
        result.token = "bool";
        if ((left.token == "num" || left.token == "long") &&
            (right.token == "num" || right.token == "long")) {
            if (stof(left.name) <= stof(right.name)) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else {
            result.name = "false";
        }
    }
        //返回值都为bool
    else if (op == "&&") {
        result.token = "bool";
        if (left.token == "bool" && right.token == "bool") {
            if (left.name == "true" && right.name == "true") {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if (left.token == "bool" && (right.token == "num" || right.token == "long")) {
            if (left.name == "true" && (stof(right.name) != 0.0F)) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if (left.token == "bool" && right.token == "string") {
            if (left.name == "true" && right.name == "true") {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if ((left.token == "num" || left.token == "long") &&
                   (right.token == "num" || right.token == "long")) {
            if ((stof(left.name) != 0.0F) && (stof(right.name) != 0.0F)) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if ((left.token == "num" || left.token == "long") && right.token == "bool") {
            if (((stof(left.name) != 0.0F) && right.name == "true") ||
                ((left.token == "num" || left.token == "long") && right.token == "string")) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if ((left.token == "string" && right.token == "string") ||
                   (left.token == "string" && right.token == "bool")) {
            if (left.name == "true" && right.name == "true") {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if (left.token == "string" && (right.token == "num" || right.token == "long")) {
            if (left.name == "true" && (stof(right.name) != 0.0F)) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else {
            result.name = "false";
        }
    }
        //返回值都为bool
    else if (op == "||") {
        result.token = "bool";
        if (left.token == "bool" && right.token == "bool") {
            if (left.name == "true" || right.name == "true") {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if (left.token == "bool" && (right.token == "num" || right.token == "long")) {
            if (left.name == "true" || (stof(right.name) != 0.0F)) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if (left.token == "bool" && right.token == "string") {
            if (left.name == "true" || right.name == "true") {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if ((left.token == "num" || left.token == "long") &&
                   (right.token == "num" || right.token == "long")) {
            if ((stof(left.name) != 0.0F) || (stof(right.name) != 0.0F)) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if ((left.token == "num" || left.token == "long") && right.token == "bool") {
            if (((stof(left.name) != 0.0F) || right.name == "true") ||
                (left.token == "num" || right.token == "string")) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if ((left.token == "string" && right.token == "string") ||
                   (left.token == "string" && right.token == "bool")) {
            if (left.name == "true" || right.name == "true") {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if (left.token == "string" && (right.token == "num" || right.token == "long")) {
            if (left.name == "true" || (stof(right.name) != 0.0F)) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if (left.token == "null") {
            if ((right.token == "num" || right.token == "long")) {
                if (stof(right.name) != 0.0F) {
                    result.name = "true";
                } else {
                    result.name = "false";
                }
            } else if (right.name == "true") {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if (right.token == "null") {
            if (left.token == "num" || left.token == "long") {
                if (stof(left.name) != 0.0F) {
                    result.name = "true";
                } else {
                    result.name = "false";
                }
            } else if (left.name == "true") {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else {
            result.name = "false";
        }
    }
        //返回值都为bool
    else if (op == "!=") {
        result.token = "bool";
        if (left.token == "bool" && (right.token == "num" || right.token == "long")) {
            if ((left.name == "true" && (stof(right.name) == 0.0F)) ||
                (left.name == "false" && (stof(right.name) != 0.0F))) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if ((left.token == "num" || left.token == "long") && right.token == "bool") {
            if (((stof(left.name) == 0.0F) && right.name == "true") ||
                ((stof(left.name) != 0.0F) && right.name == "false")) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if (((left.token == "num" || left.token == "long") &&
                    (right.token == "num" || right.token == "long"))) {
            float lef = stof(left.name);
            float rig = stof(right.name);
            if (lef != rig) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if ((left.token == "string" && right.token == "bool") ||
                   (left.token == "bool" && right.token == "string")) {
            if (left.name == right.name) {
                result.name = "false";
            }
        } else if ((left.name != right.name) || (left.token != right.token)) {
            result.name = "true";
        } else {
            result.name = "false";
        }
    }
        //返回值都为bool
    else if (op == "==") {
        result.token = "bool";
        if (left.token == "bool" && (right.token == "num" || right.token == "long")) {
            if ((left.name == "true" && (stof(right.name) != 0.0F)) ||
                (left.name == "false" && (stof(right.name) == 0.0F))) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if ((left.token == "num" || left.token == "long") && right.token == "bool") {
            if (((stof(left.name) != 0.0F) && right.name == "true") ||
                ((stof(left.name) == 0.0F) && right.name == "false")) {
                result.name = "true";
            } else {
                result.name = "false";
            }
        } else if (((left.token == "num" || left.token == "long") &&
                    (right.token == "num" || right.token == "long")) &&
                   (stof(left.name) == stof(right.name))) {
            result.name = "true";
        } else if ((left.name == right.name)) {
            if (left.token == right.token) {
                result.name = "true";
            } else if ((left.token == "string" && right.token == "bool") ||
                       (left.token == "bool" && right.token == "string")) {
                result.name = "true";
            }
        } else {
            result.name = "false";
        }
    } else if (op == "?") {
        if (left.name == "true" || ((left.name != "false" && left.token != "null"))) {
            result.name = right.name;
            result.token = right.token;
        } else if ((left.token == "num" || left.token == "long") && stof(left.name) != 0.0F) {
            result.name = right.name;
            result.token = right.token;
        } else {
            result.token = "right";
            result.name = "right";
        }
    } else if (op == "?:") {
        if (left.name == "true" || (left.name != "false" && left.token != "null")) {
            result.name = left.name;
            result.token = left.token;
        } else {
            result.name = right.name;
            result.token = right.token;
        }
    } else if (op == ":") {
        if (left.token == "right" && left.name == "right") {
            result.token = right.token;
            result.name = right.name;
        } else {
            result.token = left.token;
            result.name = left.name;
        }
    } else if (op == "+") {
        if ((left.token == "num" || left.token == "long") &&
            (right.token == "num" || right.token == "long")) {
            if (left.token == "num" || right.token == "num") {
                int n = max(countDecimalPlaces(left.name), countDecimalPlaces(right.name));
                double temp = stod(left.name) + stod(right.name);
                string resNum = formatFloat(temp, n);
                result.name = resNum;
                result.token = "num";
            } else {
                long temp = stol(left.name) + stol(right.name);
                result.name = to_string(temp);
                result.token = "long";
            }
        } else if (left.token == "string" && right.token == "string") {
            result.token = "string";
            result.name = left.name + right.name;
        } else if (left.token == "null" || right.token == "null") {
            result.name = "null";
            result.token = "null";
        } else {
            if ((left.token == "num" || left.token == "long") && right.token == "string") {
                result.name = left.name + right.name;
                result.token = "string";
            } else if ((right.token == "num" || right.token == "long") && left.token == "string") {
                result.name = left.name + right.name;
                result.token = "string";
            } else {
                result.token = "error";
                if (left.token == "string" || (left.token == "num" || left.token == "long")) {
                    result.name = "expressionError: '" + right.name +
                                  "' expected num or string value,not '" + right.token + "'";
                } else if (right.token == "string" ||
                           (right.token == "num" || right.token == "long")) {
                    result.name = "expressionError: '" + left.name +
                                  "' expected num or string value,not '" + left.token + "'";
                } else {
                    result.name = "expressionError: '" + left.name +
                                  "' expected num or string value,not '" + left.token + "'";
                }
            }
        }
    } else if (op == "-") {
        if ((left.token == "num" || left.token == "long") &&
            (right.token == "num" || right.token == "long")) {

            if (left.token == "num" || right.token == "num") {
                int n = max(countDecimalPlaces(left.name), countDecimalPlaces(right.name));
                double temp = stod(left.name) - stod(right.name);
                string resNum = formatFloat(temp, n);
                result.name = resNum;
                result.token = "num";
            } else {
                long temp = stol(left.name) - stol(right.name);
                result.name = to_string(temp);
                result.token = "long";
            }
        } else if (left.token == "null" || right.token == "null") {
            result.name = "null";
            result.token = "null";
        } else {
            result.token = "error";
            if ((left.token == "num" || left.token == "long")) {
                result.name =
                        "expressionError: '" + right.name + "'" + ": expected num value,not: " +
                        right.token;
            } else if (left.token == "null" || right.token == "null") {
                result.name = "null";
                result.token = "null";
            } else if ((right.token == "num" || right.token == "long")) {
                result.name =
                        "expressionError: '" + left.name + "'" + ": expected num value,not: " +
                        left.token;
            } else {
                result.name =
                        "expressionError: '" + left.name + "'" + ": expected num value,not: " +
                        left.token;
            }
        }
    } else if (op == "*") {
        if ((left.token == "num" || left.token == "long") &&
            (right.token == "num" || right.token == "long")) {
            if (left.token == "num" || right.token == "num") {
                //如果需要保留n位小数,那么输入时需要输入n位
                int n = max(countDecimalPlaces(left.name), countDecimalPlaces(right.name));
                double temp = stod(left.name) * stod(right.name);
                string resNum = formatFloat(temp, n);
                result.name = resNum;
                result.token = "num";
            } else {
                long temp = stol(left.name) * stol(right.name);
                result.name = to_string(temp);
                result.token = "long";
            }
        } else if (left.token == "null" || right.token == "null") {
            result.name = "null";
            result.token = "null";
        } else {
            result.token = "error";
            if ((left.token == "num" || left.token == "long")) {
                result.name =
                        "expressionError: '" + right.name + "'" + ": expected num value,not: " +
                        right.token;
            } else if (left.token == "null" || right.token == "null") {
                result.name = "null";
                result.token = "null";
            } else if ((right.token == "num" || right.token == "long")) {
                result.name =
                        "expressionError: '" + left.name + "'" + ": expected num value,not: " +
                        left.token;
            } else {
                result.name =
                        "expressionError: '" + left.name + "'" + ": expected num value,not: " +
                        left.token;
            }
        }
    } else if (op == "/") {
        if ((left.token == "num" || left.token == "long") &&
            (right.token == "num" || right.token == "long")) {
            if (stof(right.name) == 0) {
                result.token = "error";
                result.name = "expressionError: divide or mod by zero";
            } else {
                if (left.token == "num" || right.token == "num") {
                    int n = max(countDecimalPlaces(left.name), countDecimalPlaces(right.name));
                    double temp = stod(left.name) / stod(right.name);
                    string resNum = formatFloat(temp, n);
                    result.name = resNum;
                    result.token = "num";
                } else {
                    long temp = stol(left.name) / stol(right.name);
                    long double tempF = stold(left.name) / stold(right.name);
                    if (temp != tempF && (left.token == "num" || right.token == "num")) {
                        result.name = to_string(tempF);
                        result.token = "num";
                    } else {
                        result.name = to_string(temp);
                        result.token = "long";
                    }
                }
            }
        } else if (left.token == "null" || right.token == "null") {
            result.name = "null";
            result.token = "null";
        } else {
            result.token = "error";
            if ((left.token == "num" || left.token == "long")) {
                result.name =
                        "expressionError: '" + right.name + "'" + ": expected num value,not: " +
                        right.token;
            } else if (left.token == "null" || right.token == "null") {
                result.name = "null";
                result.token = "null";
            } else if ((right.token == "num" || right.token == "long")) {
                result.name =
                        "expressionError: '" + left.name + "'" + ": expected num value,not: " +
                        left.token;
            } else {
                result.name =
                        "expressionError: '" + left.name + "'" + ": expected num value,not: " +
                        left.token;
            }
        }
    } else if (op == "%") {
        if ((left.token == "num" || left.token == "long") &&
            (right.token == "num" || right.token == "long")) {
            if (stof(right.name) == 0) {
                result.token = "error";
                result.name = "expressionError: divide or mod by zero";
            } else {
                if (left.token == "num" || right.token == "num") {
                    int n = max(countDecimalPlaces(left.name), countDecimalPlaces(right.name));
                    double temp = fmod(stod(left.name), stod(right.name));
                    string resNum = formatFloat(temp, n);
                    result.name = resNum;
                    result.token = "num";
                } else {
                    long temp = stol(left.name) % stol(right.name);
                    result.name = to_string(temp);
                    result.token = "long";
                }
            }
        } else if (left.token == "null" || right.token == "null") {
            result.name = "null";
            result.token = "null";
        } else {
            result.token = "error";
            if ((left.token == "num" || left.token == "long")) {
                result.name =
                        "expressionError: '" + right.name + "'" + ": expected num value,not: " +
                        right.token;
            } else if (left.token == "null" || right.token == "null") {
                result.name = "null";
                result.token = "null";
            } else if ((right.token == "num" || right.token == "long")) {
                result.name =
                        "expressionError: '" + left.name + "'" + ": expected num value,not: " +
                        left.token;
            } else {
                result.name =
                        "expressionError: '" + left.name + "'" + ": expected num value,not: " +
                        left.token;
            }
        }
    } else {
        result.token = "error";
        result.name = "expressionError: wrong expression";
    }
    return result;
}