Nicolas Winkler пре 6 година
родитељ
комит
3c0c5b8c4d

+ 1 - 1
src/CodegenVisitor.cpp

@@ -131,7 +131,7 @@ llvm::Value* ExpressionCodegenVisitor::visit(sem::CastExpression& cast, llvm::IR
 llvm::Value* ExpressionCodegenVisitor::visit(sem::NewExpression& nexpr, llvm::IRBuilder<>& builder)
 {
     using llvm::Value;
-    
+
     sem::Context& semCtxt = nexpr.context;
     sem::TypeId type = nexpr.type;
 

+ 9 - 2
src/ErrorReporting.cpp

@@ -94,7 +94,7 @@ const std::string& InternalError::getMessage(void) const noexcept
     if (errors.find(errorCode) != errors.end())
         return errors.at(errorCode);
     else {
-        static std::string msg = "error message not found"s;
+        static std::string msg = ""s;
         return msg;
     }
 }
@@ -223,7 +223,7 @@ std::string SemanticError::getMessage(void) const noexcept
     if (errors.find(errorCode) != errors.end())
         return errors.at(errorCode);
     else
-        return "error message not found"s;
+        return ""s;
 }
 
 
@@ -234,3 +234,10 @@ SemanticError SemanticError::invalidReturnType(const std::string& should,
         should + ", but " + is + " is given.", where };
 }
 
+
+SemanticError SemanticError::newForNonClass(const std::string& type,
+    const CodePosition& where)
+{
+    return SemanticError{ NEW_FOR_NON_CLASS, "cannot allocate instance of non-class type '" + type + "' using new", where };
+}
+

+ 2 - 0
src/ErrorReporting.h

@@ -126,6 +126,7 @@ public:
         WRONG_NUMBER_OF_ARGUMENTS,
         TYPE_MISMATCH,
         INVALID_RETURN_TYPE,
+        NEW_FOR_NON_CLASS,
     };
     
     
@@ -148,6 +149,7 @@ public:
     virtual std::string getMessage(void) const noexcept;
 
     static SemanticError invalidReturnType(const std::string& should, const std::string& is, const CodePosition& where);
+    static SemanticError newForNonClass(const std::string& type, const CodePosition& where);
 };
 
 

+ 5 - 2
src/ast/Ast.h

@@ -124,10 +124,13 @@ struct qlow::ast::Class : public AstObject
 {
     std::string name;
     OwningList<FeatureDeclaration> features;
+
+    /// true if it is a class, false if struct
+    bool isReferenceType;
     
-    inline Class(const std::string& name, OwningList<FeatureDeclaration>& features, const CodePosition& cp) :
+    inline Class(std::string name, OwningList<FeatureDeclaration>& features, bool isReferenceType, const CodePosition& cp) :
         AstObject{ cp },
-        name{ name }, features(std::move(features))
+        name{ std::move(name) }, features(std::move(features)), isReferenceType{ isReferenceType }
     {
     }
 

+ 7 - 2
src/ast/AstVisitor.cpp

@@ -415,8 +415,13 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::BinaryOperatio
 std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::NewExpression& ast, sem::Scope& scope)
 {
     auto ret = std::make_unique<sem::NewExpression>(scope.getContext(), scope.getType(ast.type.get()));
-    return ret;
-    //return nullptr;
+    auto* classType = scope.getContext().getType(ret->type).getClass();
+    if (classType != nullptr && classType->isReferenceType) {
+        return ret;
+    }
+    else {
+        throw SemanticError::newForNonClass(scope.getContext().getType(ret->type).asString(), ast.pos);
+    }
 }
 
 

+ 12 - 1
src/ast/syntax.y

@@ -257,7 +257,12 @@ topLevel:
 
 classDefinition:
     CLASS IDENTIFIER featureList END {
-        $$ = new Class(*$2, *$3, @$);
+        $$ = new Class(std::move(*$2), *$3, true, @$);
+        delete $2; delete $3; $2 = 0; $3 = 0;
+    }
+    |
+    STRUCT IDENTIFIER featureList END {
+        $$ = new Class(std::move(*$2), *$3, false, @$);
         delete $2; delete $3; $2 = 0; $3 = 0;
     }
     |
@@ -265,6 +270,12 @@ classDefinition:
         reportError(qlow::SyntaxError(@2));
         yyerrok;
         $$ = nullptr;
+    }
+    |
+    STRUCT error END {
+        reportError(qlow::SyntaxError(@2));
+        yyerrok;
+        $$ = nullptr;
     };
 
 

+ 2 - 1
src/sem/Context.cpp

@@ -156,7 +156,8 @@ void Context::createLlvmTypes(llvm::LLVMContext& llvmCtxt)
             }
 
             llvm::dyn_cast<llvm::StructType>(llvmType)->setBody(llvm::ArrayRef(structTypes));
-            llvmType = llvmType->getPointerTo();
+            if (type.getClass()->isReferenceType)
+                llvmType = llvmType->getPointerTo();
         }
     }
 }

+ 4 - 0
src/sem/Semantic.h

@@ -74,6 +74,7 @@ struct qlow::sem::Class : public SemanticObject
 {
     qlow::ast::Class* astNode;
     std::string name;
+    bool isReferenceType;
     SymbolTable<Field> fields;
     SymbolTable<Method> methods;
     ClassScope scope;
@@ -87,6 +88,7 @@ struct qlow::sem::Class : public SemanticObject
         SemanticObject{ globalScope.getContext() },
         astNode{ astNode },
         name{ astNode->name },
+        isReferenceType{ astNode->isReferenceType },
         scope{ globalScope, this },
         classType{ globalScope.getContext().createClassType(this) },
         llvmType{ nullptr }
@@ -103,6 +105,8 @@ struct qlow::sem::Class : public SemanticObject
     {
     }
 
+    
+
     virtual std::string toString(void) const override;
 };
 

+ 1 - 1
src/tests/structs.qlw

@@ -1,6 +1,6 @@
 
 
-class Vec
+struct Vec
     x: Integer
     y: Integer