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); } - |