فهرست منبع

reworking types

Nicolas Winkler 6 سال پیش
والد
کامیت
328931315f
6فایلهای تغییر یافته به همراه81 افزوده شده و 38 حذف شده
  1. 2 2
      src/Builtin.cpp
  2. 8 8
      src/Builtin.h
  3. 2 2
      src/Scope.h
  4. 24 23
      src/sem/Semantic.h
  5. 29 2
      src/sem/Type.cpp
  6. 16 1
      src/sem/Type.h

+ 2 - 2
src/Builtin.cpp

@@ -13,7 +13,7 @@ sem::NativeScope qlow::sem::generateNativeScope(void)
     
     NativeScope scope;
     
-    std::map<std::string, NativeType::Type> natives = {
+    /*std::map<std::string, NativeType::Type> natives = {
         { "Boolean",    NativeType::BOOLEAN },
         { "Char",       NativeType::CHAR },
         { "String",     NativeType::STRING },
@@ -109,7 +109,7 @@ sem::NativeScope qlow::sem::generateNativeScope(void)
         
         scope.types.insert({ name, std::make_unique
             <std::shared_ptr<NativeType>>(std::move(native)) });
-    }
+    }*/
     
     return scope;
 }

+ 8 - 8
src/Builtin.h

@@ -23,8 +23,8 @@ namespace qlow
 
 struct qlow::sem::NativeMethod : public sem::Method
 {
-    inline NativeMethod(std::shared_ptr<Type> returnType) :
-        Method{ NativeScope::getInstance(), std::move(returnType) }
+    inline NativeMethod(TypeId returnType) :
+        Method{ NativeScope::getInstance(), returnType }
     {
     }
     
@@ -37,10 +37,10 @@ struct qlow::sem::UnaryNativeMethod : public sem::NativeMethod
 {
     std::function<llvm::Value*(llvm::IRBuilder<>&, llvm::Value*)> generator;
     
-    inline UnaryNativeMethod(std::shared_ptr<Type> returnType,
+    inline UnaryNativeMethod(TypeId returnType,
         const std::function
         <llvm::Value*(llvm::IRBuilder<>&, llvm::Value*)>& generator) :
-        NativeMethod{ std::move(returnType) },
+        NativeMethod{ returnType },
         generator{ generator }
     {
     }
@@ -58,13 +58,13 @@ struct qlow::sem::BinaryNativeMethod : public sem::NativeMethod
     Func generator;
     Variable argument;
     
-    inline BinaryNativeMethod(std::shared_ptr<Type> returnType,
-                              std::shared_ptr<Type> argumentType,
+    inline BinaryNativeMethod(TypeId returnType,
+                              TypeId argumentType,
         
         Func&& generator) :
-        NativeMethod{ std::move(returnType) },
+        NativeMethod{ returnType },
         generator{ generator },
-        argument{ std::move(argumentType), "arg" }
+        argument{ argumentType, "arg" }
     {
         Method::arguments = { &argument };
     }

+ 2 - 2
src/Scope.h

@@ -52,8 +52,8 @@ public:
     virtual ~Scope(void);
     virtual Variable* getVariable(const std::string& name) = 0;
     virtual Method* getMethod(const std::string& name) = 0;
-    virtual std::shared_ptr<Type> getType(const ast::Type& name) = 0;
-    virtual std::shared_ptr<Type> getReturnableType(void) = 0;
+    virtual TypeId getType(const ast::Type& name) = 0;
+    virtual TypeId getReturnableType(void) = 0;
     virtual Method* resolveMethod(const std::string& name,
         const std::vector<std::shared_ptr<Type>> argumentTypes);
 

+ 24 - 23
src/sem/Semantic.h

@@ -110,8 +110,8 @@ struct qlow::sem::Variable : public SemanticObject
     llvm::Value* allocaInst;
     
     Variable(void) = default;
-    inline Variable(std::shared_ptr<Type> type, const std::string& name) :
-        type{ std::move(type) },
+    inline Variable(TypeId type, const std::string& name) :
+        type{ type },
         name{ name },
         allocaInst { nullptr }
     {
@@ -131,7 +131,7 @@ struct qlow::sem::Field : public Variable
 struct qlow::sem::Method : public SemanticObject
 {
     Class* containingType;
-    std::shared_ptr<Type> returnType;
+    TypeId returnType;
     std::vector<Variable*> arguments;
     std::string name;
     ast::MethodDefinition* astNode;
@@ -142,9 +142,9 @@ struct qlow::sem::Method : public SemanticObject
 
     llvm::Function* llvmNode;
 
-    inline Method(Scope& parentScope, std::shared_ptr<Type> returnType) :
+    inline Method(Scope& parentScope, TypeId returnType) :
         containingType{ nullptr },
-        returnType{ std::move(returnType) },
+        returnType{ returnType },
         scope{ parentScope, this },
         thisExpression{ nullptr },
         body{ nullptr }
@@ -153,6 +153,7 @@ struct qlow::sem::Method : public SemanticObject
     
     inline Method(ast::MethodDefinition* astNode, Scope& parentScope) :
         containingType{ nullptr },
+        returnType{ Type{ parentScope.returnType.getContext() }},
         astNode{ astNode },
         name{ astNode->name },
         scope{ parentScope, this },
@@ -171,7 +172,7 @@ struct qlow::sem::ThisExpression : public Variable
 {
     Method* method;
     inline ThisExpression(Method* method) :
-        Variable{ std::make_shared<PointerType>(std::make_shared<ClassType>(method->containingType)), "this" },
+        Variable{ method->containingType.toPointer(), "this" },
         method{ method }
     {
     }
@@ -259,10 +260,10 @@ struct qlow::sem::Expression :
                      llvm::IRBuilder<>,
                      qlow::LValueVisitor>
 {
-    std::shared_ptr<sem::Type> type;
+    TypeId type;
     
-    inline Expression(std::shared_ptr<Type> type) :
-        type{ std::move(type) }
+    inline Expression(TypeId type) :
+        type{ type }
     {
     }
     
@@ -277,8 +278,8 @@ struct qlow::sem::Operation : public Expression
 {
     std::string opString;
     
-    inline Operation(std::shared_ptr<Type> type) :
-        Expression{ std::move(type) }
+    inline Operation(TypeId type) :
+        Expression{ type }
     {
     }
 };
@@ -307,7 +308,7 @@ struct qlow::sem::AddressExpression : public Expression
     std::unique_ptr<sem::Expression> target;
     
     inline AddressExpression(std::unique_ptr<sem::Expression> target) :
-        Expression{ std::make_shared<sem::PointerType>(target->type) },
+        Expression{ target->type.toPointer() },
         target{ std::move(target) }
     {
     }
@@ -325,8 +326,8 @@ struct qlow::sem::BinaryOperation : public Operation
     /// method that is called to execute the operator
     sem::Method* operationMethod;
     
-    inline BinaryOperation(std::shared_ptr<Type> type, ast::BinaryOperation* astNode) :
-        Operation{ std::move(type) },
+    inline BinaryOperation(TypeId type, ast::BinaryOperation* astNode) :
+        Operation{ type },
         astNode{ astNode }
     {
     }
@@ -340,16 +341,16 @@ struct qlow::sem::BinaryOperation : public Operation
 struct qlow::sem::CastExpression : public Expression
 {
     std::unique_ptr<Expression> expression;
-    std::shared_ptr<Type> targetType;
+    TypeId targetType;
     
     ast::CastExpression* astNode;
     
     inline CastExpression(std::unique_ptr<Expression> expression,
-                          std::shared_ptr<Type> type,
+                          TypeId type,
                           ast::CastExpression* astNode) :
         Expression{ type },
         expression{ std::move(expression) },
-        targetType{ std::move(type) },
+        targetType{ type },
         astNode{ astNode }
     {
     }
@@ -362,12 +363,12 @@ struct qlow::sem::CastExpression : public Expression
 
 struct qlow::sem::NewArrayExpression : public Expression
 {
-    std::shared_ptr<Type> arrayType;
+    TypeId arrayType;
     std::unique_ptr<Expression> length;
     
-    inline NewArrayExpression(std::shared_ptr<Type> arrayType) :
-        Expression{ std::make_shared<ArrayType>(arrayType) },
-        arrayType{ std::move(arrayType) }
+    inline NewArrayExpression(TypeId arrayType) :
+        Expression{ arrayType.toArray() },
+        arrayType{ arrayType }
     {
     }
     
@@ -381,8 +382,8 @@ 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) }
+    inline UnaryOperation(TypeId type) :
+        Operation{ type }
     {
     }
     

+ 29 - 2
src/sem/Type.cpp

@@ -2,11 +2,30 @@
 
 #include "Context.h"
 
+using qlow::sem::TypeId;
 using qlow::sem::Type;
 
+
+TypeId TypeId::toPointer(void) const
+{
+    return context.addType(Type::createPointerType(context, *this));
+}
+
+
+TypeId TypeId::toArray(void) const
+{
+    return context.addType(Type::createArrayType(context, *this));
+}
+
+
 Type::Kind Type::getKind(void) const
 {
-    return static_cast<Kind>(type.index());
+    switch(type.index()) {
+        case 0: return Kind::NATIVE;
+        case 1: return Kind::CLASS;
+        case 2: return Kind::POINTER;
+        case 3: return Kind::ARRAY;
+    }
 }
 
 
@@ -38,13 +57,21 @@ std::string Type::asString(void) const
 bool Type::operator==(const Type& other) const
 {
     return this->name == other.name &&
-           this->kind == other.kind &&
            this->type == other.type;
 }
 
 
+Type Type::createPointerType(Context& c, TypeId pointsTo)
+{
+    return Type{ Union{ PointerType{ pointsTo }}};
+}
 
 
+Type Type::createArrayType(Context& c, TypeId pointsTo)
+{
+    return Type{ Union{ ArrayType{ pointsTo }}};
+}
+
 
 
 #if 0

+ 16 - 1
src/sem/Type.h

@@ -3,6 +3,7 @@
 
 #include <variant>
 #include <string>
+#include <climits>
 
 namespace qlow::sem
 {
@@ -36,8 +37,14 @@ public:
     inline TypeId(Context& context, size_t id) :
         context{ context }, id{ id } {}
 
+    inline TypeId(Context& context) :
+        context{ context }, id{ std::numeric_limits<size_t>::max() } {}
+
     inline Context& getContext(void) const { return context; }
     inline size_t getId(void) const { return id; }
+
+    TypeId toPointer(void) const;
+    TypeId toArray(void) const;
 };
 
 
@@ -73,13 +80,21 @@ private:
         TypeId targetType;
     };
 
-    std::variant<NativeType, ClassType, PointerType, ArrayType> type;
+    using Union = std::variant<NativeType, ClassType, PointerType, ArrayType>;
+    Union type;
+
+    inline Type(Union type) :
+        type{ type } {}
+
 public:
     Kind getKind(void) const;
     std::string asString(void) const;
     size_t hash(void) const;
 
     bool operator == (const Type& other) const;
+
+    static Type createPointerType(Context& c, TypeId pointsTo);
+    static Type createArrayType(Context& c, TypeId pointsTo);
 };