瀏覽代碼

now let's go generating code

Nicolas Winkler 6 年之前
父節點
當前提交
adf0f7b713
共有 9 個文件被更改,包括 358 次插入0 次删除
  1. 15 0
      src/Builtin.cpp
  2. 34 0
      src/Builtin.h
  3. 52 0
      src/CodeGeneration.cpp
  4. 15 0
      src/CodeGeneration.h
  5. 11 0
      src/CodegenVisitor.cpp
  6. 45 0
      src/CodegenVisitor.h
  7. 83 0
      src/Scope.cpp
  8. 71 0
      src/Scope.h
  9. 32 0
      src/test.qlw

+ 15 - 0
src/Builtin.cpp

@@ -0,0 +1,15 @@
+#include "Builtin.h"
+
+using namespace qlow;
+
+sem::Class initInt32(void)
+{
+    sem::Class c;
+    c.astNode = nullptr;
+}
+
+
+sem::Class sem::Int32 = initInt32();
+
+
+

+ 34 - 0
src/Builtin.h

@@ -0,0 +1,34 @@
+#ifndef QLOW_SEM_BUILTIN_H
+#define QLOW_SEM_BUILTIN_H
+
+
+#include "Semantic.h"
+
+
+namespace qlow
+{
+    namespace sem
+    {
+        extern Class Int32;
+        extern Class String;
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif // QLOW_SEM_BUILTIN_H
+
+

+ 52 - 0
src/CodeGeneration.cpp

@@ -0,0 +1,52 @@
+#include "CodeGeneration.h"
+
+using namespace qlow;
+
+
+void generateModule(const sem::SymbolTable<sem::Class>& classes)
+{
+
+}
+
+
+void gen::generateObjectFile(const std::string& name, const sem::SymbolTable<sem::Class>& classes)
+{
+    const char cpu[] = "generic";
+    const char features[] = "";
+
+    auto targetMachine =
+        target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
+
+  TargetOptions opt;
+  auto RM = Optional<Reloc::Model>();
+  auto TheTargetMachine =
+      Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
+
+  TheModule->setDataLayout(TheTargetMachine->createDataLayout());
+
+  auto Filename = "output.o";
+  std::error_code EC;
+  raw_fd_ostream dest(Filename, EC, sys::fs::F_None);
+
+  if (EC) {
+    errs() << "Could not open file: " << EC.message();
+    return 1;
+  }
+
+  legacy::PassManager pass;
+  auto FileType = TargetMachine::CGFT_ObjectFile;
+
+  if (TheTargetMachine->addPassesToEmitFile(pass, dest, llvm::LLVMTargetMachine::CGFT_ObjectFile, FileType)) {
+    errs() << "TheTargetMachine can't emit a file of this type";
+    return 1;
+  }
+
+  pass.run(*TheModule);
+  dest.flush();
+
+  outs() << "Wrote " << Filename << "\n";
+
+  return 0;
+}
+
+

+ 15 - 0
src/CodeGeneration.h

@@ -0,0 +1,15 @@
+#ifndef QLOW_CODE_GENERATION_H
+#define QLOW_CODE_GENERATION_H
+
+#include "Semantic.h"
+
+namespace qlow
+{
+    namespace gen
+    {
+        void generateObjectFile(const std::string& name, const sem::SymbolTable<sem::Class>& classes);
+    }
+}
+
+
+#endif // QLOW_CODE_GENERATION_H

+ 11 - 0
src/CodegenVisitor.cpp

@@ -0,0 +1,11 @@
+#include "CodegenVisitor.h"
+
+
+using namespace qlow;
+
+llvm::Value* CodegenVisitor::visit(sem::IntConst& node, llvm::LLVMContext& context)
+{
+    return nullptr;
+}
+
+

+ 45 - 0
src/CodegenVisitor.h

@@ -0,0 +1,45 @@
+#ifndef QLOW_CODEGEN_VISITOR_H
+#define QLOW_CODEGEN_VISITOR_H
+
+#include "llvm/IR/Value.h"
+#include "llvm/IR/LLVMContext.h"
+
+#include "Visitor.h"
+#include "Semantic.h"
+#include "Scope.h"
+
+
+#include <memory>
+
+
+namespace qlow
+{
+    namespace gen
+    {
+    }
+}
+
+
+namespace qlow
+{
+    class CodegenVisitor;
+}
+
+
+class qlow::CodegenVisitor :
+    public Visitor<
+        llvm::Value*,
+        llvm::LLVMContext,
+
+        sem::IntConst
+    >
+{
+public:
+    llvm::Value* visit(sem::IntConst& node, llvm::LLVMContext&) override;
+};
+
+
+#endif // QLOW_CODEGEN_VISITOR_H
+
+
+

+ 83 - 0
src/Scope.cpp

@@ -0,0 +1,83 @@
+#include "Scope.h"
+
+using namespace qlow;
+
+sem::Scope::~Scope(void)
+{
+}
+
+
+sem::Variable* sem::GlobalScope::getVariable(const std::string& name)
+{
+    return nullptr;
+}
+
+
+sem::Method* sem::GlobalScope::getMethod(const std::string& name)
+{
+    return nullptr;
+}
+
+
+std::optional<sem::Type> sem::GlobalScope::getType(const std::string& name)
+{
+    auto t = classes.find(name);
+    if (t != classes.end())
+        return std::make_optional(Type{ t->second.get() });
+    return std::nullopt;
+}
+
+
+sem::Variable* sem::ClassScope::getVariable(const std::string& name)
+{
+    if (class_ref == nullptr)
+        return parentScope.getVariable(name);
+    auto m = class_ref->fields.find(name);
+    if (m != class_ref->fields.end())
+        return (*m).second.get();
+    
+    return parentScope.getVariable(name);
+}
+
+
+sem::Method * sem::ClassScope::getMethod(const std::string& name)
+{
+    if (class_ref == nullptr)
+        return parentScope.getMethod(name);
+    auto m = class_ref->methods.find(name);
+    if (m != class_ref->methods.end())
+        return (*m).second.get();
+    
+    return parentScope.getMethod(name);
+}
+
+
+std::optional<sem::Type> sem::ClassScope::getType(const std::string& name)
+{
+    return parentScope.getType(name);
+}
+
+
+sem::Variable* sem::MethodScope::getVariable(const std::string& name)
+{
+    auto m = localVariables.find(name);
+    if (m != localVariables.end())
+        return (*m).second.get();
+    
+    return parentScope.getVariable(name);
+}
+
+
+sem::Method * sem::MethodScope::getMethod(const std::string& name)
+{
+    return parentScope.getMethod(name);
+}
+
+
+std::optional<sem::Type> sem::MethodScope::getType(const std::string& name)
+{
+    return parentScope.getType(name);
+}
+
+
+

+ 71 - 0
src/Scope.h

@@ -0,0 +1,71 @@
+#ifndef QLOW_SEM_SCOPE_H
+#define QLOW_SEM_SCOPE_H
+
+#include <optional>
+
+#include "Semantic.h"
+
+namespace qlow
+{
+    namespace sem
+    {
+        class Scope;
+        class GlobalScope;
+        class ClassScope;
+        class MethodScope;
+    }
+}
+
+
+class qlow::sem::Scope
+{
+public:
+    virtual ~Scope(void);
+    virtual Variable* getVariable(const std::string& name) = 0;
+    virtual Method* getMethod(const std::string& name) = 0;
+    virtual std::optional<Type> getType(const std::string& name) = 0;
+};
+
+
+class qlow::sem::GlobalScope : public Scope
+{
+public:
+    SymbolTable<Class> classes;
+public:
+    virtual Variable* getVariable(const std::string& name);
+    virtual Method* getMethod(const std::string& name);
+    virtual std::optional<Type> getType(const std::string& name);
+};
+
+
+class qlow::sem::ClassScope : public Scope
+{
+    Scope& parentScope;
+    Class* class_ref;
+public:
+    inline ClassScope(Scope& parentScope, Class* class_ref) :
+        parentScope{ parentScope }, class_ref{ class_ref }
+    {
+    }
+    virtual Variable* getVariable(const std::string& name);
+    virtual Method* getMethod(const std::string& name);
+    virtual std::optional<Type> getType(const std::string& name);
+};
+
+
+class qlow::sem::MethodScope : public Scope
+{
+    Scope& parentScope;
+    SymbolTable<Variable> localVariables;
+public:
+    inline MethodScope(Scope& parentScope) :
+        parentScope{ parentScope }
+    {
+    }
+    virtual Variable* getVariable(const std::string& name);
+    virtual Method* getMethod(const std::string& name);
+    virtual std::optional<Type> getType(const std::string& name);
+};
+
+
+#endif // QLOW_SEM_SCOPE_H

+ 32 - 0
src/test.qlw

@@ -0,0 +1,32 @@
+
+
+class Main
+    foo: Main
+
+    fop: FF do
+        var: Integer;
+        var := 5;
+        var := 102 + var * var;
+        gagagaga;
+        
+        hohohoh;
+    end
+
+    main: Integer do
+        fop
+    end
+end
+
+class FF
+end
+
+class Fudi
+    hoi: Integer
+end
+
+class Integer               end
+
+
+
+
+