diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-30 14:31:07 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-30 14:31:07 +0000 |
| commit | 0cf54b4f77ccf8376341950b02ceb7c1d1268ed7 (patch) | |
| tree | eebbba01063451c28f0a2e1cc048215f50beb98f /lib/CodeGen/StringValueGen.cc | |
| parent | 4cb0d9b196008bc55dbfcdac1f9211dbbc879895 (diff) | |
refactor(strings): construct string values implicitly from raw literals
Keep double-quoted literals and text constants as C_STRING values. Use
marked STRING constructors for text and CHAR conversion, preserving
string operations and I/O through the existing class machinery.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/StringValueGen.cc')
| -rw-r--r-- | lib/CodeGen/StringValueGen.cc | 43 |
1 files changed, 11 insertions, 32 deletions
diff --git a/lib/CodeGen/StringValueGen.cc b/lib/CodeGen/StringValueGen.cc index 989bac8..7a42e49 100644 --- a/lib/CodeGen/StringValueGen.cc +++ b/lib/CodeGen/StringValueGen.cc @@ -35,38 +35,15 @@ Value *CodeGen::emitStringFromCString(Value *Text) { return Builder->CreateLoad(Type->LLVMType, Storage, "string"); } -// CHAR -> STRING: STRING.NEW(1, ch). -Value *CodeGen::emitStringFromChar(Value *Ch) { - const TypeInfo *Type = requireStringType(); - if (!Type || !Ch) return nullptr; - const TypeInfo *CChar = resolveType("C_CHAR"); - const FuncSig *Constructor = nullptr; - for (const FuncSig *Sig : FuncGen->getOverloads(Type->Name + ".NEW")) - if (Sig->Params.size() == 2 && !Sig->Params[1].IsArray && !Sig->Params[1].IsByRef && - CChar->sameType(resolveType(Sig->Params[1].TypeName))) - Constructor = Sig; - if (!Constructor) { - reportError("STRING requires a constructor NEW(Count : INTEGER, Ch : C_CHAR)"); - return nullptr; - } - if (!checkOperatorAccess(*Constructor)) return nullptr; - auto *Storage = CreateEntryBlockAlloca(Builder->GetInsertBlock()->getParent(), - Type->LLVMType, "string_value"); - Builder->CreateStore(Types->getZeroValue(Type->Name), Storage); - if (!emitFieldDefaults(Type, Storage, DiagnosticLine)) return nullptr; - Value *Count = ConstantInt::get(resolveType("INTEGER")->LLVMType, 1); - if (!FuncGen->emitCall(*Constructor, {Storage, Count, Ch})) return nullptr; - // The consumer takes ownership, just as with an ordinary class result. - return Builder->CreateLoad(Type->LLVMType, Storage, "string"); -} - // STRING -> CHAR: the string must hold exactly one character. Value *CodeGen::emitCharFromString(ExprAST *Expr, int Line) { const TypeInfo *Type = requireStringType(); if (!Type) return nullptr; - Value *Text = emitExpr(Expr); + const TypeInfo *Source = getExprTypeInfo(Expr); + Value *Text = emitCoercedExpr(Expr, Type); if (!Text) return nullptr; - if (!isObjectLValue(Expr)) materializeOperatorReceiver(Text, Type); + if (!isObjectLValue(Expr) || !Source || !Source->sameType(Type)) + materializeOperatorReceiver(Text, Type); auto *Receiver = CreateEntryBlockAlloca(Builder->GetInsertBlock()->getParent(), Type->LLVMType, "string_view"); Builder->CreateStore(Text, Receiver); @@ -101,14 +78,16 @@ Value *CodeGen::emitStringCString(Value *Value) { } Value *CodeGen::emitCStringExpr(ExprAST *Expr) { - const TypeInfo *Type = getExprTypeInfo(Expr); - if (!Type || !Type->isString() || isWholeArrayVar(Expr)) { - reportError("Expected a STRING value"); + const TypeInfo *Source = getExprTypeInfo(Expr); + const TypeInfo *Type = requireStringType(); + if (!Type || !Source || isWholeArrayVar(Expr) || + (!Source->sameType(Type) && !findImplicitConstructor(Source, Type))) { + reportError("Expected a STRING value or an IMPLICIT conversion to STRING"); return nullptr; } - Value *Value = emitExpr(Expr); + Value *Value = emitCoercedExpr(Expr, Type); if (!Value) return nullptr; - if (!isObjectLValue(Expr)) materializeOperatorReceiver(Value, Type); + if (!isObjectLValue(Expr) || !Source->sameType(Type)) materializeOperatorReceiver(Value, Type); return emitStringCString(Value); } |
