aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-22 03:45:06 +0000
committer_ov4 <ov4@ov4.org>2026-10-22 03:58:26 +0000
commit1d2bb133b7a3540aeb81c5f9616cb366aebc919f (patch)
treeb4b90c1d991ad8dd05033dfbdbb18a60a1343cfe
parent91e506e404c0d285ec1ec77196e83248c8c77161 (diff)
refactor(codegen): share file keyword filename operand emission
EOF, OPENFILE, READFILE and CLOSEFILE each rejected a whole-array filename and then emitted it as a C string. Route them through a private emitFileNameOperand helper; diagnostics are unchanged. WRITEFILE keeps its own combined check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--include/cps/CodeGen.h1
-rw-r--r--lib/CodeGen/ExpressionGen.cc6
-rw-r--r--lib/CodeGen/StatementGen.cc28
3 files changed, 15 insertions, 20 deletions
diff --git a/include/cps/CodeGen.h b/include/cps/CodeGen.h
index 73068bf..2d77284 100644
--- a/include/cps/CodeGen.h
+++ b/include/cps/CodeGen.h
@@ -128,6 +128,7 @@ class CodeGen {
llvm::Value *emitStringFromCString(llvm::Value *Text);
llvm::Value *emitStringCString(llvm::Value *Value);
llvm::Value *emitCStringExpr(ExprAST *Expr);
+ llvm::Value *emitFileNameOperand(ExprAST *E, const char *Keyword);
bool containsString(const TypeInfo *Type) const;
std::unique_ptr<TypeSystem> Types;
diff --git a/lib/CodeGen/ExpressionGen.cc b/lib/CodeGen/ExpressionGen.cc
index 3377a39..ece055a 100644
--- a/lib/CodeGen/ExpressionGen.cc
+++ b/lib/CodeGen/ExpressionGen.cc
@@ -225,11 +225,7 @@ Value *CodeGen::emitCall(const std::string &Callee,
return Memory->emitRelease(Address, Line);
}
if (Name == "EOF") {
- if (isWholeArrayVar(ArgExprs[0].get())) {
- reportError("Cannot use a whole array as the EOF filename");
- return nullptr;
- }
- Value *FileName = emitCStringExpr(ArgExprs[0].get());
+ Value *FileName = emitFileNameOperand(ArgExprs[0].get(), "EOF");
if (!FileName) return nullptr;
return Files->emitEof(FileName, Line);
}
diff --git a/lib/CodeGen/StatementGen.cc b/lib/CodeGen/StatementGen.cc
index 40fe394..f4cd661 100644
--- a/lib/CodeGen/StatementGen.cc
+++ b/lib/CodeGen/StatementGen.cc
@@ -239,11 +239,7 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
}
if (auto *Open = dynamic_cast<OpenFileStmtAST*>(Stmt)) {
- if (isWholeArrayVar(Open->getFileName())) {
- reportError("Cannot use a whole array as the OPENFILE filename");
- return;
- }
- Value *Name = emitCStringExpr(Open->getFileName());
+ Value *Name = emitFileNameOperand(Open->getFileName(), "OPENFILE");
if (!Name) return;
Files->emitOpen(Name, Open->getMode(), Open->getLine());
return;
@@ -265,11 +261,7 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
Read->getVarName().c_str(), Info->TypeName.c_str());
return;
}
- if (isWholeArrayVar(Read->getFileName())) {
- reportError("Cannot use a whole array as the READFILE filename");
- return;
- }
- Value *Name = emitCStringExpr(Read->getFileName());
+ Value *Name = emitFileNameOperand(Read->getFileName(), "READFILE");
if (!Name) return;
Value *LineStr = Files->emitRead(Name, Read->getLine());
if (!LineStr) return;
@@ -302,11 +294,7 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
}
if (auto *Close = dynamic_cast<CloseFileStmtAST*>(Stmt)) {
- if (isWholeArrayVar(Close->getFileName())) {
- reportError("Cannot use a whole array as the CLOSEFILE filename");
- return;
- }
- Value *Name = emitCStringExpr(Close->getFileName());
+ Value *Name = emitFileNameOperand(Close->getFileName(), "CLOSEFILE");
if (!Name) return;
Files->emitClose(Name, Close->getLine());
return;
@@ -346,3 +334,13 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
return;
}
}
+
+// File keywords take their filename as a STRING-valued expression; a whole
+// array is rejected before evaluation.
+Value *CodeGen::emitFileNameOperand(ExprAST *E, const char *Keyword) {
+ if (isWholeArrayVar(E)) {
+ reportError("Cannot use a whole array as the %s filename", Keyword);
+ return nullptr;
+ }
+ return emitCStringExpr(E);
+}