Nicolas Winkler 6 năm trước cách đây
mục cha
commit
5999516e07
14 tập tin đã thay đổi với 138 bổ sung151 xóa
  1. 19 16
      src/AstVisitor.cpp
  2. 2 1
      src/Builtin.cpp
  3. 1 1
      src/CodeGeneration.cpp
  4. 12 5
      src/CodegenVisitor.cpp
  5. 2 0
      src/CodegenVisitor.h
  6. 12 12
      src/Scope.cpp
  7. 13 13
      src/Scope.h
  8. 1 0
      src/Semantic.cpp
  9. 42 9
      src/Semantic.h
  10. 25 9
      src/Type.cpp
  11. 8 8
      src/Type.h
  12. 0 39
      src/TypeVisitor.cpp
  13. 0 37
      src/TypeVisitor.h
  14. 1 1
      src/test.qlw

+ 19 - 16
src/AstVisitor.cpp

@@ -29,7 +29,7 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FieldDeclarati
 {
     auto f = std::make_unique<sem::Field>();
     f->name = ast.name;
-    auto* type = scope.getType(*ast.type);
+    auto type = scope.getType(*ast.type);
     if (type) {
         f->type = type;
     }
@@ -79,9 +79,9 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::VariableDeclar
 {
     auto v = std::make_unique<sem::Variable>();
     v->name = ast.name;
-    auto* type = scope.getType(*ast.type);
+    auto type = scope.getType(*ast.type);
     if (type) {
-        v->type = type;
+        v->type = std::move(type);
     }
     else {
         throw SemanticError(SemanticError::UNKNOWN_TYPE,
@@ -107,13 +107,13 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::DoEndBlock& as
     for (auto& statement : ast.statements) {
         
         if (ast::LocalVariableStatement* nvs = dynamic_cast<ast::LocalVariableStatement*>(statement.get()); nvs) {
-            auto* type = body->scope.getType(*nvs->type);
+            auto type = body->scope.getType(*nvs->type);
 
             if (!type)
                 throw SemanticError(SemanticError::UNKNOWN_TYPE,
                                     nvs->type->asString(),
                                     nvs->type->pos);
-            auto var = std::make_unique<sem::Variable>(type, nvs->name);
+            auto var = std::make_unique<sem::Variable>(std::move(type), nvs->name);
             body->scope.putVariable(nvs->name, std::move(var));
             continue;
         }
@@ -188,12 +188,10 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FeatureCall& a
     auto* var = scope.getVariable(ast.name);
     
     if (var) {
-        auto lve = std::make_unique<sem::LocalVariableExpression>();
-        lve->var = var;
-        return lve;
+        return std::make_unique<sem::LocalVariableExpression>(var);
     }
     else if (method) {
-        auto fce = std::make_unique<sem::FeatureCallExpression>();
+        auto fce = std::make_unique<sem::FeatureCallExpression>(method->returnType);
         for (auto& arg : ast.arguments) {
             auto argument = arg->accept(*this, scope);
             if (dynamic_cast<sem::Expression*>(argument.get())) {
@@ -250,28 +248,33 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::IntConst& ast,
 
 std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::UnaryOperation& ast, sem::Scope& scope)
 {
-    auto ret = std::make_unique<sem::UnaryOperation>();
+    auto argument = unique_dynamic_cast<sem::Expression>(ast.expr->accept(*this, scope));
+    auto ret = std::make_unique<sem::UnaryOperation>(argument->type);
+            // TODO not a feasible assumption
     ret->op = ast.op;
     ret->side = ast.side;
-    ret->arg = unique_dynamic_cast<sem::Expression>(ast.expr->accept(*this, scope));
-    ret->type = ret->arg->type; // TODO not a feasible assumption
+    ret->arg = std::move(argument);
     return ret;
 }
 
 
 std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::BinaryOperation& ast, sem::Scope& scope)
 {
-    auto ret = std::make_unique<sem::BinaryOperation>();
+    auto leftEval = unique_dynamic_cast<sem::Expression>(ast.left->accept(*this, scope));
+    auto rightEval = unique_dynamic_cast<sem::Expression>(ast.right->accept(*this, scope));
+    
+    auto ret = std::make_unique<sem::BinaryOperation>(leftEval->type);
+    
     ret->op = ast.op;
-    ret->left = unique_dynamic_cast<sem::Expression>(ast.left->accept(*this, scope));
-    ret->right = unique_dynamic_cast<sem::Expression>(ast.right->accept(*this, scope));
+    ret->left = std::move(leftEval);
+    ret->right = std::move(rightEval);
     return ret;
 }
 
 
 std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::NewArrayExpression& ast, sem::Scope& scope)
 {
-    auto ret = std::make_unique<sem::BinaryOperation>();
+    auto ret = std::make_unique<sem::NewArrayExpression>(scope.getType(*ast.type));
     return ret;
 }
 

+ 2 - 1
src/Builtin.cpp

@@ -36,7 +36,8 @@ sem::NativeScope qlow::sem::generateNativeScope(void)
     };
     
     for (auto [name, type] : natives) {
-        scope.types.insert({ name, std::make_unique<NativeType>(type) });
+        scope.types.insert({ name, std::make_unique
+            <std::shared_ptr<NativeType>>(std::make_shared<NativeType>(type)) });
     }
     
     return scope;

+ 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::Type::VOID)) {
         if (!getCurrentBlock()->getTerminator())
             builder.CreateRetVoid();
     }

+ 12 - 5
src/CodegenVisitor.cpp

@@ -14,10 +14,10 @@ std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::LocalVa
     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 };
+        return { val, lve.var->type.get() };
     }
     else {
-        return { lve.var->allocaInst, lve.var->type };
+        return { lve.var->allocaInst, lve.var->type.get() };
     }
 }
 
