Nicolas Winkler 6 éve
szülő
commit
28d8ecdae5
10 módosított fájl, 75 hozzáadás és 70 törlés
  1. 1 1
      src/CodeGeneration.cpp
  2. 37 37
      src/CodegenVisitor.cpp
  3. 7 7
      src/CodegenVisitor.h
  4. 1 0
      src/Driver.cpp
  5. 1 1
      src/Operation.h
  6. 1 1
      src/Scope.cpp
  7. 6 6
      src/Semantic.cpp
  8. 11 10
      src/Semantic.h
  9. 7 4
      src/Type.cpp
  10. 3 3
      src/Type.h

+ 1 - 1
src/CodeGeneration.cpp

@@ -273,7 +273,7 @@ llvm::Function* qlow::gen::FunctionGenerator::generate(void)
     //Value* val = llvm::ConstantFP::get(context, llvm::APFloat(5.0));
     
     builder.SetInsertPoint(getCurrentBlock());
-    if (method.returnType->equals(*sem::Type::VOID)) {
+    if (method.returnType->equals(sem::NativeType(sem::NativeType::Type::VOID))) {
         if (!getCurrentBlock()->getTerminator())
             builder.CreateRetVoid();
     }

+ 37 - 37
src/CodegenVisitor.cpp

@@ -9,26 +9,28 @@
 
 using namespace qlow;
 
-std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::LocalVariableExpression& lve, llvm::IRBuilder<>& builder)
+llvm::Value* ExpressionCodegenVisitor::visit(sem::LocalVariableExpression& lve, llvm::IRBuilder<>& builder)
 {
     assert(lve.var->allocaInst != nullptr);
     if (llvm::dyn_cast<llvm::AllocaInst>(lve.var->allocaInst)) {
         llvm::Value* val = builder.CreateLoad(lve.var->allocaInst);
-        return { val, lve.var->type.get() };
+        return val;
     }
     else {
-        return { lve.var->allocaInst, lve.var->type.get() };
+        return lve.var->allocaInst;
     }
 }
 
 
