#include "utils.h" inline ZYM::int2048 Any2Int(const std::any &value) { if (auto ptr = std::any_cast(&value)) return *ptr; else if (auto ptr = std::any_cast(&value)) { std::stringstream buf; buf << std::fixed << std::setprecision(0) << std::floor(*ptr); std::string tmp; buf >> tmp; return std::move(ZYM::int2048(tmp)); } else if (auto ptr = std::any_cast(&value)) return std::move(ZYM::int2048((long long)(*ptr))); else if (auto ptr = std::any_cast(&value)) { std::string str = *ptr; size_t dot_position = str.find('.'); if (dot_position != std::string::npos) { std::string integer_part = str.substr(0, dot_position); str = integer_part; } return std::move(ZYM::int2048(str)); } else if (auto ptr = std::any_cast(&value)) return std::move(ZYM::int2048(0)); else { std::cerr << value.type().name() << std::endl; throw FatalError("Any2Int2048: unknown type", 29); } } double Any2Float(const std::any &value) { if (auto ptr = std::any_cast(&value)) return *ptr; else if (auto ptr = std::any_cast(&value)) { double res = 0; std::stringstream buf; buf << *ptr; std::string tmp; buf >> tmp; int p = 0; if (tmp[0] == '-') p++; for (; p < tmp.size(); p++) res = res * 10 + tmp[p] - '0'; if (tmp[0] == '-') res = -res; return res; } else if (auto ptr = std::any_cast(&value)) return (double)(*ptr); else if (auto ptr = std::any_cast(&value)) return std::stod(*ptr); else throw FatalError("Any2Float: unknown type", 30); } std::string Any2String(const std::any &value) { std::stringstream buf; std::string res; if (auto ptr = std::any_cast(&value)) { buf << std::fixed << std::setprecision(6) << *ptr; } else if (auto ptr = std::any_cast(&value)) { if (*ptr) buf << "True"; else buf << "False"; } else if (auto ptr = std::any_cast(&value)) buf << *ptr; else if (auto ptr = std::any_cast(&value)) buf << *ptr; else if (auto ptr = std::any_cast(&value)) buf << "None"; else throw FatalError("Any2String: unknown type", 31); std::getline(buf, res); return res; } bool Any2Bool(const std::any &value) { if (auto ptr = std::any_cast(&value)) { return (*ptr) != 0; } else if (auto ptr = std::any_cast(&value)) { return (*ptr) != 0; } else if (auto ptr = std::any_cast(&value)) { return *ptr; } else if (auto ptr = std::any_cast(&value)) { return (*ptr) != ""; } else if (auto ptr = std::any_cast(&value)) return false; else throw FatalError("Any2Bool: unknown type", 32); } std::any DeQuate(std::any val, VariableContainer &Variables) { if (auto ptr = std::any_cast>(&val)) { for (int i = 0; i < ptr->size(); i++) (*ptr)[i] = DeQuate((*ptr)[i], Variables); return *ptr; } else if (auto ptr = std::any_cast(&val)) { return Variables.ReadVariable(ptr->name); } else if (std::any_cast(&val) || std::any_cast(&val) || std::any_cast(&val) || std::any_cast(&val) || std::any_cast(&val)) return val; else return NoneType(); // throw FatalError("DeQuate: unknown type"); } int ConverToSameArithType(std::any &a, std::any &b, bool allow_string_operation) { if (std::any_cast(&a) != nullptr && std::any_cast(&b) == nullptr) a = (bool)false; if (std::any_cast(&b) != nullptr && std::any_cast(&a) == nullptr) b = (bool)false; ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); std::string *ptr_a_string = std::any_cast(&a); std::string *ptr_b_string = std::any_cast(&b); if ((!allow_string_operation) && (ptr_a_string || ptr_b_string)) throw InterpretException( "ConverToSameArithType: string operation not allowed in this " "situation", 33); if (allow_string_operation && (ptr_a_string || ptr_b_string)) { return 1; } int level_a = (ptr_a_bool != nullptr ? 1 : 0) + (ptr_a_int2048 != nullptr ? 2 : 0) + (ptr_a_float != nullptr ? 3 : 0); int level_b = (ptr_b_bool != nullptr ? 1 : 0) + (ptr_b_int2048 != nullptr ? 2 : 0) + (ptr_b_float != nullptr ? 3 : 0); int res_level = std::max(level_a, level_b); switch (res_level) { case 1: break; case 2: a = Any2Int(a); b = Any2Int(b); break; case 3: a = Any2Float(a); b = Any2Float(b); break; default: throw FatalError("ConverToSameArithType: unknown type", 36); } return 0; } std::any Add(std::any a, std::any b) { int status = ConverToSameArithType(a, b, true); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); std::string *ptr_a_string = std::any_cast(&a); std::string *ptr_b_string = std::any_cast(&b); if ((ptr_a_string != nullptr ? 1 : 0) + (ptr_b_string != nullptr ? 1 : 0) == 2) return (*ptr_a_string) + (*ptr_b_string); if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) return ZYM::int2048(int(*ptr_a_bool) + int(*ptr_b_bool)); else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) return (*ptr_a_int2048) + (*ptr_b_int2048); else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) return (*ptr_a_float) + (*ptr_b_float); else if ((ptr_a_string != nullptr) || (ptr_b_string != nullptr)) return Any2String(a) + Any2String(b); else throw FatalError("Add: Type Error", 38); } std::any Sub(std::any a, std::any b) { if (std::any_cast(&a) != nullptr) a = ZYM::int2048(0); if (std::any_cast(&b) != nullptr) b = ZYM::int2048(0); if (std::any_cast(&a)) a = (bool)false; if (std::any_cast(&b)) b = (bool)false; ConverToSameArithType(a, b); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) return ZYM::int2048(int(*ptr_a_bool) - int(*ptr_b_bool)); else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) return (*ptr_a_int2048) - (*ptr_b_int2048); else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) return (*ptr_a_float) - (*ptr_b_float); else throw FatalError("Sub: Type Error", 39); return a; } std::any Mul(std::any a, std::any b) { if (std::any_cast(&a)) a = (bool)false; if (std::any_cast(&b)) b = (bool)false; int status = ConverToSameArithType(a, b, true); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); std::string *ptr_a_string = std::any_cast(&a); std::string *ptr_b_string = std::any_cast(&b); if ((ptr_a_string != nullptr ? 1 : 0) + (ptr_b_string != nullptr ? 1 : 0) == 2) { return std::string(""); } else if ((ptr_a_string != nullptr ? 1 : 0) + (ptr_b_string != nullptr ? 1 : 0) == 1) { if (ptr_a_string == nullptr) { std::swap(a, b); ptr_a_bool = std::any_cast(&a); ptr_b_bool = std::any_cast(&b); ptr_a_int2048 = std::any_cast(&a); ptr_b_int2048 = std::any_cast(&b); ptr_a_float = std::any_cast(&a); ptr_b_float = std::any_cast(&b); ptr_a_string = std::any_cast(&a); ptr_b_string = std::any_cast(&b); } if (Less(b, ZYM::int2048(0))) { b = Neg(b); ptr_b_bool = std::any_cast(&b); ptr_b_int2048 = std::any_cast(&b); ptr_b_float = std::any_cast(&b); ptr_b_string = std::any_cast(&b); } if (ptr_b_float != nullptr) { b = Any2Int(*ptr_b_float); ptr_b_int2048 = std::any_cast(&b); goto st; } if (ptr_b_bool != nullptr) { if (*ptr_b_bool) { return *ptr_a_string; } else { return std::string(""); } } if (std::any_cast(&a) != nullptr || std::any_cast(&b) != nullptr) return std::string(""); if (ptr_b_int2048 != nullptr) { st:; std::string res; for (int i = 0; i < (*ptr_b_int2048); i++) res += *ptr_a_string; return res; } } if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) return ZYM::int2048(int(*ptr_a_bool) * int(*ptr_b_bool)); else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) return (*ptr_a_int2048) * (*ptr_b_int2048); else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) return (*ptr_a_float) * (*ptr_b_float); else throw FatalError("Mul: Type Error", 42); } std::any Div(std::any a, std::any b) { if (std::any_cast(&a)) a = (bool)false; if (std::any_cast(&b)) b = (bool)false; bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); std::string *ptr_a_string = std::any_cast(&a); std::string *ptr_b_string = std::any_cast(&b); if ((ptr_a_string != nullptr) || (ptr_b_string != nullptr)) throw InterpretException( "Div: string operation not allowed in this situation", 43); double t_a = Any2Float(a); double t_b = Any2Float(b); // if (t_b == 0) throw InterpretException("Div: divided by zero", 44); t_a = t_a / t_b; return t_a; } std::any Divv(std::any a, std::any b) { if (std::any_cast(&a)) a = (bool)false; if (std::any_cast(&b)) b = (bool)false; if (std::any_cast(&a) != nullptr) a = ZYM::int2048(0); if (std::any_cast(&b) != nullptr) b = ZYM::int2048(0); ConverToSameArithType(a, b); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) { if ((*ptr_b_float) == 0) throw InterpretException("Divv: divided by zero", 45); return ZYM::int2048(std::floor((*ptr_a_float) / (*ptr_b_float))); } else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) { if ((*ptr_b_int2048) == 0) throw InterpretException("Divv: divided by zero", 46); return (*ptr_a_int2048) / (*ptr_b_int2048); } else if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) { if ((*ptr_b_bool) == 0) throw InterpretException("Divv: divided by zero", 47); return ZYM::int2048(int(*ptr_a_bool) / int(*ptr_b_bool)); } else throw FatalError("Divv: Type Error", 48); } std::any Mod(std::any a, std::any b) { if (std::any_cast(&a)) a = (bool)false; if (std::any_cast(&b)) b = (bool)false; if (std::any_cast(&a) != nullptr) a = ZYM::int2048(0); ConverToSameArithType(a, b); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) { // if ((*ptr_b_float) == 0) // throw InterpretException("Mod: divided by zero", 49); return (*ptr_a_float) - (*ptr_b_float) * std::floor((*ptr_a_float) / (*ptr_b_float)); } else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) { // if ((*ptr_b_int2048) == 0) // throw InterpretException("Mod: divided by zero", 50); return (*ptr_a_int2048) % (*ptr_b_int2048); } else if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) { // if ((*ptr_b_bool) == 0) // throw InterpretException("Mod: divided by zero", 51); return ZYM::int2048(int(*ptr_a_bool) % int(*ptr_b_bool)); } else throw FatalError("Mod: Type Error", 52); } std::any &SelfAdd(std::any &a, std::any b) { a = Add(a, b); return a; } std::any &SelfSub(std::any &a, std::any b) { a = Sub(a, b); return a; } std::any &SelfMul(std::any &a, std::any b) { a = Mul(a, b); return a; } std::any &SelfDiv(std::any &a, std::any b) { a = Div(a, b); return a; } std::any &SelfDivv(std::any &a, std::any b) { a = Divv(a, b); return a; } std::any &SelfMod(std::any &a, std::any b) { a = Mod(a, b); return a; } std::any Neg(std::any a) { if (std::any_cast(&a)) a = (bool)false; bool *ptr_a_bool = std::any_cast(&a); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); double *ptr_a_float = std::any_cast(&a); if (ptr_a_bool != nullptr) return ZYM::int2048(-(*ptr_a_bool)); else if (ptr_a_int2048 != nullptr) return -(*ptr_a_int2048); else if (ptr_a_float != nullptr) return -(*ptr_a_float); else throw FatalError("Neg: Type Error", 53); } bool Greater(std::any a, std::any b) { ConverToSameArithType(a, b, true); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); std::string *ptr_a_string = std::any_cast(&a); std::string *ptr_b_string = std::any_cast(&b); if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) return (*ptr_a_bool) > (*ptr_b_bool); else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) return (*ptr_a_int2048) > (*ptr_b_int2048); else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) return (*ptr_a_float) > (*ptr_b_float); else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) return (*ptr_a_string) > (*ptr_b_string); else if (((ptr_a_string != nullptr) || (ptr_b_string != nullptr))) return false; else throw FatalError("Greater: Type Error", 54); } bool Less(std::any a, std::any b) { ConverToSameArithType(a, b, true); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); std::string *ptr_a_string = std::any_cast(&a); std::string *ptr_b_string = std::any_cast(&b); if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) return (*ptr_a_bool) < (*ptr_b_bool); else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) return (*ptr_a_int2048) < (*ptr_b_int2048); else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) return (*ptr_a_float) < (*ptr_b_float); else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) return (*ptr_a_string) < (*ptr_b_string); else if (((ptr_a_string != nullptr) || (ptr_b_string != nullptr))) return false; else throw FatalError("Less: Type Error", 55); } bool Equal(std::any a, std::any b) { ConverToSameArithType(a, b, true); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); std::string *ptr_a_string = std::any_cast(&a); std::string *ptr_b_string = std::any_cast(&b); if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) return (*ptr_a_bool) == (*ptr_b_bool); else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) return (*ptr_a_int2048) == (*ptr_b_int2048); else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) return (*ptr_a_float) == (*ptr_b_float); else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) return (*ptr_a_string) == (*ptr_b_string); else if (((ptr_a_string != nullptr) || (ptr_b_string != nullptr))) return false; else throw FatalError("Equal: Type Error", 56); } bool NotEqual(std::any a, std::any b) { ConverToSameArithType(a, b, true); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); std::string *ptr_a_string = std::any_cast(&a); std::string *ptr_b_string = std::any_cast(&b); if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) return (*ptr_a_bool) != (*ptr_b_bool); else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) return (*ptr_a_int2048) != (*ptr_b_int2048); else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) return (*ptr_a_float) != (*ptr_b_float); else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) return (*ptr_a_string) != (*ptr_b_string); else if (((ptr_a_string != nullptr) || (ptr_b_string != nullptr))) return false; else throw FatalError("NotEqual: Type Error", 57); } bool GreaterEqual(std::any a, std::any b) { ConverToSameArithType(a, b, true); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); std::string *ptr_a_string = std::any_cast(&a); std::string *ptr_b_string = std::any_cast(&b); if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) return (*ptr_a_bool) >= (*ptr_b_bool); else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) return (*ptr_a_int2048) >= (*ptr_b_int2048); else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) return (*ptr_a_float) >= (*ptr_b_float); else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) return (*ptr_a_string) >= (*ptr_b_string); else if (((ptr_a_string != nullptr) || (ptr_b_string != nullptr))) return false; else throw FatalError("GreaterEqual: Type Error", 58); } bool LessEqual(std::any a, std::any b) { ConverToSameArithType(a, b, true); bool *ptr_a_bool = std::any_cast(&a); bool *ptr_b_bool = std::any_cast(&b); ZYM::int2048 *ptr_a_int2048 = std::any_cast(&a); ZYM::int2048 *ptr_b_int2048 = std::any_cast(&b); double *ptr_a_float = std::any_cast(&a); double *ptr_b_float = std::any_cast(&b); std::string *ptr_a_string = std::any_cast(&a); std::string *ptr_b_string = std::any_cast(&b); if ((ptr_a_bool != nullptr) && (ptr_b_bool != nullptr)) return (*ptr_a_bool) <= (*ptr_b_bool); else if ((ptr_a_int2048 != nullptr) && (ptr_b_int2048 != nullptr)) return (*ptr_a_int2048) <= (*ptr_b_int2048); else if ((ptr_a_float != nullptr) && (ptr_b_float != nullptr)) return (*ptr_a_float) <= (*ptr_b_float); else if ((ptr_a_string != nullptr) && (ptr_b_string != nullptr)) return (*ptr_a_string) <= (*ptr_b_string); else if (((ptr_a_string != nullptr) || (ptr_b_string != nullptr))) return false; else throw FatalError("LessEqual: Type Error", 59); }