diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-22 15:33:17 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-22 15:35:05 +0000 |
| commit | 8745f421b4cf7e1d54c17a360d46fab889ca12cc (patch) | |
| tree | 4c2a3508627db04493af35643580417d41b63f89 /lib/CodeGen/StatementGen.cc | |
| parent | 5e84edbe1a79c6a7752ee276ea6c1a4daef4fa8e (diff) | |
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 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/StatementGen.cc')
| -rw-r--r-- | lib/CodeGen/StatementGen.cc | 30 |
1 files changed, 5 insertions, 25 deletions
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<Value*> 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()); } |
