diff options
author | Roland Reichwein <mail@reichwein.it> | 2020-10-24 16:32:18 +0200 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2020-10-24 16:32:18 +0200 |
commit | 1011655d2ef76a0c0aa29dbbff091dab139198e3 (patch) | |
tree | 63763828f259846f56285691805c187583ecb6bb /tests | |
parent | 1349c00b782eca3ea841bfa388301cb6fc908cc7 (diff) |
Add FlowGraph
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test-asm.cpp | 132 | ||||
-rw-r--r-- | tests/test-cpp.cpp | 78 | ||||
-rw-r--r-- | tests/test-cppbnf.cpp | 45 | ||||
-rw-r--r-- | tests/test-elf.cpp | 71 | ||||
-rw-r--r-- | tests/test-flowgraph.cpp | 50 | ||||
-rw-r--r-- | tests/test-grammer.cpp | 65 | ||||
-rw-r--r-- | tests/test-lexer.cpp | 39 | ||||
-rw-r--r-- | tests/test-minicc.cpp | 8 |
8 files changed, 488 insertions, 0 deletions
diff --git a/tests/test-asm.cpp b/tests/test-asm.cpp new file mode 100644 index 0000000..2d3afa0 --- /dev/null +++ b/tests/test-asm.cpp @@ -0,0 +1,132 @@ +#include "asm/chunk.h" +#include "asm/assembler.h" +#include "asm/segment.h" +#include "asm/intel64/all_ops.h" + +#include "minicc.h" + +#include <boost/algorithm/string.hpp> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include <algorithm> +#include <cctype> +#include <deque> +#include <map> +#include <memory> +#include <string> +#include <system_error> +#include <utility> +#include <vector> + +using namespace std::string_literals; +namespace fs = std::filesystem; + +class AsmTest: public ::testing::Test +{ +protected: + AsmTest() { + //debug = true; + } + ~AsmTest() { + } + void SetUp(){ + } + void TearDown(){ + } +}; + +TEST_F(AsmTest, Intel64_add) { + Segment segment; + Asm::Args args{{Asm::Args::Register32("eax"), Asm::Args::Immediate32(1)}}; + segment.push_back(makeOp("add", args)); + + ASSERT_EQ(segment.size(), 1); + ASSERT_EQ(segment.getCode(), std::vector<uint8_t>({0x05, 0x01, 0x00, 0x00, 0x00})); +} + +TEST_F(AsmTest, Intel64_int_0) { + Segment segment; + Asm::Args args{{Asm::Args::Immediate8(0)}}; + segment.push_back(makeOp("int", args)); + + ASSERT_EQ(segment.size(), 1); + ASSERT_EQ(segment.getCode(), std::vector<uint8_t>{0xCE}); +} + +TEST_F(AsmTest, Intel64_int_1) { + Segment segment; + Asm::Args args{{Asm::Args::Immediate8(1)}}; + segment.push_back(makeOp("int", args)); + + ASSERT_EQ(segment.size(), 1); + ASSERT_EQ(segment.getCode(), std::vector<uint8_t>{0xF1}); +} + +TEST_F(AsmTest, Intel64_int_5) { + Segment segment; + Asm::Args args{{Asm::Args::Immediate8(5)}}; + segment.push_back(makeOp("int", args)); + + ASSERT_EQ(segment.size(), 1); + ASSERT_EQ(segment.getCode(), std::vector<uint8_t>({0xCD, 0x05})); +} + +TEST_F(AsmTest, Intel64_nop) { + Segment segment; + segment.push_back(makeOp("nop")); + + ASSERT_EQ(segment.size(), 1); + ASSERT_EQ(segment.getCode(), std::vector<uint8_t>{0x90}); +} + +TEST_F(AsmTest, Intel64_ret) { + Segment segment; + segment.push_back(makeOp("ret")); + + ASSERT_EQ(segment.size(), 1); + ASSERT_EQ(segment.getCode(), std::vector<uint8_t>{0xC3}); +} + +TEST_F(AsmTest, Intel64_multiple) { + Segment segment; + + segment.push_back(makeOp("nop")); + Asm::Args args0{{Asm::Args::Immediate8(5)}}; + segment.push_back(makeOp("int", args0)); + segment.push_back(makeOp("ret")); + segment.push_back(makeLabel("data1")); + segment.push_back(makeOp("ret")); + Asm::Args args1{{Asm::Args::Label("data1")}}; + segment.push_back(makeOp("jmp", args1)); + segment.push_back(makeData({1, 2, 3})); + + segment.insertAddresses(); + + ASSERT_EQ(segment.size(), 7); + ASSERT_EQ(segment.getCode(), std::vector<uint8_t>( + { + 0x90, // nop + 0xCD, 0x05, // int 5 + 0xC3, // ret + // data1: + 0xC3, // ret + 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, // jmp data1 + 0x01, 0x02, 0x03 // data + })); + + segment.optimize(); + + ASSERT_EQ(segment.size(), 7); + ASSERT_EQ(segment.getCode(), std::vector<uint8_t>( + { + 0x90, // nop + 0xCD, 0x05, // int 5 + 0xC3, // ret + // data1: + 0xC3, // ret + 0xEB, 0xFF, // jmp data1 + 0x01, 0x02, 0x03 // data + })); +} diff --git a/tests/test-cpp.cpp b/tests/test-cpp.cpp new file mode 100644 index 0000000..513a3a5 --- /dev/null +++ b/tests/test-cpp.cpp @@ -0,0 +1,78 @@ +#include "bnf.h" +#include "cpp.h" +#include "cppbnf.h" +#include "lexer.h" +#include "grammer.h" +#include "minicc.h" +#include "debug.h" + +#include <boost/algorithm/string.hpp> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include <algorithm> +#include <cctype> +#include <deque> +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +class CppTest: public ::testing::Test +{ +protected: + CppTest() { + debug = true; + } + ~CppTest() { + } +}; + +TEST_F(CppTest, preprocessing_tokenize) { + CPP cpp; + auto pp_tokens = cpp.preprocessing_tokenize("int main() { return 1; }"); + + ASSERT_EQ(pp_tokens.size(), 9); + + auto tokens = cpp.tokens_from_pptokens(pp_tokens); + + ASSERT_EQ(tokens.size(), 9); + + auto nodes = cpp.analysis(tokens); + + ASSERT_EQ(nodes.size(), 60/*44*/); +} + +TEST_F(CppTest, preprocessing_tokenize_compile_error) { + CPP cpp; + auto ppTree = cpp.preprocessing_tokenize("in ma"); + + auto tokens = cpp.tokens_from_pptokens(ppTree); + + ASSERT_EQ(tokens.size(), 2); + + try { + auto nodes = cpp.analysis(tokens); + } catch (const std::exception& ex) { + EXPECT_EQ(ex.what(), "Compile error"s); + return; + } + + FAIL() << "Exception expected"; +} + +TEST(Cpp, compile) { + CPP cpp; + + cpp.compile("int main() { return 1 + 1; }"); +} + +TEST(Cpp, compile_2_times) { + CPP cpp; + + cpp.compile("int main() { return (1 + 2) * 2; }"); + cpp.compile("int main() { return 1 + 2 * 2; }"); +} + diff --git a/tests/test-cppbnf.cpp b/tests/test-cppbnf.cpp new file mode 100644 index 0000000..e365574 --- /dev/null +++ b/tests/test-cppbnf.cpp @@ -0,0 +1,45 @@ +#include "bnf.h" +#include "cpp.h" +#include "cppbnf.h" +#include "lexer.h" +#include "grammer.h" +#include "minicc.h" +#include "debug.h" + +#include <boost/algorithm/string.hpp> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include <algorithm> +#include <cctype> +#include <deque> +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +class CppBnfTest: public ::testing::Test +{ +protected: + CppBnfTest() { + //debug = true; + } + ~CppBnfTest() { + } +}; + +TEST_F(CppBnfTest, LexicalBnf) { + auto bnf = SubBNF(CPPBNF::GetCppBNFLex(), "preprocessing-token"); + + EXPECT_TRUE(CPPBNF::valid(bnf)); + EXPECT_TRUE(CPPBNF::validLex(bnf)); +} + +TEST_F(CppBnfTest, GrammarBnf) { + auto bnf = SubBNF(CPPBNF::GetCppBNFGram(), "translation-unit"); + + EXPECT_TRUE(CPPBNF::valid(bnf)); +} + diff --git a/tests/test-elf.cpp b/tests/test-elf.cpp new file mode 100644 index 0000000..0bf1d42 --- /dev/null +++ b/tests/test-elf.cpp @@ -0,0 +1,71 @@ +#include "elf.h" +#include "minicc.h" + +#include <boost/algorithm/string.hpp> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include <algorithm> +#include <cctype> +#include <deque> +#include <map> +#include <memory> +#include <string> +#include <system_error> +#include <utility> +#include <vector> + +using namespace std::string_literals; +namespace fs = std::filesystem; + +class ElfTest: public ::testing::Test +{ +protected: + ElfTest() { + //debug = true; + } + ~ElfTest() { + } + fs::path TempFilename(){return "tempfile.txt";} + + void SetUp(){ + std::error_code ec; + fs::remove(TempFilename(), ec); + } + void TearDown(){ + std::error_code ec; + fs::remove(TempFilename(), ec); + } +}; + +#if 0 +TEST_F(ElfTest, read) { +} +#endif + +TEST_F(ElfTest, write_code) { + Elf::Write(TempFilename(), + { + 0x48, 0xc7, 0xc0, 0x3c, 0x00, 0x00, 0x00, // mov $0x3c,%rax # syscall 60 + 0x48, 0x31, 0xff, // xor %rdi,%rdi # exit code 0 + 0x0f, 0x05, // syscall + }, {}); + + ASSERT_TRUE(fs::exists(TempFilename())); + ASSERT_GT(fs::file_size(TempFilename()), 0); +} + +TEST_F(ElfTest, write_code_data) { + Elf::Write(TempFilename(), + { + 0x48, 0xc7, 0xc0, 0x3c, 0x00, 0x00, 0x00, // mov $0x3c,%rax # syscall 60 + 0x48, 0x8b, 0x3c, 0x25, 0x00, 0x20, 0x40, // mov 0x402000,%rdi # use value from data segment as exit code + 0, + 0x0f, 0x05, // syscall + }, + {1, 0, 0, 0, 0, 0, 0, 0}); + + ASSERT_TRUE(fs::exists(TempFilename())); + ASSERT_GT(fs::file_size(TempFilename()), 0); +} diff --git a/tests/test-flowgraph.cpp b/tests/test-flowgraph.cpp new file mode 100644 index 0000000..132af4b --- /dev/null +++ b/tests/test-flowgraph.cpp @@ -0,0 +1,50 @@ +#include "flowgraph/data.h" +#include "flowgraph/graph.h" +#include "flowgraph/node.h" +#include "flowgraph/storage.h" + +#include <boost/algorithm/string.hpp> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include <algorithm> +#include <cctype> +#include <deque> +#include <map> +#include <memory> +#include <string> +#include <system_error> +#include <utility> +#include <vector> + +using namespace std::string_literals; +namespace fs = std::filesystem; + +using namespace FlowGraph; + +class FlowGraphTest: public ::testing::Test +{ +protected: + FlowGraphTest() { + //debug = true; + } + ~FlowGraphTest() { + } + void SetUp(){ + } + void TearDown(){ + } +}; + +TEST_F(FlowGraphTest, build_graph) { + Graph graph; + + Data pointer{ MakeLocalPointer("malloc1") }; + Data size{ MakeLocalSize("size1") }; + std::shared_ptr<Node> malloc1 {std::make_shared<AllocateDynamic>(pointer, size) }; + std::shared_ptr<Node> free1{ std::make_shared<DeallocateDynamic>(pointer) }; + + graph.push_back(malloc1); + graph.push_back(free1); +} diff --git a/tests/test-grammer.cpp b/tests/test-grammer.cpp new file mode 100644 index 0000000..1734da2 --- /dev/null +++ b/tests/test-grammer.cpp @@ -0,0 +1,65 @@ +#include "bnf.h" +#include "cpp.h" +#include "cppbnf.h" +#include "lexer.h" +#include "grammer.h" +#include "minicc.h" +#include "debug.h" + +#include <boost/algorithm/string.hpp> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include <algorithm> +#include <cctype> +#include <deque> +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +using namespace std::string_literals; + +class GrammerTest: public ::testing::Test +{ +protected: + GrammerTest() { + //debug = true; + } + ~GrammerTest() { + } + + // Accessors for friend + size_t minimumSymbolsNeeded(Gram::Compiler& compiler, std::vector<std::string> list) { + return compiler.minimumSymbolsNeeded(list); + } + size_t minimumSymbolsNeeded(Gram::Compiler& compiler, std::string s) { + return compiler.minimumSymbolsNeeded(s); + } +}; + +TEST_F(GrammerTest, minimumSymbolsNeeded) { + auto bnf = SubBNF(CPPBNF::GetCppBNFGram(), "translation-unit"); + + Gram::Compiler compiler(bnf, "translation-unit"); + + EXPECT_EQ(minimumSymbolsNeeded(compiler, std::vector<std::string>{}), 0); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "translation-unit"), 0); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "logical-or-expression"), 1); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "assignment-expression"), 1); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "declaration"), 1); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "block-declaration"), 3); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "simple-declaration"), 2); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "asm-declaration"), 5); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "namespace-alias-definition"), 5); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-declaration"), 4); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-enum-declaration"), 4); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-directive"), 4); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "static_assert-declaration"), 5); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "alias-declaration"), 7); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "opaque-enum-declaration"), 3); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "function-definition"), 4); +} + diff --git a/tests/test-lexer.cpp b/tests/test-lexer.cpp new file mode 100644 index 0000000..23983f1 --- /dev/null +++ b/tests/test-lexer.cpp @@ -0,0 +1,39 @@ +#include "bnf.h" +#include "cpp.h" +#include "cppbnf.h" +#include "lexer.h" +#include "grammer.h" +#include "minicc.h" +#include "debug.h" + +#include <boost/algorithm/string.hpp> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include <algorithm> +#include <cctype> +#include <deque> +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +class LexerTest: public ::testing::Test { +protected: + LexerTest(){ + debug = false; + } + ~LexerTest() override {} +}; + +TEST_F(LexerTest, Lex) { + auto bnf{SubBNF(CPPBNF::GetCppBNFLex(), "preprocessing-token")}; + + Lex::Lexer lexer(bnf, "preprocessing-token"); + + std::vector<Token> tokens{lexer.Lex("int main() { return 1; }")}; + + ASSERT_EQ(tokens.size(), 9); +} diff --git a/tests/test-minicc.cpp b/tests/test-minicc.cpp new file mode 100644 index 0000000..baf8b3f --- /dev/null +++ b/tests/test-minicc.cpp @@ -0,0 +1,8 @@ +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +int main(int argc, char* argv[]) { + ::testing::InitGoogleMock(&argc, argv); + return RUN_ALL_TESTS(); +} + |