@@ -40,7 +40,7 @@ std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::BinaryO
     
     
     Value* implicitelyCastedRight = right;
-    if (!leftType->equals(rightType))
+    if (!leftType->equals(*rightType))
         implicitelyCastedRight = dynamic_cast<sem::NativeType*>(leftType)->generateImplicitCast(right);
     
     if (dynamic_cast<sem::NativeType*>(leftType)->isIntegerType()) {
@@ -92,6 +92,13 @@ std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::UnaryOp
     }
 }
 
+
+std::pair<llvm::Value*, sem::Type*> 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)
 {
     using llvm::Value;
@@ -104,7 +111,7 @@ std::pair<llvm::Value*, sem::Type*> ExpressionCodegenVisitor::visit(sem::Feature
         auto& arg = call.arguments[i];
         auto [value, type] = arg->accept(*this, builder);
         
-        if (!type->equals(call.callee->arguments[i]->type)) {
+        if (!type->equals(*call.callee->arguments[i]->type.get())) {
             throw "argument type mismatch";
         }
         
@@ -113,7 +120,7 @@ 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 };
+    return { callInst, returnType.get() };
     //return { nullptr, sem::Type::NULL_TYPE };
 }
 

+ 2 - 0
src/CodegenVisitor.h

@@ -38,6 +38,7 @@ class qlow::ExpressionCodegenVisitor :
         sem::LocalVariableExpression,
         sem::BinaryOperation,
         sem::UnaryOperation,
+        sem::NewArrayExpression,
         sem::FeatureCallExpression,
         sem::IntConst
     >
@@ -46,6 +47,7 @@ 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;
 };

+ 12 - 12
src/Scope.cpp

@@ -26,10 +26,10 @@ sem::Method* sem::GlobalScope::getMethod(const std::string& name)
 }
 
 
-sem::Type* sem::GlobalScope::getType(const ast::Type& 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 new sem::ArrayType(getType(*arr->arrayType));
+        return std::make_unique<sem::ArrayType>(getType(*arr->arrayType));
     }
     
     auto native = NativeScope::getInstance().getType(name);
@@ -46,13 +46,13 @@ sem::Type* sem::GlobalScope::getType(const ast::Type& name)
     
     auto t = classes.find(classType->typeName);
     if (t != classes.end())
-        return new sem::ClassType(t->second.get());
+        return std::make_shared<sem::ClassType>(t->second.get());
     
     return nullptr;
 }
 
 
-sem::Type* sem::GlobalScope::getReturnableType(void)
+std::shared_ptr<sem::Type> sem::GlobalScope::getReturnableType(void)
 {
     return nullptr;
 }
@@ -70,21 +70,21 @@ std::string sem::GlobalScope::toString(void)
 }
 
 
