From 6154309f0cd3ed5071996951465808f2503e2eb1 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Sun, 29 Mar 2020 18:30:04 +0200 Subject: mcc produces first dummy executable --- Makefile | 11 ++++++----- cpp.cpp | 33 +++++++++++++++++++++++++++------ cpp.h | 3 +++ debug.cpp | 12 ++++++++++++ debug.h | 4 ++++ elf.cpp | 7 +++++-- file.cpp | 2 -- grammer.cpp | 10 ++-------- mcc.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ minicc.h | 7 +++++-- test-elf.cpp | 1 - 11 files changed, 108 insertions(+), 26 deletions(-) create mode 100644 debug.cpp diff --git a/Makefile b/Makefile index e338d84..ec4db3c 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/cpp.cpp b/cpp.cpp index 67c76ef..73f11e1 100644 --- a/cpp.cpp +++ b/cpp.cpp @@ -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 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 CPP::getData() +{ + return {}; // TODO } diff --git a/cpp.h b/cpp.h index 316eaa3..467b268 100644 --- a/cpp.h +++ b/cpp.h @@ -30,6 +30,9 @@ void link(); // phase 9 // all phases of translation void translate(const std::string& code); +std::vector getCode(); +std::vector getData(); + private: std::string m_code; std::vector 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 + +bool debug{false}; + +void Debug(std::string s) +{ + if (debug) + std::cout << s << std::endl; +} + diff --git a/debug.h b/debug.h index 28502dd..25a9671 100644 --- a/debug.h +++ b/debug.h @@ -1,3 +1,7 @@ #pragma once +#include + extern bool debug; + +void Debug(std::string s); diff --git a/elf.cpp b/elf.cpp index 0ad7a04..43d595d 100644 --- a/elf.cpp +++ b/elf.cpp @@ -1,6 +1,7 @@ #include "elf.h" #include "file.h" +#include "minicc.h" #include @@ -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& 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 Elf::Read(const std::filesystem::path& path) diff --git a/file.cpp b/file.cpp index 5e17d1a..72522b3 100644 --- a/file.cpp +++ b/file.cpp @@ -4,8 +4,6 @@ #include -namespace fs = std::filesystem; - std::vector 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 #include using namespace Gram; -bool debug{false}; - -void Debug(std::string s) -{ - if (debug) - std::cout << s << std::endl; -} - void Compiler::clear() { symbol_variants.clear(); diff --git a/mcc.cpp b/mcc.cpp index da2a981..fa9b0b8 100644 --- a/mcc.cpp +++ b/mcc.cpp @@ -1,6 +1,50 @@ +// // CLI +// + +#include "cpp.h" +#include "elf.h" +#include "file.h" + +#include + +using namespace std::string_literals; + +namespace { + +void usage() { + std::cout << "Usage: mcc " << 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(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; } diff --git a/minicc.h b/minicc.h index 5a5f5d8..d3135c6 100644 --- a/minicc.h +++ b/minicc.h @@ -1,14 +1,17 @@ #pragma once #include -#include -#include +#include #include +#include +#include using namespace std::string_literals; using index_t = size_t; +namespace fs = std::filesystem; + std::vector 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); } - -- cgit v1.2.3