#include #include #include #include #include #include namespace Fig::Builtins { const std::unordered_map &getBuiltinValues() { static const std::unordered_map builtinValues = { {u8"null", Object::getNullInstance()}, {u8"true", Object::getTrueInstance()}, {u8"false", Object::getFalseInstance()}, {u8"Error", std::make_shared(InterfaceType(getErrorInterfaceTypeInfo(), {Ast::InterfaceMethod(u8"toString", Ast::FunctionParameters({}, {}), std::make_shared(u8"String"), nullptr), Ast::InterfaceMethod(u8"getErrorClass", Ast::FunctionParameters({}, {}), std::make_shared(u8"String"), nullptr), Ast::InterfaceMethod(u8"getErrorMessage", Ast::FunctionParameters({}, {}), std::make_shared(u8"String"), nullptr)}))}, {u8"Operation", std::make_shared(InterfaceType(getOperationInterfaceTypeInfo(), {}))}, {u8"Any", std::make_shared(StructType(ValueType::Any, nullptr, {}, true))}, {u8"Int", std::make_shared(StructType(ValueType::Int, nullptr, {}, true))}, {u8"Null", std::make_shared(StructType(ValueType::Null, nullptr, {}, true))}, {u8"String", std::make_shared(StructType(ValueType::String, nullptr, {}, true))}, {u8"Bool", std::make_shared(StructType(ValueType::Bool, nullptr, {}, true))}, {u8"Double", std::make_shared(StructType(ValueType::Double, nullptr, {}, true))}, {u8"Function", std::make_shared(StructType(ValueType::Function, nullptr, {}, true))}, {u8"List", std::make_shared(StructType(ValueType::List, nullptr, {}, true))}, {u8"Map", std::make_shared(StructType(ValueType::Map, nullptr, {}, true))}, // Type `StructType` `StructInstance` `Module` `InterfaceType` // Not allowed to call constructor! }; return builtinValues; } const std::unordered_map &getBuiltinFunctionArgCounts() { static const std::unordered_map builtinFunctionArgCounts = { {u8"__fstdout_print", -1}, // variadic {u8"__fstdout_println", -1}, // variadic {u8"__fstdin_read", 0}, {u8"__fstdin_readln", 0}, {u8"__fvalue_type", 1}, {u8"__fvalue_int_parse", 1}, {u8"__fvalue_int_from", 1}, {u8"__fvalue_double_parse", 1}, {u8"__fvalue_double_from", 1}, {u8"__fvalue_string_from", 1}, {u8"__ftime_now_ns", 0}, /* math start */ {u8"__fmath_acos", 1}, {u8"__fmath_acosh", 1}, {u8"__fmath_asin", 1}, {u8"__fmath_asinh", 1}, {u8"__fmath_atan", 1}, {u8"__fmath_atan2", 2}, {u8"__fmath_atanh", 1}, {u8"__fmath_ceil", 1}, {u8"__fmath_cos", 1}, {u8"__fmath_cosh", 1}, {u8"__fmath_exp", 1}, {u8"__fmath_expm1", 1}, {u8"__fmath_fabs", 1}, {u8"__fmath_floor", 1}, {u8"__fmath_fmod", 2}, {u8"__fmath_frexp", 1}, {u8"__fmath_gcd", 2}, {u8"__fmath_hypot", 2}, {u8"__fmath_isequal", 2}, {u8"__fmath_log", 1}, {u8"__fmath_log10", 1}, {u8"__fmath_log1p", 1}, {u8"__fmath_log2", 1}, {u8"__fmath_sin", 1}, {u8"__fmath_sinh", 1}, {u8"__fmath_sqrt", 1}, {u8"__fmath_tan", 1}, {u8"__fmath_tanh", 1}, {u8"__fmath_trunc", 1}, }; return builtinFunctionArgCounts; } const std::unordered_map &getBuiltinFunctions() { static const std::unordered_map builtinFunctions{ {u8"__fstdout_print", [](const std::vector &args) -> ObjectPtr { for (auto arg : args) { std::print("{}", arg->toStringIO().toBasicString()); } return std::make_shared(ValueType::IntClass(args.size())); }}, {u8"__fstdout_println", [](const std::vector &args) -> ObjectPtr { for (auto arg : args) { std::print("{}", arg->toStringIO().toBasicString()); } std::print("\n"); return std::make_shared(ValueType::IntClass(args.size())); }}, {u8"__fstdin_read", [](const std::vector &args) -> ObjectPtr { std::string input; std::cin >> input; return std::make_shared(FString::fromBasicString(input)); }}, {u8"__fstdin_readln", [](const std::vector &args) -> ObjectPtr { std::string line; std::getline(std::cin, line); return std::make_shared(FString::fromBasicString(line)); }}, {u8"__fvalue_type", [](const std::vector &args) -> ObjectPtr { return std::make_shared(args[0]->getTypeInfo().toString()); }}, {u8"__fvalue_int_parse", [](const std::vector &args) -> ObjectPtr { FString str = args[0]->as(); try { ValueType::IntClass val = std::stoi(str.toBasicString()); return std::make_shared(val); } catch (...) { throw RuntimeError(FString(std::format("Invalid int string for parsing", str.toBasicString()))); } }}, {u8"__fvalue_int_from", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; if (val->is()) { return std::make_shared( static_cast(val->as())); } else if (val->is()) { return std::make_shared( static_cast(val->as() ? 1 : 0)); } else { throw RuntimeError(FString(std::format("Type '{}' cannot be converted to int", val->getTypeInfo().toString().toBasicString()))); } }}, {u8"__fvalue_double_parse", [](const std::vector &args) -> ObjectPtr { FString str = args[0]->as(); try { ValueType::DoubleClass val = std::stod(str.toBasicString()); return std::make_shared(ValueType::DoubleClass(val)); } catch (...) { throw RuntimeError(FString(std::format("Invalid double string for parsing", str.toBasicString()))); } }}, {u8"__fvalue_double_from", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; if (val->is()) { return std::make_shared( static_cast(val->as())); } else if (val->is()) { return std::make_shared( ValueType::DoubleClass(val->as() ? 1.0 : 0.0)); } else { throw RuntimeError(FString(std::format("Type '{}' cannot be converted to double", val->getTypeInfo().toString().toBasicString()))); } }}, {u8"__fvalue_string_from", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; return std::make_shared(val->toStringIO()); }}, {u8"__ftime_now_ns", [](const std::vector &args) -> ObjectPtr { // returns nanoseconds using namespace Fig::Time; auto now = Clock::now(); return std::make_shared(static_cast( std::chrono::duration_cast(now - start_time).count())); }}, /* math start */ {u8"__fmath_acos", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(acos(d)); }}, {u8"__fmath_acosh", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(acosh(d)); }}, {u8"__fmath_asin", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(asin(d)); }}, {u8"__fmath_asinh", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(asinh(d)); }}, {u8"__fmath_atan", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(atan(d)); }}, {u8"__fmath_atan2", [](const std::vector &args) -> ObjectPtr { ValueType::DoubleClass y = args[0]->getNumericValue(); ValueType::DoubleClass x = args[1]->getNumericValue(); return std::make_shared(atan2(y, x)); }}, {u8"__fmath_atanh", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(atanh(d)); }}, {u8"__fmath_ceil", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(ceil(d)); }}, {u8"__fmath_cos", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(cos(d)); }}, {u8"__fmath_cosh", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(cosh(d)); }}, {u8"__fmath_exp", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(exp(d)); }}, {u8"__fmath_expm1", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(expm1(d)); }}, {u8"__fmath_fabs", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(fabs(d)); }}, {u8"__fmath_floor", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(floor(d)); }}, {u8"__fmath_fmod", [](const std::vector &args) -> ObjectPtr { ValueType::DoubleClass x = args[0]->getNumericValue(); ValueType::DoubleClass y = args[1]->getNumericValue(); return std::make_shared(fmod(x, y)); }}, {u8"__fmath_frexp", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); int e; return std::make_shared(List({std::make_shared(frexp(d, &e)), std::make_shared(static_cast(e))})); }}, {u8"__fmath_gcd", [](const std::vector &args) -> ObjectPtr { ValueType::IntClass x = args[0]->as(); ValueType::IntClass y = args[1]->as(); return std::make_shared(std::gcd(x, y)); }}, {u8"__fmath_hypot", [](const std::vector &args) -> ObjectPtr { ValueType::DoubleClass x = args[0]->getNumericValue(); ValueType::DoubleClass y = args[1]->getNumericValue(); return std::make_shared(hypot(x, y)); }}, {u8"__fmath_isequal", [](const std::vector &args) -> ObjectPtr { ValueType::DoubleClass x = args[0]->getNumericValue(); ValueType::DoubleClass y = args[1]->getNumericValue(); static const double epsilon = 1e-9; return std::make_shared(fabs(x - y) < epsilon); }}, {u8"__fmath_log", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(log(d)); }}, {u8"__fmath_log10", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(log10(d)); }}, {u8"__fmath_log1p", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(log1p(d)); }}, {u8"__fmath_log2", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(log2(d)); }}, {u8"__fmath_sin", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(sin(d)); }}, {u8"__fmath_sinh", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(sinh(d)); }}, {u8"__fmath_sqrt", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(sqrt(d)); }}, {u8"__fmath_tan", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(tan(d)); }}, {u8"__fmath_tanh", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(tanh(d)); }}, {u8"__fmath_trunc", [](const std::vector &args) -> ObjectPtr { ObjectPtr val = args[0]; ValueType::DoubleClass d = val->getNumericValue(); return std::make_shared(trunc(d)); }}, }; return builtinFunctions; } }