| 
					
				 | 
			
			
				@@ -1,25 +1,31 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "CodegenVisitor.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "CodeGeneration.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "Type.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <llvm/IR/Constants.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <llvm/IR/IRBuilder.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using namespace qlow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-llvm::Value* ExpressionVisitor::visit(sem::LocalVariableExpression& lve, llvm::IRBuilder<>& builder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+std::pair<llvm::Value*, sem::Type> ExpressionVisitor::visit(sem::LocalVariableExpression& lve, llvm::IRBuilder<>& builder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     llvm::Value* val = builder.CreateLoad(lve.var->allocaInst); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { val, lve.var->type }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-llvm::Value* ExpressionVisitor::visit(sem::BinaryOperation& binop, llvm::IRBuilder<>& builder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+std::pair<llvm::Value*, sem::Type> ExpressionVisitor::visit(sem::BinaryOperation& binop, llvm::IRBuilder<>& builder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     using llvm::Value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Value* left = binop.left->accept(*this, builder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Value* right = binop.right->accept(*this, builder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using sem::Type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto [left, leftType] = binop.left->accept(*this, builder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto [right, rightType] = binop.right->accept(*this, builder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (leftType != Type::INTEGER || rightType != Type::INTEGER) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw "invalid types in BinaryOperation"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (left == nullptr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         printf("WOW: %s\n", binop.left->toString().c_str()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -27,25 +33,28 @@ llvm::Value* ExpressionVisitor::visit(sem::BinaryOperation& binop, llvm::IRBuild 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     switch (binop.op) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         case ast::Operation::Operator::PLUS: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return builder.CreateAdd(left, right, "add"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { builder.CreateAdd(left, right, "add"), Type::INTEGER }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         case ast::Operation::Operator::MINUS: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return builder.CreateSub(left, right, "sub"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { builder.CreateSub(left, right, "sub"), Type::INTEGER }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         case ast::Operation::Operator::ASTERISK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return builder.CreateMul(left, right, "mul"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { builder.CreateMul(left, right, "mul"), Type::INTEGER }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         case ast::Operation::Operator::SLASH: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return builder.CreateSDiv(left, right, "add"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { builder.CreateSDiv(left, right, "add"), Type::INTEGER }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-llvm::Value* ExpressionVisitor::visit(sem::UnaryOperation& unop, llvm::IRBuilder<>& builder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+std::pair<llvm::Value*, sem::Type> ExpressionVisitor::visit(sem::UnaryOperation& unop, llvm::IRBuilder<>& builder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     using llvm::Value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Value* value = unop.arg->accept(*this, builder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto [value, type] = unop.arg->accept(*this, builder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (type != sem::Type::INTEGER) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw "invalid type to negate"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     switch (unop.op) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         case ast::Operation::Operator::MINUS: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return builder.CreateNeg(value, "negate"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { builder.CreateNeg(value, "negate"), sem::Type::INTEGER }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         case ast::Operation::Operator::PLUS: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         [[fallthrough]]; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -56,20 +65,25 @@ llvm::Value* ExpressionVisitor::visit(sem::UnaryOperation& unop, llvm::IRBuilder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-llvm::Value* ExpressionVisitor::visit(sem::FeatureCallExpression& call, llvm::IRBuilder<>& builder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+std::pair<llvm::Value*, sem::Type> ExpressionVisitor::visit(sem::FeatureCallExpression& call, llvm::IRBuilder<>& builder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     using llvm::Value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     std::vector<Value*> arguments; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for (auto& arg : call.arguments) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        arguments.push_back(arg->accept(*this, builder)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        auto [value, type] = arg->accept(*this, builder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO implement type check 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        arguments.push_back(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     //return builder.CreateCall(nullptr, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return nullptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { nullptr, sem::Type::NULL_TYPE }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-llvm::Value* ExpressionVisitor::visit(sem::IntConst& node, llvm::IRBuilder<>& builder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+std::pair<llvm::Value*, sem::Type> ExpressionVisitor::visit(sem::IntConst& node, llvm::IRBuilder<>& builder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, std::to_string(node.value), 10)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, std::to_string(node.value), 10)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sem::Type::INTEGER 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -78,7 +92,7 @@ llvm::Value* StatementVisitor::visit(sem::AssignmentStatement& assignment, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     llvm::IRBuilder<> builder(fg.getContext()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     builder.SetInsertPoint(fg.getCurrentBlock()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    llvm::Value* val = assignment.value->accept(fg.expressionVisitor, builder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto [val, type] = assignment.value->accept(fg.expressionVisitor, builder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     //builder.CreateRet(val); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return llvm::ConstantFP::get(fg.getContext(), llvm::APFloat(5.0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |