Nicolas Winkler 6 gadi atpakaļ
vecāks
revīzija
e4dbf963e8
5 mainītis faili ar 52 papildinājumiem un 5 dzēšanām
  1. 25 1
      src/CodeGeneration.cpp
  2. 2 0
      src/Semantic.h
  3. 18 0
      src/Type.cpp
  4. 6 1
      src/Type.h
  5. 1 3
      src/test.qlw

+ 25 - 1
src/CodeGeneration.cpp

@@ -3,6 +3,7 @@
 #include <llvm/IR/LLVMContext.h>
 #include <llvm/IR/LegacyPassManager.h>
 #include <llvm/IR/Type.h>
+#include <llvm/IR/DerivedTypes.h>
 #include <llvm/IR/Constants.h>
 #include <llvm/IR/BasicBlock.h>
 #include <llvm/IR/Verifier.h>
@@ -34,11 +35,34 @@ std::unique_ptr<llvm::Module> generateModule(const sem::SymbolTable<sem::Class>&
     using llvm::IRBuilder;
 
     std::unique_ptr<Module> module = llvm::make_unique<Module>("qlow_module", context);
+
+    // create llvm structs
+    // TODO implement detection of circles
+    for (auto& [name, cl] : classes){
+        llvm::StructType* st;
+        std::vector<llvm::Type*> fields;
+#ifdef DEBUGGING
+        printf("creating llvm struct for %s\n", name.c_str());
+#endif 
+        for (auto& [name, field] : cl->fields) {
+            fields.push_back(field->type.getLlvmType(context));
+            if (fields[fields.size() - 1] == nullptr)
+                throw "internal error: possible circular dependency";
+        }
+        st = llvm::StructType::create(context, fields, name);
+        cl->llvmType = st;
+    }
     
     for (auto& [name, cl] : classes){
         for (auto& [name, method] : cl->methods) {
             std::vector<Type*> doubles(1, Type::getDoubleTy(context));
-            FunctionType* funcType = FunctionType::get(Type::getDoubleTy(context), doubles, false);
+#ifdef DEBUGGING
+            printf("looking up llvm type of %s\n", name.c_str());
+#endif 
+            llvm::Type* returnType = method->returnType.getLlvmType(context);
+            if (returnType == nullptr)
+                throw "invalid return type";
+            FunctionType* funcType = FunctionType::get(returnType, doubles, false);
             Function* func = Function::Create(funcType, Function::ExternalLinkage, method->name, module.get());
             method->llvmNode = func;
         }

+ 2 - 0
src/Semantic.h

@@ -75,6 +75,8 @@ struct qlow::sem::Class : public SemanticObject
     SymbolTable<Method> methods;
     ClassScope scope;
 
+    llvm::Type* llvmType;
+
     inline Class(qlow::ast::Class* astNode, GlobalScope& globalScope) :
         astNode{ astNode }, name{ astNode->name }, scope{ globalScope, this }
     {

+ 18 - 0
src/Type.cpp

@@ -1,5 +1,10 @@
 #include "Type.h"
 
+#include "Semantic.h"
+
+#include <llvm/IR/DerivedTypes.h>
+#include <llvm/IR/Type.h>
+
 
 using namespace qlow;
 
@@ -29,6 +34,19 @@ sem::Class* sem::Type::getClassType(void)
 }
 
 
+llvm::Type* sem::Type::getLlvmType(llvm::LLVMContext& context) const
+{
+    switch (kind) {
+        case Kind::NULL_TYPE:
+            return llvm::Type::getVoidTy(context);
+        case Kind::INTEGER:
+            return llvm::Type::getInt32Ty(context);
+        case Kind::CLASS:
+            return data.classType->llvmType;
+    }
+}
+
+
 const sem::Type sem::Type::INTEGER = sem::Type{ sem::Type::Kind::INTEGER };
 
 

+ 6 - 1
src/Type.h

@@ -1,6 +1,11 @@
 #ifndef QLOW_SEM_TYPE_H
 #define QLOW_SEM_TYPE_H
 
+namespace llvm {
+    class Type;
+    class LLVMContext;
+}
+
 namespace qlow
 {
     namespace sem
@@ -51,7 +56,7 @@ public:
     bool isNative(void) const;
 
     Class* getClassType(void);
-
+    llvm::Type* getLlvmType(llvm::LLVMContext& context) const;
 
     static const Type INTEGER;
 

+ 1 - 3
src/test.qlw

@@ -1,8 +1,7 @@
 
 
 class Main
-    foo: Main
-
+    hoi: Fudi 
     fop: FF do
         var: Integer;
         var := 5;
@@ -27,7 +26,6 @@ class FF
 end
 
 class Fudi
-    hoi: Integer
 end
 
 class Integer               end