aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/StatementGen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/StatementGen.cc')
-rw-r--r--lib/CodeGen/StatementGen.cc38
1 files changed, 24 insertions, 14 deletions
diff --git a/lib/CodeGen/StatementGen.cc b/lib/CodeGen/StatementGen.cc
index c0bc223..5b60d29 100644
--- a/lib/CodeGen/StatementGen.cc
+++ b/lib/CodeGen/StatementGen.cc
@@ -97,7 +97,7 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
if (auto *Call = dynamic_cast<MemberCallStmtAST*>(Stmt)) {
Value *Result = emitMemberCall(Call->getCall());
const TypeInfo *Type = getExprTypeInfo(Call->getCall());
- if (Result && Type && Type->IsClass) materializeOperatorReceiver(Result, Type);
+ if (Result && Type && (Type->IsClass || containsString(Type))) materializeOperatorReceiver(Result, Type);
return;
}
@@ -106,7 +106,7 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
const FuncSig *Sig = FuncGen->hasFunction(Call->getCallee())
? resolveCall(Call->getCallee(), Call->getArgs()) : nullptr;
const TypeInfo *Type = Sig ? resolveType(Sig->ReturnTypeName) : nullptr;
- if (Result && Type && Type->IsClass) materializeOperatorReceiver(Result, Type);
+ if (Result && Type && (Type->IsClass || containsString(Type))) materializeOperatorReceiver(Result, Type);
return;
}
@@ -195,11 +195,7 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
Value *BoolVal = Builder->CreateICmpNE(Val, ConstantInt::get(*TheContext, APInt(64, 0)), "bool_cast");
Builder->CreateStore(BoolVal, Target.Addr);
} else if (TypeInfo->isString()) {
- Value *Mem = Builder->CreateCall(MallocFunc, ConstantInt::get(*TheContext, APInt(64, 1024)), "input_str");
- Args.push_back(ScanfStringFormatStr);
- Args.push_back(Mem);
- Builder->CreateCall(ScanfFunc, Args);
- Builder->CreateStore(Mem, Target.Addr);
+ emitMethodCall(TypeInfo->Name, Target.Addr, "READ_INPUT", {}, Stmt->getLine());
} else if (TypeInfo->isChar()) {
Value *CharFmt = Builder->CreateGlobalString(" %c", "fmt_in_char", 0, TheModule.get());
Args.push_back(CharFmt);
@@ -233,6 +229,8 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
reportError("Cannot OUTPUT the result of a PROCEDURE call");
continue;
}
+ if (TypeInfo->IsClass && !isObjectLValue(Expr))
+ materializeOperatorReceiver(Val, TypeInfo);
emitOutputValue(Val, TypeInfo, I + 1 == Exprs.size());
}
return;
@@ -243,7 +241,7 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
reportError("Cannot use a whole array as the OPENFILE filename");
return;
}
- Value *Name = emitCoercedExpr(Open->getFileName(), resolveType("STRING"));
+ Value *Name = emitCStringExpr(Open->getFileName());
if (!Name) return;
Files->emitOpen(Name, Open->getMode(), Open->getLine());
return;
@@ -260,7 +258,7 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
reportError("READFILE into entire array %s is not supported", Read->getVarName().c_str());
return;
}
- if (Info->TypeName != "STRING") {
+ if (!sameIdentifier(Info->TypeName, "STRING")) {
reportError("READFILE variable %s must be of type STRING (got %s)",
Read->getVarName().c_str(), Info->TypeName.c_str());
return;
@@ -269,11 +267,23 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
reportError("Cannot use a whole array as the READFILE filename");
return;
}
- Value *Name = emitCoercedExpr(Read->getFileName(), resolveType("STRING"));
+ Value *Name = emitCStringExpr(Read->getFileName());
if (!Name) return;
Value *LineStr = Files->emitRead(Name, Read->getLine());
if (!LineStr) return;
- Builder->CreateStore(LineStr, Info->Storage);
+ const auto *Type = resolveType(Info->TypeName);
+ for (const FuncSig *Sig : FuncGen->getOverloads(Type->Name + ".OPERATOR <-")) {
+ if (Sig->Params.size() == 1 && !Sig->Params[0].IsByRef &&
+ resolveType("C_STRING")->sameType(resolveType(Sig->Params[0].TypeName)) &&
+ checkOperatorAccess(*Sig)) {
+ FuncGen->emitCall(*Sig, {symbolAddress(*Info), LineStr});
+ auto Free = TheModule->getOrInsertFunction("free", FunctionType::get(
+ Type::getVoidTy(*TheContext), {PointerType::getUnqual(*TheContext)}, false));
+ Builder->CreateCall(Free, {LineStr});
+ return;
+ }
+ }
+ reportError("READFILE requires STRING.OPERATOR<-(Text : C_STRING)");
return;
}
@@ -282,8 +292,8 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
reportError("Cannot use a whole array in WRITEFILE");
return;
}
- Value *Name = emitCoercedExpr(Write->getFileName(), resolveType("STRING"));
- Value *Data = emitCoercedExpr(Write->getData(), resolveType("STRING"));
+ Value *Name = emitCStringExpr(Write->getFileName());
+ Value *Data = emitCStringExpr(Write->getData());
if (!Name || !Data) return;
Files->emitWrite(Name, Data, Write->getLine());
return;
@@ -294,7 +304,7 @@ void CodeGen::emitStmtImpl(StmtAST *Stmt) {
reportError("Cannot use a whole array as the CLOSEFILE filename");
return;
}
- Value *Name = emitCoercedExpr(Close->getFileName(), resolveType("STRING"));
+ Value *Name = emitCStringExpr(Close->getFileName());
if (!Name) return;
Files->emitClose(Name, Close->getLine());
return;