summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile11
-rw-r--r--cpp.cpp33
-rw-r--r--cpp.h3
-rw-r--r--debug.cpp12
-rw-r--r--debug.h4
-rw-r--r--elf.cpp7
-rw-r--r--file.cpp2
-rw-r--r--grammer.cpp10
-rw-r--r--mcc.cpp44
-rw-r--r--minicc.h7
-rw-r--r--test-elf.cpp1
11 files changed, 108 insertions, 26 deletions
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<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
}
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<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;
+}
+
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 <string>
+
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 <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)
diff --git a/file.cpp b/file.cpp
index 5e17d1a..72522b3 100644
--- a/file.cpp
+++ b/file.cpp
@@ -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();
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 <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;
}
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 <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);
}
-