Pārlūkot izejas kodu

improving module support

Nicolas Winkler 6 gadi atpakaļ
vecāks
revīzija
192f32e990
12 mainītis faili ar 101 papildinājumiem un 42 dzēšanām
  1. 1 0
      src/CMakeLists.txt
  2. 31 12
      src/Driver.cpp
  3. 0 2
      src/Driver.h
  4. 14 0
      src/ast/Ast.cpp
  5. 5 2
      src/ast/Ast.h
  6. 5 0
      src/ast/Parser.cpp
  7. 5 3
      src/ast/Parser.h
  8. 6 0
      src/ast/syntax.y
  9. 9 4
      src/main.cpp
  10. 5 2
      src/sem/CodeGeneration.cpp
  11. 19 0
      src/some.qlw
  12. 1 17
      src/test.qlw

+ 1 - 0
src/CMakeLists.txt

@@ -46,6 +46,7 @@ if ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG )
     target_compile_options(${PROJECT_NAME} PRIVATE 
         -Wall -Wextra -Wpedantic -pedantic -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable
     )
+    target_link_libraries(${PROJECT_NAME} stdc++fs)
     set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -DDEBUGGING")
 endif()
 if ( MSVC )

+ 31 - 12
src/Driver.cpp

@@ -9,6 +9,10 @@
 #include "ErrorReporting.h"
 
 #include <cstdio>
+#include <set>
+#include <filesystem>
+#include <functional>
+#include <algorithm>
 
 extern std::unique_ptr<std::vector<std::unique_ptr<qlow::ast::AstObject>>> parsedClasses;
 extern FILE* qlow_parser_in;
@@ -176,17 +180,35 @@ bool Driver::parseStage(void)
     this->ast = std::make_unique<ast::Ast>();
     bool errorOccurred = false;
 
-    for (auto& filename : options.infiles) {
+    std::set<std::filesystem::path> alreadyParsed = {};
+    std::set<std::filesystem::path> toParse = {};
+
+    toParse.insert(options.infiles.begin(), options.infiles.end());
+
+    while(!toParse.empty()) {
+        auto filename = toParse.extract(toParse.begin()).value();
+        auto dirPath = filename.parent_path();
         std::FILE* file = std::fopen(filename.c_str(), "r");
 
         if (!file) {
-            reportError("could not open file "s + filename + ".");
+            reportError("could not open file "s + filename.string() + ".");
+            errorOccurred = true;
             continue;
         }
 
         try {
             // parse file content and add parsed objects to global ast
-            this->ast->merge(parseFile(file, filename));
+            ast::Parser parser(file, filename);
+            this->ast->merge(parser.parse());
+            for (auto& import : parser.getImports()) {
+                auto importPath = dirPath / import->getRelativePath();
+#ifdef DEBUGGING
+                printer << "imported " << importPath << std::endl;
+#endif
+                if (alreadyParsed.count(dirPath) == 0) {
+                    toParse.insert(importPath);
+                }
+            }
         }
         catch (const CompileError& ce) {
             ce.print(printer);
@@ -196,14 +218,20 @@ bool Driver::parseStage(void)
             reportError(errMsg);
             errorOccurred = true;
         }
+        catch (const SyntaxError& se) {
+            se.print(printer);
+            errorOccurred = true;
+        }
         catch (...) {
             reportError("an unknown error occurred.");
             errorOccurred = true;
+            throw;
         }
         
         if (file)
             std::fclose(file);
     }
+
     return errorOccurred;
 }
 
@@ -233,15 +261,6 @@ bool Driver::semanticStage(void)
 }
 
 
-qlow::ast::Ast Driver::parseFile(FILE* file,
-        const std::string& filename)
-{
-    ast::Parser parser(file, filename);
-    return parser.parse();
-}
-
-
-
 
 
 

+ 0 - 2
src/Driver.h

@@ -51,8 +51,6 @@ public:
 
     bool parseStage(void);
     bool semanticStage(void);
-    
-    qlow::ast::Ast parseFile(FILE* file, const std::string& filename);
 };
 
 

+ 14 - 0
src/ast/Ast.cpp

@@ -12,6 +12,20 @@ void Ast::merge(Ast other)
 }
 
 
+std::filesystem::path ImportDeclaration::getRelativePath(void) const
+{
+    if (imported.empty())
+        return "";
+    std::filesystem::path path = imported[0];
+
+    for (size_t i = 1; i < imported.size(); i++) {
+        path = path / imported[i];
+    }
+
+    return path.string() + ".qlw";
+}
+
+
 AstObject::~AstObject(void)
 {
 }

+ 5 - 2
src/ast/Ast.h

@@ -27,6 +27,7 @@
 #include <memory>
 #include <utility>
 #include <map>
+#include <filesystem>
 
 #include "Visitor.h"
 #include "Util.h"
@@ -125,13 +126,15 @@ struct qlow::ast::AstObject :
 struct qlow::ast::ImportDeclaration
 {
     CodePosition pos;
-    std::string imported;
+    std::vector<std::string> imported;
     
     inline ImportDeclaration(std::string imported, const CodePosition& cp) :
         pos{ cp },
-        imported{ std::move(imported) }
+        imported{ std::vector<std::string>{ std::move(imported) } }
     {
     }
+
+    std::filesystem::path getRelativePath(void) const;
 };
 
 