-sem::Type* sem::NativeScope::getType(const ast::Type& name)
+std::shared_ptr<sem::Type> sem::NativeScope::getType(const ast::Type& name)
 {
     if (const auto* arr = dynamic_cast<const ast::ArrayType*>(&name); arr) {
-        return new sem::ArrayType(getType(*arr->arrayType));
+        return std::make_shared<sem::ArrayType>(getType(*arr->arrayType));
     }
     
     const auto* classType = dynamic_cast<const ast::ClassType*>(&name);
    
     if (!classType)
-        return sem::Type::VOID;
+        return std::make_shared<sem::NativeType>(NativeType::VOID);
     
     
     auto t = types.find(classType->typeName);
     if (t != types.end())
-        return t->second.get();
+        return *t->second;
     
     return nullptr;
 }
@@ -143,13 +143,13 @@ std::string sem::ClassScope::toString(void)
 }
 
 
-sem::Type* sem::ClassScope::getType(const ast::Type& name)
+std::shared_ptr<sem::Type> sem::ClassScope::getType(const ast::Type& name)
 {
     return parentScope.getType(name);
 }
 
 
-sem::Type* sem::ClassScope::getReturnableType(void)
+std::shared_ptr<sem::Type> sem::ClassScope::getReturnableType(void)
 {
     return nullptr;
 }
@@ -183,13 +183,13 @@ sem::Method* sem::LocalScope::getMethod(const std::string& name)
 }
 
 
-sem::Type* sem::LocalScope::getType(const ast::Type& name)
+std::shared_ptr<sem::Type> sem::LocalScope::getType(const ast::Type& name)
 {
     return parentScope.getType(name);
 }
 
 
-sem::Type* sem::LocalScope::getReturnableType(void)
+std::shared_ptr<sem::Type> sem::LocalScope::getReturnableType(void)
 {
     return returnType;
 }

+ 13 - 13
src/Scope.h

@@ -43,8 +43,8 @@ public:
     virtual ~Scope(void);
     virtual Variable* getVariable(const std::string& name) = 0;
     virtual Method* getMethod(const std::string& name) = 0;
-    virtual Type* getType(const ast::Type& name) = 0;
-    virtual Type* getReturnableType(void) = 0;
+    virtual std::shared_ptr<Type> getType(const ast::Type& name) = 0;
+    virtual std::shared_ptr<Type> getReturnableType(void) = 0;
 
     virtual std::string toString(void) = 0;
 };
@@ -58,8 +58,8 @@ public:
 public:
     virtual Variable* getVariable(const std::string& name);
     virtual Method* getMethod(const std::string& name);
-    virtual Type* getType(const ast::Type& name);
-    virtual Type* getReturnableType(void);
+    virtual std::shared_ptr<Type> getType(const ast::Type& name);
+    virtual std::shared_ptr<Type> getReturnableType(void);
 
     virtual std::string toString(void);
 };
@@ -69,9 +69,9 @@ class qlow::sem::NativeScope : public GlobalScope
 {
     static NativeScope instance;
 public:
-    SymbolTable<NativeType> types;
+    SymbolTable<std::shared_ptr<NativeType>> types;
 public:
-    virtual Type* getType(const ast::Type& name);
+    virtual std::shared_ptr<Type> getType(const ast::Type& name);
 
     virtual std::string toString(void);
     
@@ -91,8 +91,8 @@ public:
     }
     virtual Variable* getVariable(const std::string& name);
     virtual Method* getMethod(const std::string& name);
-    virtual Type* getType(const ast::Type& name);
-    virtual Type* getReturnableType(void);
+    virtual std::shared_ptr<Type> getType(const ast::Type& name);
+    virtual std::shared_ptr<Type> getReturnableType(void);
     virtual std::string toString(void);
 };
 