-std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::BinaryOperation& binop, llvm::IRBuilder<>& builder)
+llvm::Value* ExpressionCodegenVisitor::visit(sem::BinaryOperation& binop, llvm::IRBuilder<>& builder)
 {
     using llvm::Value;
     using sem::Type;
-    auto [left, leftType] = binop.left->accept(*this, builder);
-    auto [right, rightType] = binop.right->accept(*this, builder);
+    auto left = binop.left->accept(*this, builder);
+    auto right = binop.right->accept(*this, builder);
     
+    auto& leftType = binop.left->type;
+    auto& rightType = binop.right->type;
     
     if (!leftType->isNativeType() || !rightType->isNativeType())
         throw "invalid types in BinaryOperation";
@@ -41,9 +43,9 @@ std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::BinaryO
     
     Value* implicitelyCastedRight = right;
     if (!leftType->equals(*rightType))
-        implicitelyCastedRight = dynamic_cast<sem::NativeType*>(leftType)->generateImplicitCast(right);
+        implicitelyCastedRight = dynamic_cast<sem::NativeType*>(leftType.get())->generateImplicitCast(right);
     
-    if (dynamic_cast<sem::NativeType*>(leftType)->isIntegerType()) {
+    if (dynamic_cast<sem::NativeType*>(leftType.get())->isIntegerType()) {
         // TODO allow integer operations
     }
     
@@ -51,55 +53,56 @@ std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::BinaryO
     // TODO insert type checks
     switch (binop.op) {
         case ast::Operation::Operator::PLUS:
-            return { builder.CreateAdd(left, right, "add"), leftType };
+            return builder.CreateAdd(left, right, "add");
         case ast::Operation::Operator::MINUS:
-            return { builder.CreateSub(left, right, "sub"), leftType };
+            return builder.CreateSub(left, right, "sub");
         case ast::Operation::Operator::ASTERISK:
-            return { builder.CreateMul(left, right, "mul"), leftType };
+            return builder.CreateMul(left, right, "mul");
         case ast::Operation::Operator::SLASH:
-            return { builder.CreateSDiv(left, right, "sdiv"), leftType };
+            return builder.CreateSDiv(left, right, "sdiv");
             
         case ast::Operation::Operator::AND:
-            return { builder.CreateAnd(left, right, "and"), Type::BOOLEAN };
+            return builder.CreateAnd(left, right, "and");
         case ast::Operation::Operator::OR:
-            return { builder.CreateOr(left, right, "or"), Type::BOOLEAN };
+            return builder.CreateOr(left, right, "or");
         case ast::Operation::Operator::XOR:
-            return { builder.CreateXor(left, right, "xor"), Type::BOOLEAN };
+            return builder.CreateXor(left, right, "xor");
             
         case ast::Operation::Operator::EQUALS:
-            return { builder.CreateICmpEQ(left, right, "equals"), Type::BOOLEAN };
+            return builder.CreateICmpEQ(left, right, "equals");
         case ast::Operation::Operator::NOT_EQUALS:
-            return { builder.CreateICmpNE(left, right, "not_equals"), Type::BOOLEAN };
+            return builder.CreateICmpNE(left, right, "not_equals");
     }
 }
 
 
-std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::UnaryOperation& unop, llvm::IRBuilder<>& builder)
+llvm::Value* ExpressionCodegenVisitor::visit(sem::UnaryOperation& unop, llvm::IRBuilder<>& builder)
 {
     using llvm::Value;
-    auto [value, type] = unop.arg->accept(*this, builder);
+    auto value = unop.arg->accept(*this, builder);
+    auto& type = unop.arg->type;
     
-    if (type != sem::Type::INTEGER)
+    if (type->equals(sem::NativeType(sem::NativeType::Type::VOID)))
         throw "invalid type to negate";
 
     switch (unop.op) {
         case ast::Operation::Operator::MINUS:
-            return { builder.CreateNeg(value, "negate"), sem::Type::INTEGER };
+            return builder.CreateNeg(value, "negate");
         case ast::Operation::Operator::NOT:
-            return { builder.CreateNot(value, "not"), sem::Type::BOOLEAN };
+            return builder.CreateNot(value, "not");
         default:
             throw "operator not supported";
     }
 }
 
 
-std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::NewArrayExpression& naexpr, llvm::IRBuilder<>& builder)
+llvm::Value* ExpressionCodegenVisitor::visit(sem::NewArrayExpression& naexpr, llvm::IRBuilder<>& builder)
 {
     using llvm::Value;
     // TODO implement
 }
 
-std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::FeatureCallExpression& call, llvm::IRBuilder<>& builder)
+llvm::Value* ExpressionCodegenVisitor::visit(sem::FeatureCallExpression& call, llvm::IRBuilder<>& builder)
 {
     using llvm::Value;
     std::vector<Value*> arguments;
@@ -109,9 +112,9 @@ std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::Feature
     for (size_t i = 0; i < call.arguments.size(); i++) {
         // : call.arguments) {
         auto& arg = call.arguments[i];
-        auto [value, type] = arg->accept(*this, builder);
+        auto value = arg->accept(*this, builder);
         
-        if (!type->equals(*call.callee->arguments[i]->type.get())) {
+        if (!arg->type->equals(*call.callee->arguments[i]->type.get())) {
             throw "argument type mismatch";
         }
         
@@ -120,16 +123,13 @@ std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::Feature
     auto returnType = call.callee->returnType;
     llvm::CallInst* callInst = builder.CreateCall(call.callee->llvmNode, arguments);
     
-    return { callInst, returnType.get() };
-    //return { nullptr, sem::Type::NULL_TYPE };
+    return callInst;
 }
 
-std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::IntConst& node, llvm::IRBuilder<>& builder)
+llvm::Value* ExpressionCodegenVisitor::visit(sem::IntConst& node, llvm::IRBuilder<>& builder)
 {
-    return {
-        llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, std::to_string(node.value), 10)),
-        sem::Type::INTEGER
-    };
+    return llvm::ConstantInt::get(builder.getContext(),
+        llvm::APInt(32, std::to_string(node.value), 10));
 }
 
 
