From 9ff9bf184558f47f83c44196a05983a49f5bdf16 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 8 Mar 2026 06:22:49 +0100 Subject: [FEAT] CompilerKit testing coverage additions and 64-bit assembler patches. Signed-off-by: Amlal El Mahrouss --- include/CompilerKit/Utilities/Compiler.h | 5 ++-- snippets/.gitkeep | 0 snippets/test_snippets/inner.nc | 11 ++++++++ snippets/test_snippets/test_ostream.nc | 9 ++++++ snippets/test_snippets/test_printf.nc | 11 ++++++++ snippets/test_snippets/test_struct.nc | 20 ++++++++++++++ src/CompilerKit/src/Assemblers/Assembler+AMD64.cpp | 14 ++++++---- src/CompilerKit/test/Compilers/.gitkeep | 0 src/CompilerKit/test/Compilers/CMakeLists.txt | 23 ++++++++++++++++ .../test/Compilers/NectarCodegen.test.cpp | 20 ++++++++++++++ test/.gitkeep | 0 test/test_01_codegen/.gitkeep | 0 test/test_01_codegen/CMakeLists.txt | 23 ---------------- test/test_01_codegen/codegen.test.cc | 32 ---------------------- test/test_02_linker/.gitkeep | 0 test/test_02_linker/CMakeLists.txt | 23 ---------------- test/test_02_linker/linker.test.cc | 28 ------------------- test/test_samples/inner.nc | 11 -------- test/test_samples/test_ostream.nc | 9 ------ test/test_samples/test_printf.nc | 11 -------- test/test_samples/test_struct.nc | 20 -------------- 21 files changed, 106 insertions(+), 164 deletions(-) create mode 100644 snippets/.gitkeep create mode 100644 snippets/test_snippets/inner.nc create mode 100644 snippets/test_snippets/test_ostream.nc create mode 100644 snippets/test_snippets/test_printf.nc create mode 100644 snippets/test_snippets/test_struct.nc create mode 100644 src/CompilerKit/test/Compilers/.gitkeep create mode 100644 src/CompilerKit/test/Compilers/CMakeLists.txt create mode 100644 src/CompilerKit/test/Compilers/NectarCodegen.test.cpp delete mode 100644 test/.gitkeep delete mode 100644 test/test_01_codegen/.gitkeep delete mode 100644 test/test_01_codegen/CMakeLists.txt delete mode 100644 test/test_01_codegen/codegen.test.cc delete mode 100644 test/test_02_linker/.gitkeep delete mode 100644 test/test_02_linker/CMakeLists.txt delete mode 100644 test/test_02_linker/linker.test.cc delete mode 100644 test/test_samples/inner.nc delete mode 100644 test/test_samples/test_ostream.nc delete mode 100644 test/test_samples/test_printf.nc delete mode 100644 test/test_samples/test_struct.nc diff --git a/include/CompilerKit/Utilities/Compiler.h b/include/CompilerKit/Utilities/Compiler.h index 5d4c6d9..0c787ba 100644 --- a/include/CompilerKit/Utilities/Compiler.h +++ b/include/CompilerKit/Utilities/Compiler.h @@ -25,9 +25,10 @@ #define kRed "\e[0;31m" #define kWhite "\e[0;97m" #define kYellow "\e[0;33m" +#define kBlackOverWhite "\E[0;37m" -#define kStdOut (std::cout << kRed << "Nectar: " << kWhite) -#define kStdErr (std::cerr << kRed << "Nectar: " << kWhite) +#define kStdOut (std::cout << kRed << "Nectar: " << kBlackOverWhite) +#define kStdErr (std::cerr << kRed << "Nectar: " << kBlackOverWhite) #define kStdEndl std::endl #define kPrintF kStdOut #define kPrintErr kStdErr diff --git a/snippets/.gitkeep b/snippets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/snippets/test_snippets/inner.nc b/snippets/test_snippets/inner.nc new file mode 100644 index 0000000..5d90b41 --- /dev/null +++ b/snippets/test_snippets/inner.nc @@ -0,0 +1,11 @@ +extern exit; + +let main() +{ + let foo := 42; + + const ret_stub(): + foo := 0x10; + exit(foo); + return 0x0; +} diff --git a/snippets/test_snippets/test_ostream.nc b/snippets/test_snippets/test_ostream.nc new file mode 100644 index 0000000..0d0410b --- /dev/null +++ b/snippets/test_snippets/test_ostream.nc @@ -0,0 +1,9 @@ +#include + +let main() +{ + let io := 0; + io := ostream{}; + let arr := io.read(0, 0); + return arr; +} \ No newline at end of file diff --git a/snippets/test_snippets/test_printf.nc b/snippets/test_snippets/test_printf.nc new file mode 100644 index 0000000..c29bb05 --- /dev/null +++ b/snippets/test_snippets/test_printf.nc @@ -0,0 +1,11 @@ +export main; + +let main() +{ + if (0x01 =: 0x01): + { + return 0; + } + + return 1; +} \ No newline at end of file diff --git a/snippets/test_snippets/test_struct.nc b/snippets/test_snippets/test_struct.nc new file mode 100644 index 0000000..71a9492 --- /dev/null +++ b/snippets/test_snippets/test_struct.nc @@ -0,0 +1,20 @@ +extern exit; +extern malloc; + +let construct_foo() +{ + let io := 0; + io := malloc(4); + + return io; +} + +let main() +{ + let io := 0x0; + io := construct_foo(); + + _ := exit(io); + + return first_number; +} \ No newline at end of file diff --git a/src/CompilerKit/src/Assemblers/Assembler+AMD64.cpp b/src/CompilerKit/src/Assemblers/Assembler+AMD64.cpp index 0acbdb5..536ac27 100644 --- a/src/CompilerKit/src/Assemblers/Assembler+AMD64.cpp +++ b/src/CompilerKit/src/Assemblers/Assembler+AMD64.cpp @@ -900,7 +900,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t& pos, std::string ///////////////////////////////////////////////////////////////////////////////////////// -bool CompilerKit::EncoderAMD64::WriteLine(std::string line, std::string file) { +bool CompilerKit::EncoderAMD64::WriteLine(CompilerKit::STLString line, CompilerKit::STLString file) { if (CompilerKit::ast_find_needle(line, "public_segment ")) return true; struct RegMapAMD64 { @@ -926,7 +926,9 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string line, std::string file) { /// Move instruction handler. if (line.find(name) != std::string::npos) { - if (name == "mov" || name == "xor") { + if ((line.find(name) + name.size()) > line.size()) continue; + + if (name == "mov" || name == "xor") { std::string substr = line.substr(line.find(name) + name.size()); uint64_t bits = kRegisterBitWidth; @@ -1165,9 +1167,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string line, std::string file) { bool hasRBasedRegs = false; - if (!onlyOneReg) { - /// very tricky to understand. - /// but this checks for a r8 through r15 register. + if (!onlyOneReg && currentRegList.size() == 2) { if (currentRegList[0].fName[0] == 'r' || currentRegList[1].fName[0] == 'r') { if (isdigit(currentRegList[0].fName[1]) && isdigit(currentRegList[1].fName[1])) { kAppBytes.emplace_back(0x4d); @@ -1796,10 +1796,13 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string line, std::string file) { if (line.find("bits 64") != std::string::npos) { kRegisterBitWidth = 64U; + return true; } else if (line.find("bits 32") != std::string::npos) { kRegisterBitWidth = 32U; + return true; } else if (line.find("bits 16") != std::string::npos) { kRegisterBitWidth = 16U; + return true; } if (auto org_pos = line.find("org"); org_pos != std::string::npos) { @@ -1827,6 +1830,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string line, std::string file) { } } } + /// write a dword else if (auto pos = line.find(".dword"); pos != std::string::npos) { this->WriteNumber32(pos + strlen(".dword") + 1, line); diff --git a/src/CompilerKit/test/Compilers/.gitkeep b/src/CompilerKit/test/Compilers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/CompilerKit/test/Compilers/CMakeLists.txt b/src/CompilerKit/test/Compilers/CMakeLists.txt new file mode 100644 index 0000000..2d1a2f2 --- /dev/null +++ b/src/CompilerKit/test/Compilers/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.10) +project(NeCTICodeGen) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip +) + +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +add_executable(CodegenTestBasic NectarCodegen.test.cpp) +target_link_libraries(CodegenTestBasic gtest_main) + +set_property(TARGET CodegenTestBasic PROPERTY CXX_STANDARD 20) +target_include_directories(CodegenTestBasic PUBLIC ../../) + +include(GoogleTest) +gtest_discover_tests(CodegenTestBasic) diff --git a/src/CompilerKit/test/Compilers/NectarCodegen.test.cpp b/src/CompilerKit/test/Compilers/NectarCodegen.test.cpp new file mode 100644 index 0000000..27a908e --- /dev/null +++ b/src/CompilerKit/test/Compilers/NectarCodegen.test.cpp @@ -0,0 +1,20 @@ +// Copyright 2024-2026, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (See accompanying +// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0) +// Official repository: https://github.com/ne-foss-org/nectar + +/// @brief Codegen Unit test, from the C++ unit to the final executable. +/// @author Amlal El Mahrouss + +#include + +TEST(CodegenTest, BasicCodegenTestGrep) { + // Compile C++ source to assembly + auto compile_result = std::system("pef-amd64-necdrv ../../../../snippets/test_snippets/inner.nc > /dev/null 2>&1"); + EXPECT_TRUE(compile_result == 0) << "C++ compiler driver failed to compile sample.cc"; +} + +TEST(CodegenTest, BasicCodegenTestAssemble) { + auto expr = std::system("pef-amd64-asm ../../../../snippets/test_snippets/inner.masm > /dev/null 2>&1"); + EXPECT_TRUE(expr == 0) << "ASM Driver did not compile the easy ASM unit."; +} diff --git a/test/.gitkeep b/test/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/test_01_codegen/.gitkeep b/test/test_01_codegen/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/test_01_codegen/CMakeLists.txt b/test/test_01_codegen/CMakeLists.txt deleted file mode 100644 index f6b363b..0000000 --- a/test/test_01_codegen/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(NeCTICodeGen) - -include(FetchContent) -FetchContent_Declare( - googletest - URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip -) - -# For Windows: Prevent overriding the parent project's compiler/linker settings -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -FetchContent_MakeAvailable(googletest) - -enable_testing() - -add_executable(CodegenTestBasic codegen.test.cc) -target_link_libraries(CodegenTestBasic gtest_main) - -set_property(TARGET CodegenTestBasic PROPERTY CXX_STANDARD 20) -target_include_directories(CodegenTestBasic PUBLIC ../../) - -include(GoogleTest) -gtest_discover_tests(CodegenTestBasic) diff --git a/test/test_01_codegen/codegen.test.cc b/test/test_01_codegen/codegen.test.cc deleted file mode 100644 index 10d1f95..0000000 --- a/test/test_01_codegen/codegen.test.cc +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (See accompanying -// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0) -// Official repository: https://github.com/ne-foss-org/nectar - -/// @brief Codegen Unit test, from the C++ unit to the final executable. -/// @author Amlal El Mahrouss - -#include - -TEST(CodegenTest, BasicCodegenTestGrep) { - // Compile C++ source to assembly - auto compile_result = std::system("pef-amd64-cxxdrv ../test_samples/sample.nc > /dev/null 2>&1"); - EXPECT_TRUE(compile_result == 0) << "C++ compiler driver failed to compile sample.cc"; - - // Grep for expected entry point symbol in generated assembly - auto grep_main = std::system("grep -q '__NECTAR_main' ../test_samples/sample.nc.masm"); - EXPECT_TRUE(grep_main == 0) << "Generated assembly missing expected entry point __NECTAR_main"; - - // Grep for return instruction - auto grep_ret = std::system("grep -q 'ret' ../test_samples/sample.nc.masm"); - EXPECT_TRUE(grep_ret == 0) << "Generated assembly missing return instruction"; - - // Grep for 64-bit mode directive - auto grep_bits64 = std::system("grep -q '%bits 64' ../test_samples/sample.nc.masm"); - EXPECT_TRUE(grep_bits64 == 0) << "Generated assembly missing 64-bit mode directive"; -} - -TEST(CodegenTest, BasicCodegenTestAssemble) { - auto expr = std::system("asm -asm-x64 test_samples/sample.asm"); - EXPECT_TRUE(expr == 0) << "ASM Driver did not compile the easy ASM unit."; -} diff --git a/test/test_02_linker/.gitkeep b/test/test_02_linker/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/test_02_linker/CMakeLists.txt b/test/test_02_linker/CMakeLists.txt deleted file mode 100644 index 0ad69e0..0000000 --- a/test/test_02_linker/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(NeCTILinkerTest) - -include(FetchContent) -FetchContent_Declare( - googletest - URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip -) - -# For Windows: Prevent overriding the parent project's compiler/linker settings -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -FetchContent_MakeAvailable(googletest) - -enable_testing() - -add_executable(LinkerTestBasic linker.test.cc) -target_link_libraries(LinkerTestBasic gtest_main) - -set_property(TARGET LinkerTestBasic PROPERTY CXX_STANDARD 20) -target_include_directories(LinkerTestBasic PUBLIC ../../) - -include(GoogleTest) -gtest_discover_tests(LinkerTestBasic) diff --git a/test/test_02_linker/linker.test.cc b/test/test_02_linker/linker.test.cc deleted file mode 100644 index bade75b..0000000 --- a/test/test_02_linker/linker.test.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (See accompanying -// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0) -// Official repository: https://github.com/ne-foss-org/nectar - -/// @brief Linker Unit test, from the C++ unit to the final executable. -/// @author Amlal El Mahrouss - -#include - -/// compile -TEST(LinkerTest, BasicLinkTestCompile) { - auto expr = std::system("pef-amd64-cxxdrv test_samples/sample.cc"); - EXPECT_TRUE(expr == 0) << "C++ Driver did not compile the easy C++ unit."; -} - -/// assemble -TEST(LinkerTest, BasicLinkTestAssemble) { - auto expr = std::system("asm -asm:x64 test_samples/sample.cc.pp.masm"); - EXPECT_TRUE(expr == 0) << "Assembler did not assemble the easy asm unit."; -} - -/// link -TEST(LinkerTest, BasicLinkTestLink) { - auto expr = std::system( - "ld64 -amd64 test_samples/sample.cc.pp.obj -start __NECTAR_main -output main.exec"); - EXPECT_TRUE(expr == 0) << "Linker did not link the easy object."; -} diff --git a/test/test_samples/inner.nc b/test/test_samples/inner.nc deleted file mode 100644 index 5d90b41..0000000 --- a/test/test_samples/inner.nc +++ /dev/null @@ -1,11 +0,0 @@ -extern exit; - -let main() -{ - let foo := 42; - - const ret_stub(): - foo := 0x10; - exit(foo); - return 0x0; -} diff --git a/test/test_samples/test_ostream.nc b/test/test_samples/test_ostream.nc deleted file mode 100644 index 0d0410b..0000000 --- a/test/test_samples/test_ostream.nc +++ /dev/null @@ -1,9 +0,0 @@ -#include - -let main() -{ - let io := 0; - io := ostream{}; - let arr := io.read(0, 0); - return arr; -} \ No newline at end of file diff --git a/test/test_samples/test_printf.nc b/test/test_samples/test_printf.nc deleted file mode 100644 index c29bb05..0000000 --- a/test/test_samples/test_printf.nc +++ /dev/null @@ -1,11 +0,0 @@ -export main; - -let main() -{ - if (0x01 =: 0x01): - { - return 0; - } - - return 1; -} \ No newline at end of file diff --git a/test/test_samples/test_struct.nc b/test/test_samples/test_struct.nc deleted file mode 100644 index 71a9492..0000000 --- a/test/test_samples/test_struct.nc +++ /dev/null @@ -1,20 +0,0 @@ -extern exit; -extern malloc; - -let construct_foo() -{ - let io := 0; - io := malloc(4); - - return io; -} - -let main() -{ - let io := 0x0; - io := construct_foo(); - - _ := exit(io); - - return first_number; -} \ No newline at end of file -- cgit v1.2.3