@@ -101,7 +101,7 @@ class qlow::sem::LocalScope : public Scope
 {
     Scope& parentScope;
     SymbolTable<Variable> localVariables;
-    Type* returnType;
+    std::shared_ptr<Type> returnType;
 public:
     inline LocalScope(Scope& parentScope, Type* returnType) :
         parentScope{ parentScope },
@@ -112,9 +112,9 @@ public:
     inline LocalScope(Scope& parentScope) :
         parentScope{ parentScope }
     {
-        Type* returnable = parentScope.getReturnableType();
+        auto returnable = parentScope.getReturnableType();
         if (returnable) {
-            returnType = returnable;
+            returnType = std::move(returnable);
         }
         else {
             returnType = nullptr;
@@ -126,8 +126,8 @@ public:
 
     virtual Variable* getVariable(const std::string& name);
     virtual Method* getMethod(const std::string& name);
-    virtual Type* getType(const ast::Type& name);
-    virtual Type* getReturnableType(void);
+    virtual std::shared_ptr<Type> getType(const ast::Type& name);
+    virtual std::shared_ptr<Type> getReturnableType(void);
     virtual std::string toString(void);
 };
 

+ 1 - 0
src/Semantic.cpp

@@ -171,6 +171,7 @@ ReturnType ClassName::accept(Visitor& v, Arg 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<>&)

+ 42 - 9
src/Semantic.h

@@ -96,7 +96,7 @@ struct qlow::sem::Class : public SemanticObject
 
 struct qlow::sem::Variable : public SemanticObject
 {
-    Type* type;
+    std::shared_ptr<Type> type;
     std::string name;
 
     /// if this is a local variable, this stores a reference to the llvm
@@ -104,8 +104,8 @@ struct qlow::sem::Variable : public SemanticObject
     llvm::Value* allocaInst;
     
     Variable(void) = default;
-    inline Variable(Type* type, std::string& name) :
-        type{ type }, name{ name }, allocaInst { nullptr } {}
+    inline Variable(std::shared_ptr<Type> type, std::string& name) :
+        type{ std::move(type) }, name{ name }, allocaInst { nullptr } {}
         
     virtual std::string toString(void) const override;
 };
@@ -120,7 +120,7 @@ struct qlow::sem::Field : public Variable
 struct qlow::sem::Method : public SemanticObject
 {
     Class* containingType;
-    Type* returnType;
+    std::shared_ptr<Type> returnType;
     std::vector<Variable*> arguments;
     std::string name;
     ast::MethodDefinition* astNode;
@@ -130,8 +130,8 @@ struct qlow::sem::Method : public SemanticObject
 
     llvm::Function* llvmNode;
 
-    inline Method(Scope& parentScope, Type* returnType) :
-        returnType{ returnType },
+    inline Method(Scope& parentScope, std::shared_ptr<Type> returnType) :
+        returnType{ std::move(returnType) },
         scope{ parentScope },
         body{ nullptr }
     {
@@ -225,9 +225,9 @@ struct qlow::sem::Expression :
                      llvm::IRBuilder<>,
                      qlow::ExpressionCodegenVisitor>
 {
-    std::unique_ptr<sem::Type> type;
+    std::shared_ptr<sem::Type> type;
     
-    inline Expression(std::unique_ptr<Type> type) :
+    inline Expression(std::shared_ptr<Type> type) :
         type{ std::move(type) }
     {
     }
@@ -237,12 +237,23 @@ struct qlow::sem::Expression :
 struct qlow::sem::Operation : public Expression
 {
     ast::Operation::Operator op;
+    
+    inline Operation(std::shared_ptr<Type> type) :
+        Expression{ std::move(type) }
+    {
+    }
 };
 
 
 struct qlow::sem::LocalVariableExpression : public Expression
 {
     Variable* var;
+    
+    inline LocalVariableExpression(Variable* var) :
+        Expression{ var->type },
+        var{ var }
+    {
+    }
 
     virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
     virtual std::string toString(void) const override;
@@ -254,6 +265,11 @@ struct qlow::sem::BinaryOperation : public Operation
     std::unique_ptr<Expression> left;
     std::unique_ptr<Expression> right;
     
+    inline BinaryOperation(std::shared_ptr<Type> type) :
+        Operation{ std::move(type) }
+    {
+    }
+    
     virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
     
     virtual std::string toString(void) const override;
@@ -265,6 +281,11 @@ struct qlow::sem::NewArrayExpression : public Expression
     std::unique_ptr<Type> arrayType;
     std::unique_ptr<Expression> length;
     
+    inline NewArrayExpression(std::shared_ptr<Type> type) :
+        Expression{ std::move(type) }
+    {
+    }
+    
     virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
     virtual std::string toString(void) const override;
 };
@@ -274,6 +295,12 @@ struct qlow::sem::UnaryOperation : public Operation
 {
     qlow::ast::UnaryOperation::Side side;
     std::unique_ptr<Expression> arg;
+    
+    inline UnaryOperation(std::shared_ptr<Type> type) :
+        Operation{ std::move(type) }
+    {
+    }
+    
     virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
     virtual std::string toString(void) const override;
 };
@@ -283,6 +310,12 @@ struct qlow::sem::FeatureCallExpression : public Expression
 {
     Method* callee;
     OwningList<Expression> arguments;
+    
+    inline FeatureCallExpression(std::shared_ptr<Type> type) :
+        Expression{ std::move(type) }
+    {
+    }
+    
     virtual std::pair<llvm::Value*, sem::Type*> accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
     
     virtual std::string toString(void) const override;
@@ -294,7 +327,7 @@ struct qlow::sem::IntConst : public Expression
     unsigned long long value;
 
     inline IntConst(unsigned long long value) :
-        Expression{ std::make_unique<NativeType>(NativeType::INTEGER) },
+        Expression{ std::make_shared<NativeType>(NativeType::INTEGER) },
         value{ value }
     {
     }

+ 25 - 9
src/Type.cpp

@@ -15,9 +15,9 @@ sem::Type::~Type(void)
 }
 
 
-bool sem::Type::equals(const Type* other) const
+bool sem::Type::equals(const Type& other) const
 {
-    return this == other;
+    return this == &other;
 }
 
 
@@ -26,15 +26,21 @@ sem::Type* sem::Type::INTEGER = new sem::NativeType(sem::NativeType::Type::INTEG
 sem::Type* sem::Type::BOOLEAN = new sem::NativeType(sem::NativeType::Type::BOOLEAN);
 
 
+sem::Scope& sem::ClassType::getScope(void)
+{
+    return classType->scope;
+}
+
+
 llvm::Type* sem::ClassType::getLlvmType (llvm::LLVMContext& context) const
 {
     return classType->llvmType;
 }
 
 
-bool sem::ClassType::equals(const Type* other) const
+bool sem::ClassType::equals(const Type& other) const
 {
-    if (auto* oct = dynamic_cast<const ClassType*>(other); oct) {
+    if (auto* oct = dynamic_cast<const ClassType*>(&other); oct) {
         return this->classType == oct->classType;
     }
     else {
@@ -43,6 +49,11 @@ bool sem::ClassType::equals(const Type* other) const
 }
 
 
+sem::Scope& sem::ArrayType::getScope(void)
+{
+}
+
+
 llvm::Type* sem::ArrayType::getLlvmType (llvm::LLVMContext& context) const
 {
     // TODO implement
@@ -50,10 +61,10 @@ llvm::Type* sem::ArrayType::getLlvmType (llvm::LLVMContext& context) const
 }
 
 
-bool sem::ArrayType::equals(const Type* other) const
+bool sem::ArrayType::equals(const Type& other) const
 {
-    if (auto* oct = dynamic_cast<const ArrayType*>(other); oct) {
-        return this->arrayType->equals(oct->arrayType);
+    if (auto* oct = dynamic_cast<const ArrayType*>(&other); oct) {
+        return this->arrayType->equals(*oct->arrayType);
     }
     else {
         return false;
@@ -61,6 +72,11 @@ bool sem::ArrayType::equals(const Type* other) const
 }
 
 
+sem::Scope& sem::NativeType::getScope(void)
+{
+}
+
+
 bool sem::NativeType::isIntegerType(void) const
 {
     switch(type) {
@@ -126,9 +142,9 @@ llvm::Type* sem::NativeType::getLlvmType (llvm::LLVMContext& context) const
 }
 
 
-bool sem::NativeType::equals(const sem::Type* other) const
+bool sem::NativeType::equals(const sem::Type& other) const
 {
-    if (auto* oct = dynamic_cast<const NativeType*>(other); oct) {
+    if (auto* oct = dynamic_cast<const NativeType*>(&other); oct) {
         return this->type == oct->type;
     }
     else {

+ 8 - 8
src/Type.h

@@ -58,7 +58,7 @@ public:
     
     virtual llvm::Type* getLlvmType(llvm::LLVMContext& context) const = 0;
     
-    virtual bool equals(const Type* other) const;
+    virtual bool equals(const Type& other) const;
     
     static Type* VOID;
     static Type* INTEGER;
@@ -83,17 +83,17 @@ public:
     
     virtual llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
     inline sem::Class* getClassType(void) { return classType; }
-    virtual bool equals(const Type* other) const;
+    virtual bool equals(const Type& other) const;
 };
 
 
 class qlow::sem::ArrayType : public Type
 {
-    sem::Type* arrayType;
+    std::shared_ptr<sem::Type> arrayType;
 public:
     
-    inline ArrayType(sem::Type* arrayType) :
-        arrayType{ arrayType }
+    inline ArrayType(std::shared_ptr<sem::Type> arrayType) :
+        arrayType{ std::move(arrayType) }
     {
     }
     
@@ -104,8 +104,8 @@ public:
     Scope& getScope(void);
     
     virtual llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
-    inline sem::Type* getArrayType(void) { return arrayType; }
-    virtual bool equals(const Type* other) const;
+    inline std::shared_ptr<sem::Type> getArrayType(void) { return arrayType; }
+    virtual bool equals(const Type& other) const;
 };
 
 
@@ -139,7 +139,7 @@ public:
     bool isIntegerType(void) const;
     
     llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
-    virtual bool equals(const sem::Type* other) const;
+    virtual bool equals(const sem::Type& other) const;
     
     /// cast an llvm::Value from another native type to this one
     llvm::Value* generateImplicitCast(llvm::Value* value);

+ 0 - 39
src/TypeVisitor.cpp

@@ -1,39 +0,0 @@
-#include "TypeVisitor.h"
-#include "Type.h"
-
-using namespace qlow;
-
-
-
-sem::Type* sem::TypeVisitor::visit(sem::Expression& expr, const sem::SymbolTable<sem::Class>& classes)
-{
-}
-
-
-sem::Type* sem::TypeVisitor::visit(sem::UnaryOperation& expr, const sem::SymbolTable<sem::Class>& classes)
-{
-    return visit(*expr.arg, classes);
-}
-
-
-sem::Type* sem::TypeVisitor::visit(sem::BinaryOperation& expr, const sem::SymbolTable<sem::Class>& classes)
-{
-    return visit(*expr.left, classes);
-}
-
-
-sem::Type* sem::TypeVisitor::visit(sem::FeatureCallExpression& expr, const sem::SymbolTable<sem::Class>& classes)
-{
-    return expr.callee->returnType;
-}
-
-
-sem::Type* sem::TypeVisitor::visit(sem::IntConst& expr, const sem::SymbolTable<sem::Class>& classes)
-{
-    return Type::INTEGER;
-}
-
-
-
-
-

+ 0 - 37
src/TypeVisitor.h

@@ -1,37 +0,0 @@
-#ifndef QLOW_SEM_TYPEVISITOR_H
-#define QLOW_SEM_TYPEVISITOR_H
-
-#include "Visitor.h"
-#include "Semantic.h"
-
-namespace qlow
-{
-    namespace sem
-    {
-        class TypeVisitor;
-    }
-}
-
-
-class qlow::sem::TypeVisitor :
-    public Visitor<
-        qlow::sem::Type*,
-        const sem::SymbolTable<sem::Class>,
-
-        sem::Expression,
-        sem::UnaryOperation,
-        sem::BinaryOperation,
-        sem::FeatureCallExpression,
-        sem::IntConst
-    >
-{
-
-public:
-    qlow::sem::Type* visit(sem::Expression& expr, const sem::SymbolTable<sem::Class>& classes) override;
-    qlow::sem::Type* visit(sem::UnaryOperation& expr, const sem::SymbolTable<sem::Class>& classes) override;
-    qlow::sem::Type* visit(sem::BinaryOperation& expr, const sem::SymbolTable<sem::Class>& classes) override;
-    qlow::sem::Type* visit(sem::FeatureCallExpression& expr, const sem::SymbolTable<sem::Class>& classes) override;
-    qlow::sem::Type* visit(sem::IntConst& expr, const sem::SymbolTable<sem::Class>& classes) override;
-};
-
-#endif // QLOW_SEM_TYPEVISITOR_H

+ 1 - 1
src/test.qlw

@@ -23,7 +23,7 @@ bignumbers do
     b: Int128
     c: Int64
 
-    b := a + c
+    //b := a + c
 end
 
 main do