@@ -151,7 +151,7 @@ llvm::Value* StatementVisitor::visit(sem::IfElseBlock& ifElseBlock,
     
     llvm::IRBuilder<> builder(fg.getContext());
     builder.SetInsertPoint(fg.getCurrentBlock());
-    auto [condition, condType] = ifElseBlock.condition->accept(fg.expressionVisitor, builder);
+    auto condition = ifElseBlock.condition->accept(fg.expressionVisitor, builder);
     
     llvm::Function* function = fg.getCurrentBlock()->getParent();
     
@@ -200,7 +200,7 @@ llvm::Value* StatementVisitor::visit(sem::WhileBlock& whileBlock,
     builder.CreateBr(startloop);
     fg.pushBlock(startloop);
     builder.SetInsertPoint(startloop);
-    auto [condition, condType] = whileBlock.condition->accept(fg.expressionVisitor, builder);
+    auto condition = whileBlock.condition->accept(fg.expressionVisitor, builder);
     Value* boolCond = builder.CreateIntCast(condition, llvm::Type::getInt1Ty(fg.getContext()), false);
     builder.CreateCondBr(condition, body, merge);
     fg.popBlock();
@@ -220,7 +220,7 @@ llvm::Value* StatementVisitor::visit(sem::AssignmentStatement& assignment,
     Logger& logger = Logger::getInstance();
     llvm::IRBuilder<> builder(fg.getContext());
     builder.SetInsertPoint(fg.getCurrentBlock());
-    auto [val, type] = assignment.value->accept(fg.expressionVisitor, builder);
+    auto val = assignment.value->accept(fg.expressionVisitor, builder);
     if (auto* targetVar =
         dynamic_cast<sem::LocalVariableExpression*>(assignment.target.get()); targetVar) {
         logger.debug() << "assigning to LocalVariableExpression" << std::endl;
@@ -247,7 +247,7 @@ llvm::Value* StatementVisitor::visit(sem::ReturnStatement& returnStatement,
 {
     llvm::IRBuilder<> builder(fg.getContext());
     builder.SetInsertPoint(fg.getCurrentBlock());
-    auto [val, type] = returnStatement.value->accept(fg.expressionVisitor, builder);
+    auto val = returnStatement.value->accept(fg.expressionVisitor, builder);
     builder.CreateRet(val);
     return val;
 }

+ 7 - 7
src/CodegenVisitor.h

@@ -32,7 +32,7 @@ namespace qlow
 
 class qlow::ExpressionCodegenVisitor :
     public Visitor<
-        std::pair<llvm::Value*, sem::Type*>,
+        llvm::Value*,
         llvm::IRBuilder<>,
 
         sem::LocalVariableExpression,
@@ -44,12 +44,12 @@ class qlow::ExpressionCodegenVisitor :
     >
 {
 public:
-    std::pair<llvm::Value*, sem::Type*> visit(sem::LocalVariableExpression& node, llvm::IRBuilder<>&) override;
-    std::pair<llvm::Value*, sem::Type*> visit(sem::BinaryOperation& node, llvm::IRBuilder<>&) override;
-    std::pair<llvm::Value*, sem::Type*> visit(sem::UnaryOperation& node, llvm::IRBuilder<>&) override;
-    std::pair<llvm::Value*, sem::Type*> visit(sem::NewArrayExpression& node, llvm::IRBuilder<>&) override;
-    std::pair<llvm::Value*, sem::Type*> visit(sem::FeatureCallExpression& node, llvm::IRBuilder<>&) override;
-    std::pair<llvm::Value*, sem::Type*> visit(sem::IntConst& node, llvm::IRBuilder<>&) override;
+    llvm::Value* visit(sem::LocalVariableExpression& node, llvm::IRBuilder<>&) override;
+    llvm::Value* visit(sem::BinaryOperation& node, llvm::IRBuilder<>&) override;
+    llvm::Value* visit(sem::UnaryOperation& node, llvm::IRBuilder<>&) override;
+    llvm::Value* visit(sem::NewArrayExpression& node, llvm::IRBuilder<>&) override;
+    llvm::Value* visit(sem::FeatureCallExpression& node, llvm::IRBuilder<>&) override;
+    llvm::Value* visit(sem::IntConst& node, llvm::IRBuilder<>&) override;
 };
 
 

+ 1 - 0
src/Driver.cpp

@@ -71,6 +71,7 @@ int Driver::run(void)
 {
     Logger& logger = Logger::getInstance();
     
+    logger.debug() << "starting parser" << std::endl;
     //logger.logError("driver not yet implemented", {options.emitAssembly ? "asm" : "noasm", 10, 11, 12, 13});
     
     std::vector<std::unique_ptr<qlow::ast::AstObject>> objects;

+ 1 - 1
src/Operation.h

@@ -14,6 +14,6 @@ namespace qlow
 class qlow::sem::InlineOperation
 {
     
-}
+};
 
 #endif // QLOW_SEM_OPERATION_H

+ 1 - 1
src/Scope.cpp

@@ -29,7 +29,7 @@ sem::Method* sem::GlobalScope::getMethod(const std::string& name)
 std::shared_ptr<sem::Type> sem::GlobalScope::getType(const ast::Type& name)
 {
     if (const auto* arr = dynamic_cast<const ast::ArrayType*>(&name); arr) {
-        return std::make_unique<sem::ArrayType>(getType(*arr->arrayType));
+        return std::make_shared<sem::ArrayType>(getType(*arr->arrayType));
     }
     
     auto native = NativeScope::getInstance().getType(name);

+ 6 - 6
src/Semantic.cpp

@@ -169,12 +169,12 @@ ReturnType ClassName::accept(Visitor& v, Arg arg) \
     return v.visit(*this, arg); \
 }
 
-ACCEPT_DEFINITION(LocalVariableExpression, ExpressionCodegenVisitor, std::pair<llvm::Value* COMMA Type*>, llvm::IRBuilder<>&)
-ACCEPT_DEFINITION(BinaryOperation, ExpressionCodegenVisitor, std::pair<llvm::Value* COMMA Type*>, llvm::IRBuilder<>&)
-ACCEPT_DEFINITION(NewArrayExpression, ExpressionCodegenVisitor, std::pair<llvm::Value* COMMA Type*>, llvm::IRBuilder<>&)
-ACCEPT_DEFINITION(UnaryOperation, ExpressionCodegenVisitor, std::pair<llvm::Value* COMMA Type*>, llvm::IRBuilder<>&)
-ACCEPT_DEFINITION(FeatureCallExpression, ExpressionCodegenVisitor, std::pair<llvm::Value* COMMA Type*>, llvm::IRBuilder<>&)
-ACCEPT_DEFINITION(IntConst, ExpressionCodegenVisitor, std::pair<llvm::Value* COMMA Type*>, llvm::IRBuilder<>&)
+ACCEPT_DEFINITION(LocalVariableExpression, ExpressionCodegenVisitor, llvm::Value*, llvm::IRBuilder<>&)
+ACCEPT_DEFINITION(BinaryOperation, ExpressionCodegenVisitor, llvm::Value*, llvm::IRBuilder<>&)
+ACCEPT_DEFINITION(NewArrayExpression, ExpressionCodegenVisitor, llvm::Value*, llvm::IRBuilder<>&)
+ACCEPT_DEFINITION(UnaryOperation, ExpressionCodegenVisitor, llvm::Value*, llvm::IRBuilder<>&)
+ACCEPT_DEFINITION(FeatureCallExpression, ExpressionCodegenVisitor, llvm::Value*, llvm::IRBuilder<>&)
+ACCEPT_DEFINITION(IntConst, ExpressionCodegenVisitor, llvm::Value*, llvm::IRBuilder<>&)
 
 ACCEPT_DEFINITION(AssignmentStatement, StatementVisitor, llvm::Value*, qlow::gen::FunctionGenerator&) 
 ACCEPT_DEFINITION(DoEndBlock, StatementVisitor, llvm::Value*, qlow::gen::FunctionGenerator&) 

+ 11 - 10
src/Semantic.h

@@ -221,7 +221,7 @@ struct qlow::sem::ReturnStatement : public Statement
 
 struct qlow::sem::Expression :
     public SemanticObject,
-    public Visitable<std::pair<llvm::Value*, sem::Type*>,
+    public Visitable<llvm::Value*,
                      llvm::IRBuilder<>,
                      qlow::ExpressionCodegenVisitor>
 {
@@ -255,7 +255,7 @@ struct qlow::sem::LocalVariableExpression : public Expression
     {
     }
 
-    virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
+    virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
     virtual std::string toString(void) const override;
 };
 
@@ -270,7 +270,7 @@ struct qlow::sem::BinaryOperation : public Operation
     {
     }
     
-    virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
+    virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
     
     virtual std::string toString(void) const override;
 };
@@ -278,15 +278,16 @@ struct qlow::sem::BinaryOperation : public Operation
 
 struct qlow::sem::NewArrayExpression : public Expression
 {
-    std::unique_ptr<Type> arrayType;
+    std::shared_ptr<Type> arrayType;
     std::unique_ptr<Expression> length;
     
-    inline NewArrayExpression(std::shared_ptr<Type> type) :
-        Expression{ std::move(type) }
+    inline NewArrayExpression(std::shared_ptr<Type> arrayType) :
+        Expression{ std::make_shared<ArrayType>(arrayType) },
+        arrayType{ std::move(arrayType) }
     {
     }
     
-    virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
+    virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
     virtual std::string toString(void) const override;
 };
 
@@ -301,7 +302,7 @@ struct qlow::sem::UnaryOperation : public Operation
     {
     }
     
-    virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
+    virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
     virtual std::string toString(void) const override;
 };
 
@@ -316,7 +317,7 @@ struct qlow::sem::FeatureCallExpression : public Expression
     {
     }
     
-    virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
+    virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
     
     virtual std::string toString(void) const override;
 };
@@ -332,7 +333,7 @@ struct qlow::sem::IntConst : public Expression
     {
     }
     
-    virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
+    virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
 };
 
 

+ 7 - 4
src/Type.cpp

@@ -21,10 +21,13 @@ bool sem::Type::equals(const Type& other) const
 }
 
 
