diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/CodeGen/ArithmeticHandler.cc | 20 | ||||
| -rw-r--r-- | lib/CodeGen/CodeGen.cc | 20 | ||||
| -rw-r--r-- | lib/Lexer/Lexer.cc | 4 | ||||
| -rw-r--r-- | lib/Parser/Parser.cc | 18 |
4 files changed, 58 insertions, 4 deletions
diff --git a/lib/CodeGen/ArithmeticHandler.cc b/lib/CodeGen/ArithmeticHandler.cc index 762f0a3..df83513 100644 --- a/lib/CodeGen/ArithmeticHandler.cc +++ b/lib/CodeGen/ArithmeticHandler.cc @@ -1,4 +1,5 @@ #include "cps/ArithmeticHandler.h" +#include "cps/Lexer.h" #include <cstdio> using namespace llvm; @@ -20,7 +21,6 @@ Value *ArithmeticHandler::emitBinaryOp(int Op, Value *LHS, Value *RHS, int Line) return Builder.CreateFDiv(LVal, RVal, "divtmp"); } - // DIV / MOD : Only Integer. if (Op == tok_div || Op == tok_mod) { if (!LIsInt || !RIsInt) { fprintf(stderr, "Error: DIV and MOD operators require INTEGER operands.\n"); @@ -29,6 +29,24 @@ Value *ArithmeticHandler::emitBinaryOp(int Op, Value *LHS, Value *RHS, int Line) if (Op == tok_div) return Builder.CreateSDiv(LHS, RHS, "div_int_tmp"); if (Op == tok_mod) return Builder.CreateSRem(LHS, RHS, "mod_tmp"); } + + if (Op == tok_and || Op == tok_or) { + Value *L = LHS; + Value *R = RHS; + + if (L->getType()->isIntegerTy(64)) + L = Builder.CreateICmpNE(L, ConstantInt::get(Context, APInt(64, 0)), "tobool"); + if (R->getType()->isIntegerTy(64)) + R = Builder.CreateICmpNE(R, ConstantInt::get(Context, APInt(64, 0)), "tobool"); + + if (L->getType()->isDoubleTy()) + L = Builder.CreateFCmpONE(L, ConstantFP::get(Context, APFloat(0.0)), "tobool"); + if (R->getType()->isDoubleTy()) + R = Builder.CreateFCmpONE(R, ConstantFP::get(Context, APFloat(0.0)), "tobool"); + + if (Op == tok_and) return Builder.CreateAnd(L, R, "andtmp"); + if (Op == tok_or) return Builder.CreateOr(L, R, "ortmp"); + } if (LIsDouble || RIsDouble) { Value *LVal = LHS; diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc index da6b005..95e3768 100644 --- a/lib/CodeGen/CodeGen.cc +++ b/lib/CodeGen/CodeGen.cc @@ -105,6 +105,21 @@ Value *CodeGen::emitExpr(ExprAST *Expr) { return Arrays->emitArrayAccess(ArrAcc, *this); } + if (auto *Unary = dynamic_cast<UnaryExprAST*>(Expr)) { + Value *Operand = emitExpr(Unary->getOperand()); + if (!Operand) return nullptr; + + if (Unary->getOp() == tok_not) { + if (Operand->getType()->isIntegerTy(64)) { + Operand = Builder->CreateICmpNE(Operand, ConstantInt::get(*TheContext, APInt(64, 0)), "tobool"); + } else if (Operand->getType()->isDoubleTy()) { + Operand = Builder->CreateFCmpONE(Operand, ConstantFP::get(*TheContext, APFloat(0.0)), "tobool"); + } + + return Builder->CreateNot(Operand, "nottmp"); + } + } + if (auto *Bin = dynamic_cast<BinaryExprAST*>(Expr)) { Value *L = emitExpr(Bin->getLHS()); Value *R = emitExpr(Bin->getRHS()); @@ -385,6 +400,11 @@ void CodeGen::emitStmt(StmtAST *Stmt) { if (AI->getAllocatedType() == Type::getDoubleTy(*TheContext) && Val->getType()->isIntegerTy(64)) { Val = Builder->CreateSIToFP(Val, Type::getDoubleTy(*TheContext)); } + + if (AI->getAllocatedType() == Type::getInt64Ty(*TheContext) && Val->getType()->isIntegerTy(1)) { + Val = Builder->CreateZExt(Val, Type::getInt64Ty(*TheContext)); + } + Builder->CreateStore(Val, Alloca); } } diff --git a/lib/Lexer/Lexer.cc b/lib/Lexer/Lexer.cc index ad7b4a1..d9eb09b 100644 --- a/lib/Lexer/Lexer.cc +++ b/lib/Lexer/Lexer.cc @@ -53,6 +53,10 @@ int Lexer::gettok() { if (IdentifierStr == "DIV") return tok_div; if (IdentifierStr == "MOD") return tok_mod; + + if (IdentifierStr == "AND") return tok_and; + if (IdentifierStr == "OR") return tok_or; + if (IdentifierStr == "NOT") return tok_not; if (IdentifierStr == "FUNCTION") return tok_function; if (IdentifierStr == "ENDFUNCTION") return tok_endfunction; diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc index 32a6db8..c5e91f9 100644 --- a/lib/Parser/Parser.cc +++ b/lib/Parser/Parser.cc @@ -6,6 +6,9 @@ using namespace cps; Parser::Parser(Lexer &L) : Lex(L) { getNextToken(); + BinopPrecedence[tok_or] = 3; + BinopPrecedence[tok_and] = 5; + BinopPrecedence[tok_eq] = 10; BinopPrecedence[tok_ne] = 10; BinopPrecedence[tok_le] = 10; @@ -40,7 +43,6 @@ std::unique_ptr<ExprAST> Parser::ParseNumberExpr() { getNextToken(); return Result; } - // Default to Int auto Result = std::make_unique<IntegerExprAST>(Lex.NumVal); getNextToken(); return Result; @@ -126,6 +128,16 @@ std::unique_ptr<ExprAST> Parser::ParsePrimary() { } } +std::unique_ptr<ExprAST> Parser::ParseUnary() { + if (CurTok == tok_not) { + getNextToken(); + auto Operand = ParseUnary(); + if (!Operand) return nullptr; + return std::make_unique<UnaryExprAST>(tok_not, std::move(Operand)); + } + return ParsePrimary(); +} + std::unique_ptr<ExprAST> Parser::ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) { while (true) { int TokPrec = GetTokPrecedence(); @@ -135,7 +147,7 @@ std::unique_ptr<ExprAST> Parser::ParseBinOpRHS(int ExprPrec, std::unique_ptr<Exp int Line = Lex.getLine(); getNextToken(); - auto RHS = ParsePrimary(); + auto RHS = ParseUnary(); if (!RHS) return nullptr; int NextPrec = GetTokPrecedence(); @@ -149,7 +161,7 @@ std::unique_ptr<ExprAST> Parser::ParseBinOpRHS(int ExprPrec, std::unique_ptr<Exp } std::unique_ptr<ExprAST> Parser::ParseExpression() { - auto LHS = ParsePrimary(); + auto LHS = ParseUnary(); if (!LHS) return nullptr; return ParseBinOpRHS(0, std::move(LHS)); } |
