From 62b605c6c0ea13e9763c0a0115464007b13a8831 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Tue, 20 Oct 2026 11:57:16 +0000 Subject: refactor(strings): replace compiler builtins with the STRING library Construct literals as STRING values and route string operations through ordinary library functions and operators. Preserve value ownership in records, arrays, constants and file I/O. Co-Authored-By: Claude Opus 5.5 --- lib/CodeGen/ExpressionGen.cc | 108 ++----------------------------------------- 1 file changed, 4 insertions(+), 104 deletions(-) (limited to 'lib/CodeGen/ExpressionGen.cc') diff --git a/lib/CodeGen/ExpressionGen.cc b/lib/CodeGen/ExpressionGen.cc index a01cab2..15d0fe3 100644 --- a/lib/CodeGen/ExpressionGen.cc +++ b/lib/CodeGen/ExpressionGen.cc @@ -36,7 +36,8 @@ Value *CodeGen::emitExpr(ExprAST *Expr) { } if (auto *Str = dynamic_cast(Expr)) { - return StrHandler->createLiteral(Str->getVal()); + Value *Text = Builder->CreateGlobalString(Str->getVal()); + return Str->isCString() ? Text : emitStringFromCString(Text); } if (auto *Var = dynamic_cast(Expr)) { @@ -50,7 +51,7 @@ Value *CodeGen::emitExpr(ExprAST *Expr) { reportError("Unknown variable name %s", Var->getName().c_str()); return nullptr; } - if (Info->ConstantValue) return Info->ConstantValue; + if (Info->ConstantValue && !Info->Storage) return Info->ConstantValue; if (Info->IsArray) { return symbolAddress(*Info); } @@ -62,9 +63,6 @@ Value *CodeGen::emitExpr(ExprAST *Expr) { } Value *Loaded = Builder->CreateLoad(TypeInfo->LLVMType, symbolAddress(*Info), Var->getName().c_str()); - if (TypeInfo->isString()) { - Loaded = emitStringNullGuard(Loaded); - } return Loaded; } @@ -190,23 +188,6 @@ Value *CodeGen::emitBinaryOp(int Op, Value *L, const TypeInfo *LT, return emitCBinaryOp(Op, L, LT, R, RT, Line); if ((LT && LT->isUserKind()) || (RT && RT->isUserKind())) return emitUserKindBinaryOp(Op, L, LT, R, RT, Line); - if (Op == '&') { - L = coerceValueToType(L, resolveType("STRING")); - R = coerceValueToType(R, resolveType("STRING")); - return L && R ? StrHandler->emitConcat(L, R) : nullptr; - } - switch (Op) { - case tok_eq: case tok_ne: case '<': case '>': case tok_le: case tok_ge: - if ((LT && LT->isString()) || (RT && RT->isString())) { - if (!(LT && LT->isString() && RT && RT->isString())) { - reportError("STRING comparison requires two STRING operands"); - return nullptr; - } - return StrHandler->emitCompare(Op, L, R); - } - break; - default: break; - } return ArithHandler->emitBinaryOp(Op, L, R, Line); } @@ -238,93 +219,12 @@ Value *CodeGen::emitCall(const std::string &Callee, if (!Address) return nullptr; return Memory->emitRelease(Address, Line); } - if (Name == "LENGTH") { - Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING")); - if (!Str) return nullptr; - return StrHandler->emitLength(Str); - } - if (Name == "MID") { - Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING")); - Value *Start = emitCoercedExpr(ArgExprs[1].get(), resolveType("INTEGER")); - Value *Len = emitCoercedExpr(ArgExprs[2].get(), resolveType("INTEGER")); - if (!Str || !Start || !Len) return nullptr; - return StrHandler->emitMid(Str, Start, Len); - } - if (Name == "RIGHT") { - Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING")); - Value *Len = emitCoercedExpr(ArgExprs[1].get(), resolveType("INTEGER")); - if (!Str || !Len) return nullptr; - return StrHandler->emitRight(Str, Len); - } - if (Name == "LEFT") { - Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING")); - Value *Len = emitCoercedExpr(ArgExprs[1].get(), resolveType("INTEGER")); - if (!Str || !Len) return nullptr; - return StrHandler->emitLeft(Str, Len); - } - if (Name == "LCASE") { - Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING")); - if (!Str) return nullptr; - return StrHandler->emitLCase(Str); - } - if (Name == "UCASE") { - Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING")); - if (!Str) return nullptr; - return StrHandler->emitUCase(Str); - } - if (Name == "ASC") { - const TypeInfo *ArgType = getExprTypeInfo(ArgExprs[0].get()); - if (ArgType && (ArgType->isUserKind() || ArgType->isC())) { - reportError("ASC expects a CHAR or STRING (got %s)", ArgType->Name.c_str()); - return nullptr; - } - Value *ArgVal = emitExpr(ArgExprs[0].get()); - if (!ArgVal) return nullptr; - Value *CharVal = nullptr; - if (ArgType && ArgType->isChar()) { - CharVal = coerceValueToType(ArgVal, resolveType("CHAR")); - } else { - CharVal = Builder->CreateLoad(Type::getInt8Ty(*TheContext), ArgVal, "char_load"); - } - Value *AscVal = Builder->CreateZExt(CharVal, Type::getInt32Ty(*TheContext), "asc_val"); - return coerceValueToType(AscVal, resolveType("INTEGER")); - } - if (Name == "CHR") { - Value *IntVal = emitCoercedExpr(ArgExprs[0].get(), resolveType("INTEGER")); - if (!IntVal) return nullptr; - Value *CharVal = Builder->CreateTrunc(IntVal, Type::getInt8Ty(*TheContext), "chr_val"); - return coerceValueToType(CharVal, resolveType("STRING")); - } - if (Name == "IS_NUM") { - Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING")); - if (!Str) return nullptr; - return StrConvHandler->emitIsNum(Str); - } - if (Name == "NUM_TO_STR") { - const TypeInfo *ArgType = getExprTypeInfo(ArgExprs[0].get()); - if (ArgType && (ArgType->isUserKind() || ArgType->isC())) { - reportError("NUM_TO_STR expects a number (got %s)", ArgType->Name.c_str()); - return nullptr; - } - Value *NumV = emitExpr(ArgExprs[0].get()); - if (!NumV) return nullptr; - bool IsReal = NumV->getType()->isDoubleTy(); - if (NumV->getType()->isIntegerTy(8)) { - NumV = coerceValueToType(NumV, resolveType("INTEGER")); - } - return StrConvHandler->emitNumToStr(NumV, IsReal); - } - if (Name == "STR_TO_NUM") { - Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING")); - if (!Str) return nullptr; - return StrConvHandler->emitStrToNum(Str, true); - } if (Name == "EOF") { if (isWholeArrayVar(ArgExprs[0].get())) { reportError("Cannot use a whole array as the EOF filename"); return nullptr; } - Value *FileName = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING")); + Value *FileName = emitCStringExpr(ArgExprs[0].get()); if (!FileName) return nullptr; return Files->emitEof(FileName, Line); } -- cgit v1.3.1-4-g156e