-sem::Type* sem::Type::VOID = new sem::NativeType(sem::NativeType::Type::VOID);
-sem::Type* sem::Type::INTEGER = new sem::NativeType(sem::NativeType::Type::INTEGER);
-sem::Type* sem::Type::BOOLEAN = new sem::NativeType(sem::NativeType::Type::BOOLEAN);
-
+/*std::shared_ptr<sem::Type> sem::Type::VOID =
+    std::make_shared<sem::NativeType>(sem::NativeType::Type::VOID);
+std::shared_ptr<sem::Type> sem::Type::INTEGER =
+    std::make_shared<sem::NativeType>(sem::NativeType::Type::INTEGER);
+std::shared_ptr<sem::Type> sem::Type::BOOLEAN =
+    std::make_shared<sem::NativeType>(sem::NativeType::Type::BOOLEAN);
+*/
 
 sem::Scope& sem::ClassType::getScope(void)
 {

+ 3 - 3
src/Type.h

@@ -62,9 +62,9 @@ public:
     
     virtual bool equals(const Type& other) const;
     
-    static Type* VOID;
-    static Type* INTEGER;
-    static Type* BOOLEAN;
+//    static std::shared_ptr<Type> VOID;
+//    static std::shared_ptr<Type> INTEGER;
+//    static std::shared_ptr<Type> BOOLEAN;
 };