#pragma once #include #include #include #include #include #include #include namespace Fig { namespace Builtins { const std::unordered_map builtinValues = { {u8"null", Object::getNullInstance()}, {u8"true", Object::getTrueInstance()}, {u8"false", Object::getFalseInstance()}, }; using BuiltinFunction = std::function &)>; 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}, }; const std::unordered_map builtinFunctions{ {u8"__fstdout_print", [](const std::vector &args) -> ObjectPtr { for (auto arg : args) { std::print("{}", arg->toString().toBasicString()); } return std::make_shared(ValueType::IntClass(args.size())); }}, {u8"__fstdout_println", [](const std::vector &args) -> ObjectPtr { for (auto arg : args) { std::print("{}", arg->toString().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(FStringView(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(FStringView(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(FStringView(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(FStringView(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->toString()); }}, }; inline bool isBuiltinFunction(const FString &name) { return builtinFunctions.find(name) != builtinFunctions.end(); } inline BuiltinFunction getBuiltinFunction(const FString &name) { auto it = builtinFunctions.find(name); if (it == builtinFunctions.end()) { throw RuntimeError(FStringView(std::format("Builtin function '{}' not found", name.toBasicString()))); } return it->second; } inline int getBuiltinFunctionParamCount(const FString &name) { auto it = builtinFunctionArgCounts.find(name); if (it == builtinFunctionArgCounts.end()) { throw RuntimeError(FStringView(std::format("Builtin function '{}' not found", name.toBasicString()))); } return it->second; } }; // namespace Builtins }; // namespace Fig