Driver.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #include "Driver.h"
  2. #include "Ast.h"
  3. #include "Semantic.h"
  4. #include "CodeGeneration.h"
  5. #include "Logging.h"
  6. #include <cstdio>
  7. extern std::unique_ptr<std::vector<std::unique_ptr<qlow::ast::Class>>> parsedClasses;
  8. extern FILE* qlow_parser_in;
  9. extern int qlow_parser_parse(void);
  10. extern const char* qlow_parser_filename;
  11. using namespace qlow;
  12. Options Options::parseOptions(int argc, char** argv)
  13. {
  14. static const std::map<std::string, bool Options::*> boolArgs =
  15. {
  16. {"-S", &Options::emitAssembly},
  17. {"--emit-assembly", &Options::emitAssembly},
  18. {"-L", &Options::emitLlvm},
  19. {"--emit-llvm", &Options::emitLlvm},
  20. };
  21. Options options{};
  22. for (int i = 1; i < argc; i++) {
  23. std::string arg = argv[i];
  24. if (boolArgs.find(arg) != boolArgs.end()) {
  25. bool Options::* attr = boolArgs.find(arg)->second;
  26. options.*attr = true;
  27. }
  28. else if (arg == "-o" || arg == "--out") {
  29. if (argc > i + 1) {
  30. options.outfile = argv[++i];
  31. }
  32. else {
  33. throw "Please specify a filename after '-o'";
  34. }
  35. }
  36. else {
  37. options.infiles.push_back(std::move(arg));
  38. }
  39. }
  40. return options;
  41. }
  42. Driver::Driver(int argc, char** argv) :
  43. options{ Options::parseOptions(argc, argv) }
  44. {
  45. }
  46. int Driver::run(void)
  47. {
  48. Logger& logger = Logger::getInstance();
  49. //logger.logError("driver not yet implemented", {options.emitAssembly ? "asm" : "noasm", 10, 11, 12, 13});
  50. std::vector<std::unique_ptr<qlow::ast::Class>> classes;
  51. for (auto& filename : options.infiles) {
  52. std::FILE* file = std::fopen(filename.c_str(), "r");
  53. ::qlow_parser_filename = filename.c_str();
  54. try {
  55. auto newClasses = parseFile(file);
  56. classes.insert(classes.end(),
  57. std::make_move_iterator(newClasses.begin()),
  58. std::make_move_iterator(newClasses.end()));
  59. }
  60. catch (const CompileError& ce) {
  61. ce.print(logger);
  62. return 1;
  63. }
  64. catch (const char* errMsg) {
  65. logger.logError(errMsg);
  66. return 1;
  67. }
  68. if (file)
  69. std::fclose(file);
  70. }
  71. std::unique_ptr<qlow::sem::GlobalScope> semClasses =
  72. qlow::sem::createFromAst(*parsedClasses.get());
  73. for (auto& [a, b] : semClasses->classes) {
  74. logger.debug() << a << ": " << b->toString() << std::endl;
  75. }
  76. auto main = semClasses->classes.find("Main");
  77. qlow::sem::Class* mainClass = nullptr;
  78. if (main == semClasses->classes.end()) {
  79. throw "No Main class found!";
  80. }
  81. else {
  82. mainClass = main->second.get();
  83. }
  84. auto mainmain = mainClass->methods.find("main");
  85. qlow::sem::Method* mainMethod = nullptr;
  86. if (mainmain == mainClass->methods.end()) {
  87. //throw "No main method found inside Main class!";
  88. }
  89. else {
  90. mainMethod = mainmain->second.get();
  91. }
  92. logger.debug() << "starting code generation!" << std::endl;
  93. auto mod = qlow::gen::generateModule(semClasses->classes);
  94. qlow::gen::generateObjectFile("obj.o", std::move(mod));
  95. logger.debug() << "object exported!" << std::endl;
  96. return 0;
  97. }
  98. std::vector<std::unique_ptr<qlow::ast::Class>> Driver::parseFile(FILE* file)
  99. {
  100. ::qlow_parser_in = file;
  101. if (!::qlow_parser_in)
  102. throw "Could not run parser: Invalid file";
  103. ::qlow_parser_parse();
  104. auto retval = std::move(*parsedClasses);
  105. parsedClasses.reset();
  106. return retval;
  107. }