diff options
| -rw-r--r-- | Makefile | 11 | ||||
| -rw-r--r-- | cpp.cpp | 33 | ||||
| -rw-r--r-- | cpp.h | 3 | ||||
| -rw-r--r-- | debug.cpp | 12 | ||||
| -rw-r--r-- | debug.h | 4 | ||||
| -rw-r--r-- | elf.cpp | 7 | ||||
| -rw-r--r-- | file.cpp | 2 | ||||
| -rw-r--r-- | grammer.cpp | 10 | ||||
| -rw-r--r-- | mcc.cpp | 44 | ||||
| -rw-r--r-- | minicc.h | 7 | ||||
| -rw-r--r-- | test-elf.cpp | 1 | 
11 files changed, 108 insertions, 26 deletions
| @@ -46,21 +46,22 @@ PROGSRC=\      bnf.cpp \      cpp.cpp \      cppbnf.cpp \ +    debug.cpp \ +    elf.cpp \ +    file.cpp \      grammer.cpp \      lexer.cpp \      minicc.cpp \ -    elf.cpp \ -    file.cpp \  TESTSRC=\      test-cpp.cpp \      test-cppbnf.cpp \ +    test-elf.cpp \      test-grammer.cpp \      test-lexer.cpp \      test-minicc.cpp \ -    test-elf.cpp \ -    googletest/src/gtest-all.cpp \      googlemock/src/gmock-all.cpp \ +    googletest/src/gtest-all.cpp \      $(PROGSRC)  SRC=$(PROGSRC) mcc.cpp @@ -92,7 +93,7 @@ ADD_DEP=Makefile  # misc ---------------------------------------------------  clean: -	-rm -f test-$(PROJECTNAME) +	-rm -f test-$(PROJECTNAME) mcc tempfile.txt  	-find . -name '*.o' -o -name '*.d' -o -name '*.gcno' -o -name '*.gcda' | xargs rm -f  zip: clean @@ -243,18 +243,39 @@ void CPP::link()  // phases of translation, according to standard  void CPP::translate(const std::string& code)  { -#if 0 // fix signatures!   source_charset_map(); +    backslash_escape(); - preprocessing_tokenize(code); +  + auto pp_tokens = preprocessing_tokenize(code); +    preprocess(); +    execution_charset_map(); +    concatenate_strings(); - tokens_from_pptokens(); -  analysis(); -  translate(); +  + auto tokens = tokens_from_pptokens(pp_tokens); + auto nodes = analysis(tokens); + translate(); +    instantiate(); +    link(); -#endif +} + +std::vector<uint8_t> CPP::getCode() +{ + // TODO + return { +            0x48, 0xc7, 0xc0, 0x3c, 0x00, 0x00, 0x00, // mov    $0x3c,%rax     # syscall 60 +            0x48, 0x31, 0xff,                         // xor    %rdi,%rdi      # exit code 0 +            0x0f, 0x05,                               // syscall + }; +} + +std::vector<uint8_t> CPP::getData() +{ + return {}; // TODO  } @@ -30,6 +30,9 @@ void link(); // phase 9  // all phases of translation  void translate(const std::string& code); +std::vector<uint8_t> getCode(); +std::vector<uint8_t> getData(); +  private:   std::string m_code;   std::vector<Token> m_charTokens; diff --git a/debug.cpp b/debug.cpp new file mode 100644 index 0000000..391c522 --- /dev/null +++ b/debug.cpp @@ -0,0 +1,12 @@ +#include "debug.h" + +#include <iostream> + +bool debug{false}; + +void Debug(std::string s) +{ + if (debug) +  std::cout << s << std::endl; +} + @@ -1,3 +1,7 @@  #pragma once +#include <string> +  extern bool debug; + +void Debug(std::string s); @@ -1,6 +1,7 @@  #include "elf.h"  #include "file.h" +#include "minicc.h"  #include <iostream> @@ -156,8 +157,8 @@ namespace {   {    if (elf.size() < size) {     elf.resize(size); -  } else -   throw std::runtime_error("Padding not possible. Too many bytes already."); +  } else if (elf.size() > size) +   throw std::runtime_error("Padding not possible. Too many bytes already. ("s + std::to_string(elf.size()) + " > "s + std::to_string(size) + ")"s);   }  } @@ -195,6 +196,8 @@ void Elf::Write(const std::filesystem::path& path, const std::vector<uint8_t>& c   AddSectionHeaderSectionNames(elf, code, data);   File::setFile(path, elf); + + fs::permissions(path, fs::perms::owner_exec | fs::perms::group_exec | fs::perms::others_exec, fs::perm_options::add);  }  std::vector<uint8_t> Elf::Read(const std::filesystem::path& path) @@ -4,8 +4,6 @@  #include <fstream> -namespace fs = std::filesystem; -  std::vector<uint8_t> File::getFile(const fs::path& filename)  {   std::ifstream file(filename.string(), std::ios::in | std::ios::binary | std::ios::ate); diff --git a/grammer.cpp b/grammer.cpp index cb6b3bf..40775ef 100644 --- a/grammer.cpp +++ b/grammer.cpp @@ -1,18 +1,12 @@  #include "grammer.h" +#include "debug.h" +  #include <algorithm>  #include <limits>  using namespace Gram; -bool debug{false}; - -void Debug(std::string s) -{ - if (debug) -  std::cout << s << std::endl; -} -  void Compiler::clear()  {   symbol_variants.clear(); @@ -1,6 +1,50 @@ +//  // CLI +// + +#include "cpp.h" +#include "elf.h" +#include "file.h" + +#include <iostream> + +using namespace std::string_literals; + +namespace { + +void usage() { + std::cout << "Usage: mcc <translation_unit>" << std::endl; +} + +}  int main(int argc, char* argv[])  { + try { +  CPP cpp; + +  if (argc != 2) { +   usage(); +   return 1; +  } + +  fs::path in_filename{argv[1]}; +  fs::path out_filename{in_filename.parent_path() / in_filename.stem()}; + +  if (in_filename == out_filename) +   throw std::runtime_error("Bad output filename: "s + out_filename.generic_string()); + +  auto unit {File::getFile(in_filename)}; + +  std::string unit_string(reinterpret_cast<char*>(unit.data()), unit.size()); + +  cpp.translate(unit_string); + +  Elf::Write(out_filename, cpp.getCode(), cpp.getData()); + } catch (const std::exception& ex) { +  std::cout << "Error: " << ex.what() << std::endl; +  return 1; + } +   return 0;  } @@ -1,14 +1,17 @@  #pragma once  #include <cstdlib> -#include <vector> -#include <string> +#include <filesystem>  #include <iostream> +#include <string> +#include <vector>  using namespace std::string_literals;  using index_t = size_t; +namespace fs = std::filesystem; +  std::vector<std::string> split(std::string s);  struct Location { diff --git a/test-elf.cpp b/test-elf.cpp index 46ef267..0bf1d42 100644 --- a/test-elf.cpp +++ b/test-elf.cpp @@ -69,4 +69,3 @@ TEST_F(ElfTest, write_code_data) {   ASSERT_TRUE(fs::exists(TempFilename()));   ASSERT_GT(fs::file_size(TempFilename()), 0);  } - | 
