From 8745f421b4cf7e1d54c17a360d46fab889ca12cc Mon Sep 17 00:00:00 2001 From: _ov4 Date: Thu, 22 Oct 2026 15:33:17 +0000 Subject: feat(input)!: validate INPUT and read whole lines into STRING Scalar INPUT now reads one whitespace-delimited token through module-local IR helpers instead of scanf, then skips spaces and tabs and consumes one newline. INTEGER, REAL, BOOLEAN (TRUE or FALSE in any case) and CHAR are validated, and bad input or end of input is a runtime error. STRING INPUT reads the rest of the line. The unused scanf and REAL printf format globals are removed. Co-Authored-By: Claude Sonnet 5.5 --- lib/CodeGen/StatementGen.cc | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) (limited to 'lib/CodeGen/StatementGen.cc') diff --git a/lib/CodeGen/StatementGen.cc b/lib/CodeGen/StatementGen.cc index 0b14cf2..c161049 100644 --- a/lib/CodeGen/StatementGen.cc +++ b/lib/CodeGen/StatementGen.cc @@ -252,35 +252,15 @@ void CodeGen::emitInputStmt(InputStmtAST *In) { return; } - std::vector Args; if (TypeInfo->isC()) { - emitCInput(Target.Addr, TypeInfo); - } else if (TypeInfo->isReal()) { - Args.push_back(ScanfFloatFormatStr); - Args.push_back(Target.Addr); - Builder->CreateCall(ScanfFunc, Args); - } else if (TypeInfo->isBoolean()) { - AllocaInst *TempInt = CreateEntryBlockAlloca(Builder->GetInsertBlock()->getParent(), "tmp_bool_input"); - Args.push_back(ScanfFormatStr); - Args.push_back(TempInt); - Builder->CreateCall(ScanfFunc, Args); - - Value *Val = Builder->CreateLoad(Type::getInt64Ty(*TheContext), TempInt); - Value *BoolVal = Builder->CreateICmpNE(Val, ConstantInt::get(*TheContext, APInt(64, 0)), "bool_cast"); - Builder->CreateStore(BoolVal, Target.Addr); + emitCInput(Target.Addr, TypeInfo, In->getLine()); } else if (TypeInfo->isString()) { emitMethodCall(TypeInfo->Name, Target.Addr, "READ_INPUT", {}, In->getLine()); - } else if (TypeInfo->isChar()) { - Value *CharFmt = Builder->CreateGlobalString(" %c", "fmt_in_char", 0, TheModule.get()); - Args.push_back(CharFmt); - Args.push_back(Target.Addr); - Builder->CreateCall(ScanfFunc, Args); - } else if (TypeInfo->Kind == TypeKind::Integer) { - Args.push_back(ScanfFormatStr); - Args.push_back(Target.Addr); - Builder->CreateCall(ScanfFunc, Args); + } else if (TypeInfo->Kind == TypeKind::Integer || TypeInfo->isReal() || TypeInfo->isBoolean() || + TypeInfo->isChar()) { + emitScalarInput(Target.Addr, TypeInfo, In->getLine()); } else { - // Enum/Record/Pointer and any future kind: scanf'ing raw bytes + // Enum/Record/Pointer and any future kind: reading raw bytes // into typed storage would corrupt it — reject explicitly. reportError("INPUT is not supported for a value of type %s", TypeInfo->Name.c_str()); } -- cgit v1.3.1-4-g156e