From 713a313b06256a13ddefa5e257e3b80f8aa808ba Mon Sep 17 00:00:00 2001 From: _ov4 Date: Thu, 22 Oct 2026 15:32:49 +0000 Subject: feat(codegen): convert implicitly between CHAR and STRING A CHAR becomes a one-character STRING in &, comparisons, assignment, parameter passing and RETURN. A STRING becomes a CHAR in assignment, parameter passing and RETURN, with a runtime error when its length is not 1. CHAR with INTEGER or BOOLEAN still does not convert. Co-Authored-By: Claude Sonnet 5.5 --- lib/CodeGen/CallGen.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'lib/CodeGen/CallGen.cc') diff --git a/lib/CodeGen/CallGen.cc b/lib/CodeGen/CallGen.cc index 4631332..43c0dd4 100644 --- a/lib/CodeGen/CallGen.cc +++ b/lib/CodeGen/CallGen.cc @@ -225,6 +225,30 @@ const FuncSig *CodeGen::resolveCall(const std::string &Name, } } if (Ordinary) return Ordinary; + // Failing an exact match, CHAR and STRING arguments convert into one + // another; the overload must be unique. + if (!HasTemplates && !HasExplicit) { + auto Scalar = [](const TypeInfo *T) { return T && (T->Kind == TypeKind::Char || T->isString()); }; + const FuncSig *Converted = nullptr; + for (const FuncSig *Sig : Overloads) { + if (Sig->Params.size() != Actual.size()) continue; + bool Match = true; + for (size_t I = 0; I < Actual.size() && Match; ++I) { + const ParamSig &P = Sig->Params[I]; + const TypeInfo *Formal = Types->resolve(P.TypeName); + Match = Actual[I].Rank == (P.IsArray ? P.Rank : 0) && Actual[I].Type && + (Actual[I].Type->sameType(Formal) || + (!P.IsByRef && !P.IsArray && Scalar(Actual[I].Type) && Scalar(Formal))); + } + if (!Match) continue; + if (Converted) { + reportError("Ambiguous call to %s(%s)", Name.c_str(), Key.c_str()); + return nullptr; + } + Converted = Sig; + } + if (Converted) return Converted; + } if (HasTemplates) { // A matching non-variadic template wins before any variadic candidate. for (bool Variadic : {false, true}) { -- cgit v1.3.1-4-g156e