+ 5 - 0
src/ast/Parser.cpp

@@ -30,5 +30,10 @@ qlow::ast::Ast Parser::parse(void)
 void Parser::addImports(std::vector<std::unique_ptr<ImportDeclaration>> toAdd)
 {
     std::move(toAdd.begin(), toAdd.end(), std::back_inserter(this->imports));
+}
+
 
+const std::vector<std::unique_ptr<qlow::ast::ImportDeclaration>>& Parser::getImports(void) const
+{
+    return imports;
 }

+ 5 - 3
src/ast/Parser.h

@@ -3,6 +3,7 @@
 
 #include <cstdio>
 #include <string>
+#include <filesystem>
 #include "Ast.h"
 
 namespace qlow
@@ -16,17 +17,18 @@ namespace qlow
 class qlow::ast::Parser
 {
     FILE* stream;
-    std::string filename;
+    std::filesystem::path filename;
     std::vector<std::unique_ptr<ImportDeclaration>> imports;
 public:
-    inline Parser(FILE* stream, std::string filename) :
+    inline Parser(FILE* stream, std::filesystem::path filename) :
         stream{ stream }, filename{ std::move(filename) } {}
     
     Ast parse(void);
 
     void addImports(std::vector<std::unique_ptr<ImportDeclaration>> toAdd);
+    const std::vector<std::unique_ptr<ImportDeclaration>>& getImports(void) const;
 
-    inline const std::string& getFilename(void) const { return filename; }
+    inline std::string getFilename(void) const { return filename.string(); }
 };
 
 #endif // QLOW_AST_PARSER_H

+ 6 - 0
src/ast/syntax.y

@@ -277,6 +277,12 @@ importDeclaration:
     IMPORT IDENTIFIER {
         $$ = new qlow::ast::ImportDeclaration(std::move(*$2), @2);
         delete $2; $2 = nullptr;
+    }
+    |
+    importDeclaration DOT IDENTIFIER {
+        $$->pos = @$;
+        $$->imported.push_back(std::move(*$3));
+        delete $3; $3 = nullptr;
     };
 
 classDefinition:

+ 9 - 4
src/main.cpp

@@ -13,10 +13,12 @@
 
 int main(int argc, char** argv) try
 {
-    /*std::set_terminate ([] () {
+#ifndef DEBUGGING
+    std::set_terminate ([] () {
         qlow::printError(qlow::Printer::getInstance(), "severe internal compiler error");
         exit(1);
-    });*/
+    });
+#endif
 
     qlow::Driver driver(argc, argv);
     return driver.run();
@@ -26,8 +28,11 @@ int main(int argc, char** argv) try
 catch (float f) {
     std::cerr << "uncaught float" << std::endl;
 }
-catch(...) {
-    std::cerr << "uncaught exception" << std::endl;
+catch (std::bad_alloc ba) {
+    std::cerr << "out of memory" << std::endl;
 }
+/*catch(...) {
+    std::cerr << "uncaught exception" << std::endl;
+}*/
 
 

+ 5 - 2
src/sem/CodeGeneration.cpp

@@ -269,13 +269,16 @@ void generateObjectFile(const std::string& filename, std::unique_ptr<llvm::Modul
             features, targetOptions, relocModel);
 
     std::error_code errorCode;
-    raw_fd_ostream dest(filename, errorCode, llvm::sys::fs::F_None);
+
+    auto tempfile = std::filesystem::temp_directory_path() / "qlow.o";
+
+    raw_fd_ostream dest(tempfile.c_str(), errorCode, llvm::sys::fs::F_None);
 #ifdef DEBUGGING
     printer << "adding passes" << std::endl;
 #endif
     targetMachine->addPassesToEmitFile(pm, dest,
 //        llvm::LLVMTargetMachine::CGFT_ObjectFile,
-        nullptr,
+//        nullptr,
         llvm::TargetMachine::CGFT_ObjectFile);
 
     pm.run(*module);

+ 19 - 0
src/some.qlw

@@ -0,0 +1,19 @@
+extern printint(x: Integer)
+
+fast_fibonacci(i: Integer): Integer do
+    a: Integer
+    b: Integer
+    temp: Integer
+    count: Integer
+    count := i 
+    a := 0 // sdfsfaf
+    b := 1
+    while count != 0 do
+        temp := a
+        a := a + b
+        b := temp
+        count := count - 1
+    end
+    return a
+end
+

+ 1 - 17
src/test.qlw

@@ -1,21 +1,5 @@
-fast_fibonacci(i: Integer): Integer do
-    a: Integer
-    b: Integer
-    temp: Integer
-    count: Integer
-    count := i 
-    a := 0 // sdfsfaf
-    b := 1
-    while count != 0 do
-        temp := a
-        a := a + b
-        b := temp
-        count := count - 1
-    end
-    return a
-end
+import some
 
-extern printint(x: Integer)
 
 class Aalala