aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/ExpressionGen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/ExpressionGen.cc')
-rw-r--r--lib/CodeGen/ExpressionGen.cc108
1 files changed, 4 insertions, 104 deletions
diff --git a/lib/CodeGen/ExpressionGen.cc b/lib/CodeGen/ExpressionGen.cc
index a01cab2..15d0fe3 100644
--- a/lib/CodeGen/ExpressionGen.cc
+++ b/lib/CodeGen/ExpressionGen.cc
@@ -36,7 +36,8 @@ Value *CodeGen::emitExpr(ExprAST *Expr) {
}
if (auto *Str = dynamic_cast<StringExprAST*>(Expr)) {
- return StrHandler->createLiteral(Str->getVal());
+ Value *Text = Builder->CreateGlobalString(Str->getVal());
+ return Str->isCString() ? Text : emitStringFromCString(Text);
}
if (auto *Var = dynamic_cast<VariableExprAST*>(Expr)) {
@@ -50,7 +51,7 @@ Value *CodeGen::emitExpr(ExprAST *Expr) {
reportError("Unknown variable name %s", Var->getName().c_str());
return nullptr;
}
- if (Info->ConstantValue) return Info->ConstantValue;
+ if (Info->ConstantValue && !Info->Storage) return Info->ConstantValue;
if (Info->IsArray) {
return symbolAddress(*Info);
}
@@ -62,9 +63,6 @@ Value *CodeGen::emitExpr(ExprAST *Expr) {
}
Value *Loaded = Builder->CreateLoad(TypeInfo->LLVMType, symbolAddress(*Info), Var->getName().c_str());
- if (TypeInfo->isString()) {
- Loaded = emitStringNullGuard(Loaded);
- }
return Loaded;
}
@@ -190,23 +188,6 @@ Value *CodeGen::emitBinaryOp(int Op, Value *L, const TypeInfo *LT,
return emitCBinaryOp(Op, L, LT, R, RT, Line);
if ((LT && LT->isUserKind()) || (RT && RT->isUserKind()))
return emitUserKindBinaryOp(Op, L, LT, R, RT, Line);
- if (Op == '&') {
- L = coerceValueToType(L, resolveType("STRING"));
- R = coerceValueToType(R, resolveType("STRING"));
- return L && R ? StrHandler->emitConcat(L, R) : nullptr;
- }
- switch (Op) {
- case tok_eq: case tok_ne: case '<': case '>': case tok_le: case tok_ge:
- if ((LT && LT->isString()) || (RT && RT->isString())) {
- if (!(LT && LT->isString() && RT && RT->isString())) {
- reportError("STRING comparison requires two STRING operands");
- return nullptr;
- }
- return StrHandler->emitCompare(Op, L, R);
- }
- break;
- default: break;
- }
return ArithHandler->emitBinaryOp(Op, L, R, Line);
}
@@ -238,93 +219,12 @@ Value *CodeGen::emitCall(const std::string &Callee,
if (!Address) return nullptr;
return Memory->emitRelease(Address, Line);
}
- if (Name == "LENGTH") {
- Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
- if (!Str) return nullptr;
- return StrHandler->emitLength(Str);
- }
- if (Name == "MID") {
- Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
- Value *Start = emitCoercedExpr(ArgExprs[1].get(), resolveType("INTEGER"));
- Value *Len = emitCoercedExpr(ArgExprs[2].get(), resolveType("INTEGER"));
- if (!Str || !Start || !Len) return nullptr;
- return StrHandler->emitMid(Str, Start, Len);
- }
- if (Name == "RIGHT") {
- Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
- Value *Len = emitCoercedExpr(ArgExprs[1].get(), resolveType("INTEGER"));
- if (!Str || !Len) return nullptr;
- return StrHandler->emitRight(Str, Len);
- }
- if (Name == "LEFT") {
- Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
- Value *Len = emitCoercedExpr(ArgExprs[1].get(), resolveType("INTEGER"));
- if (!Str || !Len) return nullptr;
- return StrHandler->emitLeft(Str, Len);
- }
- if (Name == "LCASE") {
- Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
- if (!Str) return nullptr;
- return StrHandler->emitLCase(Str);
- }
- if (Name == "UCASE") {
- Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
- if (!Str) return nullptr;
- return StrHandler->emitUCase(Str);
- }
- if (Name == "ASC") {
- const TypeInfo *ArgType = getExprTypeInfo(ArgExprs[0].get());
- if (ArgType && (ArgType->isUserKind() || ArgType->isC())) {
- reportError("ASC expects a CHAR or STRING (got %s)", ArgType->Name.c_str());
- return nullptr;
- }
- Value *ArgVal = emitExpr(ArgExprs[0].get());
- if (!ArgVal) return nullptr;
- Value *CharVal = nullptr;
- if (ArgType && ArgType->isChar()) {
- CharVal = coerceValueToType(ArgVal, resolveType("CHAR"));
- } else {
- CharVal = Builder->CreateLoad(Type::getInt8Ty(*TheContext), ArgVal, "char_load");
- }
- Value *AscVal = Builder->CreateZExt(CharVal, Type::getInt32Ty(*TheContext), "asc_val");
- return coerceValueToType(AscVal, resolveType("INTEGER"));
- }
- if (Name == "CHR") {
- Value *IntVal = emitCoercedExpr(ArgExprs[0].get(), resolveType("INTEGER"));
- if (!IntVal) return nullptr;
- Value *CharVal = Builder->CreateTrunc(IntVal, Type::getInt8Ty(*TheContext), "chr_val");
- return coerceValueToType(CharVal, resolveType("STRING"));
- }
- if (Name == "IS_NUM") {
- Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
- if (!Str) return nullptr;
- return StrConvHandler->emitIsNum(Str);
- }
- if (Name == "NUM_TO_STR") {
- const TypeInfo *ArgType = getExprTypeInfo(ArgExprs[0].get());
- if (ArgType && (ArgType->isUserKind() || ArgType->isC())) {
- reportError("NUM_TO_STR expects a number (got %s)", ArgType->Name.c_str());
- return nullptr;
- }
- Value *NumV = emitExpr(ArgExprs[0].get());
- if (!NumV) return nullptr;
- bool IsReal = NumV->getType()->isDoubleTy();
- if (NumV->getType()->isIntegerTy(8)) {
- NumV = coerceValueToType(NumV, resolveType("INTEGER"));
- }
- return StrConvHandler->emitNumToStr(NumV, IsReal);
- }
- if (Name == "STR_TO_NUM") {
- Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
- if (!Str) return nullptr;
- return StrConvHandler->emitStrToNum(Str, true);
- }
if (Name == "EOF") {
if (isWholeArrayVar(ArgExprs[0].get())) {
reportError("Cannot use a whole array as the EOF filename");
return nullptr;
}
- Value *FileName = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
+ Value *FileName = emitCStringExpr(ArgExprs[0].get());
if (!FileName) return nullptr;
return Files->emitEof(FileName, Line);
}