aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/StringConversionHandler.cc
diff options
context:
space:
mode:
author_ov4 <hausemasterstream@gmail.com>2026-03-03 07:22:19 +0000
committer_ov4 <hausemasterstream@gmail.com>2026-03-03 07:22:19 +0000
commitcc7b9b34e99fa17357e14ac69f5fb2d1535b5512 (patch)
tree40f093ef98c062a14a3b839ad2337646437645e9 /lib/CodeGen/StringConversionHandler.cc
parent1b524f75401a6318fbaf3fee0bfcbe59348f2e51 (diff)
Added all built-in functions
Diffstat (limited to 'lib/CodeGen/StringConversionHandler.cc')
-rw-r--r--lib/CodeGen/StringConversionHandler.cc71
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/CodeGen/StringConversionHandler.cc b/lib/CodeGen/StringConversionHandler.cc
new file mode 100644
index 0000000..62b99d7
--- /dev/null
+++ b/lib/CodeGen/StringConversionHandler.cc
@@ -0,0 +1,71 @@
+#include "cps/StringConversionHandler.h"
+
+using namespace llvm;
+using namespace cps;
+
+StringConversionHandler::StringConversionHandler(LLVMContext &Ctx, IRBuilder<> &B, llvm::Module &M)
+ : Context(Ctx), Builder(B), Module(M) {
+ setupExternalFunctions();
+}
+
+void StringConversionHandler::setupExternalFunctions() {
+ FunctionType *SprintfType = FunctionType::get(Type::getInt32Ty(Context), {PointerType::getUnqual(Context), PointerType::getUnqual(Context)}, true);
+ SprintfFunc = Module.getOrInsertFunction("sprintf", SprintfType);
+
+ FunctionType *StrtolType = FunctionType::get(Type::getInt64Ty(Context), {PointerType::getUnqual(Context), PointerType::getUnqual(Context), Type::getInt32Ty(Context)}, false);
+ StrtolFunc = Module.getOrInsertFunction("strtol", StrtolType);
+
+ FunctionType *StrtodType = FunctionType::get(Type::getDoubleTy(Context), {PointerType::getUnqual(Context), PointerType::getUnqual(Context)}, false);
+ StrtodFunc = Module.getOrInsertFunction("strtod", StrtodType);
+
+ FunctionType *MallocType = FunctionType::get(PointerType::getUnqual(Context), {Type::getInt64Ty(Context)}, false);
+ MallocFunc = Module.getOrInsertFunction("malloc", MallocType);
+}
+
+Value *StringConversionHandler::emitNumToStr(Value *Num, bool IsReal) {
+ Value *AllocSize = ConstantInt::get(Type::getInt64Ty(Context), 64);
+ Value *Buffer = Builder.CreateCall(MallocFunc, AllocSize, "num_str_buf");
+
+ Value *FormatStr;
+ if (IsReal) {
+ FormatStr = Builder.CreateGlobalStringPtr("%f");
+ } else {
+ FormatStr = Builder.CreateGlobalStringPtr("%d");
+ }
+
+ Builder.CreateCall(SprintfFunc, {Buffer, FormatStr, Num});
+ return Buffer;
+}
+
+Value *StringConversionHandler::emitStrToNum(Value *Str, bool AsReal) {
+ Value *NullPtr = ConstantPointerNull::get(PointerType::getUnqual(Context));
+ if (AsReal) {
+ return Builder.CreateCall(StrtodFunc, {Str, NullPtr}, "str_to_real");
+ } else {
+ Value *Base = ConstantInt::get(Type::getInt32Ty(Context), 10);
+ return Builder.CreateCall(StrtolFunc, {Str, NullPtr, Base}, "str_to_int");
+ }
+}
+
+Value *StringConversionHandler::emitIsNum(Value *Str) {
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ IRBuilder<> TmpB(&TheFunction->getEntryBlock(), TheFunction->getEntryBlock().begin());
+ AllocaInst *EndPtrAlloc = TmpB.CreateAlloca(PointerType::getUnqual(Context), nullptr, "endptr_alloc");
+
+ Builder.CreateCall(StrtodFunc, {Str, EndPtrAlloc});
+ Value *EndPtrVal = Builder.CreateLoad(PointerType::getUnqual(Context), EndPtrAlloc, "endptr_val");
+
+ FunctionType *StrLenType = FunctionType::get(Type::getInt64Ty(Context), {PointerType::getUnqual(Context)}, false);
+ FunctionCallee StrLenFunc = Module.getOrInsertFunction("strlen", StrLenType);
+ Value *Len = Builder.CreateCall(StrLenFunc, Str, "str_len");
+
+ Value *ExpectedEndPtr = Builder.CreateInBoundsGEP(Type::getInt8Ty(Context), Str, Len);
+
+ Value *IsMatch = Builder.CreateICmpEQ(EndPtrVal, ExpectedEndPtr, "is_full_match");
+
+ Value *Zero = ConstantInt::get(Type::getInt64Ty(Context), 0);
+ Value *IsNotEmpty = Builder.CreateICmpSGT(Len, Zero, "is_not_empty");
+
+ return Builder.CreateAnd(IsMatch, IsNotEmpty, "is_num_bool");
+}