From 9c6df3c9b68cbe805827b3a3f0fbdbf637af481b Mon Sep 17 00:00:00 2001 From: "anthony@rabine.fr" Date: Sat, 4 Oct 2025 10:51:14 +0200 Subject: [PATCH] merged tests all in core now, added print test --- .gitignore | 2 +- .vscode/launch.json | 34 +- .vscode/settings.json | 3 +- core/chip32/tests/CMakeLists.txt | 19 - .../src/compiler/assembly_generator_chip32.h | 278 +- core/story-manager/src/compiler/compiler.h | 294 - core/story-manager/src/nodes/print_node.cpp | 2 +- core/story-manager/tests/CMakeLists.txt | 32 - core/story-manager/tests/catch.hpp | 17966 ---------------- core/story-manager/tests/main.cpp | 46 - core/tests/CMakeLists.txt | 35 + core/{chip32 => }/tests/catch.hpp | 2 +- core/{chip32 => }/tests/main.cpp | 0 core/{story-manager => }/tests/test_ast.cpp | 5 +- core/{chip32 => }/tests/test_parser.cpp | 18 +- core/tests/test_print_node.cpp | 239 + core/{chip32 => }/tests/test_vm.cpp | 0 17 files changed, 493 insertions(+), 18482 deletions(-) delete mode 100644 core/chip32/tests/CMakeLists.txt delete mode 100644 core/story-manager/tests/CMakeLists.txt delete mode 100644 core/story-manager/tests/catch.hpp delete mode 100644 core/story-manager/tests/main.cpp create mode 100644 core/tests/CMakeLists.txt rename core/{chip32 => }/tests/catch.hpp (99%) rename core/{chip32 => }/tests/main.cpp (100%) rename core/{story-manager => }/tests/test_ast.cpp (98%) rename core/{chip32 => }/tests/test_parser.cpp (99%) create mode 100644 core/tests/test_print_node.cpp rename core/{chip32 => }/tests/test_vm.cpp (100%) diff --git a/.gitignore b/.gitignore index dc3ac52..b3bd684 100644 --- a/.gitignore +++ b/.gitignore @@ -85,5 +85,5 @@ story-editor/.flatpak-builder story-editor/flatpak_build/ story-editor/AppDir/ -core/story-manager/tests/build story-player/android/build/reports/problems/problems-report.html +core/tests/build \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index d979275..8aed7f4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -69,41 +69,13 @@ }, { - "name": "Debug VM Tests", + "name": "Debug tests", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/core/chip32/tests/build/chip32_test", // Remplacez par le chemin de votre exécutable + "program": "${workspaceFolder}/core/tests/build/core_tests", // Remplacez par le chemin de votre exécutable "args": [], "stopAtEntry": false, - "cwd": "${workspaceFolder}/core/chip32/tests", - "environment": [], - "externalConsole": false, - "linux": { - "MIMode": "gdb", - "miDebuggerPath": "/usr/bin/gdb" - }, - "osx": { - "MIMode": "lldb", - "miDebuggerPath": "/Users/user936511/.vscode/extensions/ms-vscode.cpptools-1.18.5-darwin-arm64/debugAdapters/lldb-mi/bin/lldb-mi" - }, - - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } - ] - - }, - { - "name": "Debug Compiler AST Tests", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceFolder}/core/story-manager/tests/build/compiler_test", // Remplacez par le chemin de votre exécutable - "args": [], - "stopAtEntry": false, - "cwd": "${workspaceFolder}/core/story-manager/tests/build", + "cwd": "${workspaceFolder}/core/tests/build", "environment": [], "externalConsole": false, "linux": { diff --git a/.vscode/settings.json b/.vscode/settings.json index cf08623..030c40d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,7 @@ { "cmake.sourceDirectory": [ - "${workspaceFolder}/core/chip32/tests", - "${workspaceFolder}/core/story-manager/tests", + "${workspaceFolder}/core/tests", "${workspaceFolder}/story-editor", "${workspaceFolder}/story-player-raylib", "${workspaceFolder}/software" diff --git a/core/chip32/tests/CMakeLists.txt b/core/chip32/tests/CMakeLists.txt deleted file mode 100644 index 09494c5..0000000 --- a/core/chip32/tests/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -cmake_minimum_required(VERSION 3.5) - -project(chip32_test LANGUAGES CXX C) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -add_executable(chip32_test - main.cpp - test_parser.cpp - test_vm.cpp - ../chip32_assembler.cpp - ../chip32_vm.c -) - -target_include_directories(chip32_test PRIVATE ../) - -install(TARGETS chip32_test - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/core/story-manager/src/compiler/assembly_generator_chip32.h b/core/story-manager/src/compiler/assembly_generator_chip32.h index 62ab485..42c6805 100644 --- a/core/story-manager/src/compiler/assembly_generator_chip32.h +++ b/core/story-manager/src/compiler/assembly_generator_chip32.h @@ -3,6 +3,7 @@ #include "ast_builder.h" #include "assembly_generator.h" #include "call_function_node.h" +#include class AssemblyGeneratorChip32 : public AssemblyGenerator { @@ -137,19 +138,97 @@ private: m_depth--; } - void GeneratePrintNode(std::shared_ptr node) { + void GeneratePrintNode(std::shared_ptr node) + { auto* printNode = node->GetAs(); if (!printNode) return; std::string label = printNode->GetLabel(); + + AddComment("Print: " + printNode->GetText()); + m_depth++; + // Count the number of arguments connected to the print node + int argCount = 0; + std::vector>> sortedInputs; + + // Collect and sort data inputs by port index + for (const auto& [port, inputNode] : node->dataInputs) { + sortedInputs.push_back({port, inputNode}); + } + + // Sort by port index to ensure correct argument order (arg0, arg1, arg2, arg3) + std::sort(sortedInputs.begin(), sortedInputs.end(), + [](const auto& a, const auto& b) { return a.first < b.first; }); + + argCount = sortedInputs.size(); + + // Save registers that we'll use m_assembly << " push r0\n" - << " push r1\n" - << " lcons r0, $" << label << "\n" - << " lcons r1, 0 ; number of arguments\n" // FIXME: handle arguments - << " syscall 4\n" - << " pop r1\n" + << " push r1\n"; + + // Save argument registers if we have arguments + if (argCount > 0) m_assembly << " push r2\n"; + if (argCount > 1) m_assembly << " push r3\n"; + if (argCount > 2) m_assembly << " push r4\n"; + if (argCount > 3) m_assembly << " push r5\n"; + + // Load arguments into registers r2, r3, r4, r5 + int regIndex = 2; // Start with r2 for first argument + for (const auto& [port, inputNode] : sortedInputs) { + if (regIndex > 5) { + // Maximum 4 arguments (r2, r3, r4, r5) + throw std::runtime_error("Print node supports maximum 4 arguments"); + } + + // Check if the input node is a variable + if (inputNode->IsType()) { + auto* varNode = inputNode->GetAs(); + if (varNode) { + std::string varUuid = varNode->GetVariableUuid(); + + // Find variable in the context + auto var = m_context.FindVariableByUuid(varUuid); + if (var) { + m_assembly << " ; Load arg" << (regIndex - 2) << ": " + << var->GetVariableName() << "\n"; + int varSize = GetVariableSize(var); + m_assembly << " load r" << regIndex << ", $" + << var->GetLabel() << ", " << varSize << " ; " + << var->GetVariableName() << "\n"; + } else { + throw std::runtime_error("Variable not found in context for print argument"); + } + } + } else { + // For non-variable inputs, we might need to evaluate expressions + // For now, we only support direct variable connections + throw std::runtime_error("Print node currently only supports direct variable connections"); + } + + regIndex++; + } + + // Load format string address into r0 + m_assembly << " lcons r0, $" << label << " ; format string\n"; + + // Load number of arguments into r1 + m_assembly << " lcons r1, " << argCount << " ; number of arguments\n"; + + // Call printf syscall + m_assembly << " syscall 4\n"; + + // Restore argument registers (in reverse order) + if (argCount > 3) m_assembly << " pop r5\n"; + if (argCount > 2) m_assembly << " pop r4\n"; + if (argCount > 1) m_assembly << " pop r3\n"; + if (argCount > 0) m_assembly << " pop r2\n"; + + // Restore r0 and r1 + m_assembly << " pop r1\n" << " pop r0\n"; + + m_depth--; } void GenerateOperatorNode(std::shared_ptr node) { @@ -175,157 +254,183 @@ private: if (var) { // Generate code to load the variable value - // FIXME: hardcoded 4 bytes, replace by actual real variable size - m_assembly << " load r" << reg << ", $" << var->GetLabel() << ", 4" << " ; Load variable " << var->GetVariableName() << "\n"; + int varSize = GetVariableSize(var); + m_assembly << " load r" << reg << ", $" << var->GetLabel() + << ", " << varSize << " ; Load variable " + << var->GetVariableName() << "\n"; m_assembly << " push r" << reg << "\n"; } else { - throw std::runtime_error("ERROR! Variable not set in node: " + inputNode->node->GetId()); + throw std::runtime_error("Variable not set in node: " + inputNode->node->GetId()); } } - reg++; } + reg++; } - + // Generate operator code based on type switch (opNode->GetOperationType()) { + // ===== ARITHMETIC OPERATORS ===== case OperatorNode::OperationType::ADD: - m_assembly << " pop r0\n" - << " pop r1\n" + m_assembly << " pop r1\n" + << " pop r0\n" << " add r0, r1\n" << " push r0\n"; break; case OperatorNode::OperationType::SUBTRACT: - m_assembly << " pop r0\n" - << " pop r1\n" + m_assembly << " pop r1\n" + << " pop r0\n" << " sub r0, r1\n" << " push r0\n"; break; case OperatorNode::OperationType::MULTIPLY: - m_assembly << " pop r0\n" - << " pop r1\n" + m_assembly << " pop r1\n" + << " pop r0\n" << " mul r0, r1\n" << " push r0\n"; break; case OperatorNode::OperationType::DIVIDE: - m_assembly << " pop r0\n" - << " pop r1\n" + m_assembly << " pop r1\n" + << " pop r0\n" << " div r0, r1\n" << " push r0\n"; break; - case OperatorNode::OperationType::MODULO: - m_assembly << " pop r0\n" - << " pop r1\n" - << " mod r0, r1\n" - << " push r0\n"; - break; + + // ===== COMPARISON OPERATORS ===== + // Utilise les instructions eq, gt, lt de Chip32 + // Syntaxe: eq r_dest, r_op1, r_op2 → r_dest = (r_op1 == r_op2 ? 1 : 0) + case OperatorNode::OperationType::EQUAL: - m_assembly << " pop r0\n" - << " pop r1\n" - << " cmp r0, r1\n" - << " lcons r0, 1\n" - << " skipz\n" - << " lcons r0, 0\n" + m_assembly << " pop r1 ; second operand\n" + << " pop r0 ; first operand\n" + << " eq r0, r0, r1 ; r0 = (r0 == r1 ? 1 : 0)\n" << " push r0\n"; break; + case OperatorNode::OperationType::NOT_EQUAL: - m_assembly << " pop r0\n" - << " pop r1\n" - << " cmp r0, r1\n" - << " lcons r0, 0\n" - << " skipz\n" - << " lcons r0, 1\n" + m_assembly << " pop r1\n" + << " pop r0\n" + << " eq r0, r0, r1 ; r0 = (r0 == r1 ? 1 : 0)\n" + << " lcons r2, 1\n" + << " xor r0, r2 ; inverse: 0→1, 1→0\n" << " push r0\n"; break; + case OperatorNode::OperationType::GREATER_THAN: - m_assembly << " pop r0\n" - << " pop r1\n" - << " cmp r0, r1\n" - << " lcons r0, 1\n" - << " skipgt\n" - << " lcons r0, 0\n" + m_assembly << " pop r1\n" + << " pop r0\n" + << " gt r0, r0, r1 ; r0 = (r0 > r1 ? 1 : 0)\n" << " push r0\n"; break; + case OperatorNode::OperationType::LESS_THAN: - m_assembly << " pop r0\n" - << " pop r1\n" - << " cmp r0, r1\n" - << " lcons r0, 1\n" - << " skiplt\n" - << " lcons r0, 0\n" + m_assembly << " pop r1\n" + << " pop r0\n" + << " lt r0, r0, r1 ; r0 = (r0 < r1 ? 1 : 0)\n" << " push r0\n"; break; + case OperatorNode::OperationType::GREATER_EQUAL: - m_assembly << " pop r0\n" - << " pop r1\n" - << " cmp r0, r1\n" - << " lcons r0, 1\n" - << " skipge\n" - << " lcons r0, 0\n" + // >= est équivalent à NOT(<) + m_assembly << " pop r1\n" + << " pop r0\n" + << " lt r0, r0, r1 ; r0 = (r0 < r1 ? 1 : 0)\n" + << " lcons r2, 1\n" + << " xor r0, r2 ; inverse: >= est NOT(<)\n" << " push r0\n"; break; + case OperatorNode::OperationType::LESS_EQUAL: - m_assembly << " pop r0\n" - << " pop r1\n" - << " cmp r0, r1\n" - << " lcons r0, 1\n" - << " skiple\n" - << " lcons r0, 0\n" + // <= est équivalent à NOT(>) + m_assembly << " pop r1\n" + << " pop r0\n" + << " gt r0, r0, r1 ; r0 = (r0 > r1 ? 1 : 0)\n" + << " lcons r2, 1\n" + << " xor r0, r2 ; inverse: <= est NOT(>)\n" << " push r0\n"; break; + + // ===== LOGICAL OPERATORS ===== case OperatorNode::OperationType::AND: - m_assembly << " pop r0\n" - << " pop r1\n" - << " and r0, r1\n" + // AND logique: résultat 1 si les deux sont non-zéro + m_assembly << " pop r1\n" + << " pop r0\n" + << " ; Logical AND\n" + << " lcons r2, 0\n" + << " skipz r0\n" + << " skipz r1\n" + << " lcons r2, 1\n" + << " mov r0, r2\n" << " push r0\n"; break; + case OperatorNode::OperationType::OR: - m_assembly << " pop r0\n" - << " pop r1\n" - << " or r0, r1\n" + // OR logique: résultat 1 si au moins un est non-zéro + m_assembly << " pop r1\n" + << " pop r0\n" + << " ; Logical OR\n" + << " or r0, r1 ; bitwise or\n" + << " lcons r2, 0\n" + << " skipz r0\n" + << " lcons r2, 1\n" + << " mov r0, r2\n" << " push r0\n"; break; + case OperatorNode::OperationType::NOT: + // NOT logique: 0→1, non-zero→0 m_assembly << " pop r0\n" - << " not r0\n" + << " ; Logical NOT\n" + << " lcons r1, 1\n" + << " skipz r0\n" + << " lcons r1, 0\n" + << " mov r0, r1\n" << " push r0\n"; break; + + // ===== BITWISE OPERATORS ===== case OperatorNode::OperationType::BITWISE_AND: - m_assembly << " pop r0\n" - << " pop r1\n" + m_assembly << " pop r1\n" + << " pop r0\n" << " and r0, r1\n" << " push r0\n"; break; + case OperatorNode::OperationType::BITWISE_OR: - m_assembly << " pop r0\n" - << " pop r1\n" + m_assembly << " pop r1\n" + << " pop r0\n" << " or r0, r1\n" << " push r0\n"; break; + case OperatorNode::OperationType::BITWISE_XOR: - m_assembly << " pop r0\n" - << " pop r1\n" + m_assembly << " pop r1\n" + << " pop r0\n" << " xor r0, r1\n" << " push r0\n"; break; + case OperatorNode::OperationType::BITWISE_NOT: m_assembly << " pop r0\n" << " not r0\n" << " push r0\n"; break; + case OperatorNode::OperationType::LEFT_SHIFT: - m_assembly << " pop r0\n" - << " pop r1\n" + m_assembly << " pop r1\n" + << " pop r0\n" << " shl r0, r1\n" << " push r0\n"; break; + case OperatorNode::OperationType::RIGHT_SHIFT: - m_assembly << " pop r0\n" - << " pop r1\n" + m_assembly << " pop r1\n" + << " pop r0\n" << " shr r0, r1\n" << " push r0\n"; break; + default: throw std::runtime_error("Unsupported operator type"); } @@ -384,4 +489,21 @@ private: m_assembly << "$" << v->GetLabel() << " DVB, " << (v->GetValue() ? "1" : "0") << " ; " << v->GetVariableName() << "\n"; } } +private: + // Helper pour obtenir la taille en bytes d'une variable selon son type + int GetVariableSize(std::shared_ptr var) const { + switch (var->GetValueType()) { + case Variable::ValueType::INTEGER: + return 4; // 32 bits = 4 bytes (DV32/DC32) + case Variable::ValueType::FLOAT: + return 4; // 32 bits = 4 bytes (DV32/DC32) + case Variable::ValueType::BOOL: + return 1; // 8 bits = 1 byte (DVB/DCB) + case Variable::ValueType::STRING: + // Pour les strings, on charge l'adresse (pointeur 32-bit) + return 4; // Adresse = 4 bytes + default: + throw std::runtime_error("Unknown variable type"); + } + } }; \ No newline at end of file diff --git a/core/story-manager/src/compiler/compiler.h b/core/story-manager/src/compiler/compiler.h index 6c5e03c..b50301c 100644 --- a/core/story-manager/src/compiler/compiler.h +++ b/core/story-manager/src/compiler/compiler.h @@ -85,9 +85,6 @@ public: } } - - - void printAST(const AST& ast, const std::shared_ptr& node, const std::string& prefix = "", bool isLast = true) { // Afficher le nœud actuel std::cout << prefix; @@ -141,68 +138,6 @@ public: printAST(m_ast, entryNode); } - void generateAssembly() { - std::ostringstream assemblyCode; - std::map labels; - - // Trouver le nœud de type "function-entry-node" - std::shared_ptr entryNode; - for (const auto& pair : m_ast.nodeMap) { - if (pair.second->node->GetType() == "function-entry-node") { - entryNode = pair.second; - break; - } - } - - if (!entryNode) { - throw std::runtime_error("No function-entry-node found in the AST."); - } - - // Fonction récursive pour générer le code assembleur - std::function&)> generateCode = [&](const std::shared_ptr& node) { - if (node->node->GetType() == "print") { - // Générer le code pour un nœud de type "print" - assemblyCode << "PRINT "; - // Supposons que le nœud print a une entrée qui est une variable - if (!node->inputs.empty()) { - assemblyCode << node->inputs[0]->node->GetTitle(); - } - assemblyCode << std::endl; - } else if (node->node->GetType() == "variable-node") { - // Générer le code pour un nœud de type "variable-node" - assemblyCode << "LOAD " << node->node->GetTitle() << " INTO REGISTER" << std::endl; - } else if (node->node->GetType() == "branch-node") { - // Générer le code pour un nœud de type "branch-node" - assemblyCode << "BRANCH TO LABEL_" << node->node->GetId() << std::endl; - // Générer le code pour les sorties du nœud branch - for (const auto& outputNode : node->body) { - generateCode(outputNode); - } - } else if (node->node->GetType() == "function-entry-node") { - // Générer le code pour un nœud de type "function-entry-node" - assemblyCode << "FUNCTION ENTRY POINT" << std::endl; - // Générer le code pour les nœuds connectés à ce nœud - for (const auto& inputNode : node->inputs) { - generateCode(inputNode); - } - } - }; - - // // Generate all constants - // for (const auto& astNode : m_ast.nodeMap) { - // assemblyCode << astNode.second->node->GenerateConstants(); - // } - - // After the constants, the main entry point: - assemblyCode << ".main:\n"; - - // Commencer la génération de code à partir du nœud d'entrée - generateCode(entryNode); - - // Stocker le code assembleur généré dans l'AST - m_ast.assemblyCode = assemblyCode.str(); - } - std::string GetCode() const { return m_ast.assemblyCode; } @@ -211,232 +146,3 @@ private: AST m_ast; }; - -/* - -class AssemblyGenerator { - public: - AssemblyGenerator() { - Reset(); - } - - void Reset() { - m_assembly.str(""); - m_labelCounter = 0; - m_variableAddresses.clear(); - m_currentStackOffset = 0; - } - - std::string GenerateAssembly(const std::vector>& roots) { - Reset(); - - // Generate data section - m_assembly << "section .data\n"; - // Add string constants for print nodes - m_assembly << "msg_good db 'Good!',0xa,0\n"; - m_assembly << "msg_bad db 'Bad :(',0xa,0\n"; - - // Generate code section - m_assembly << "\nsection .text\n"; - m_assembly << "global _start\n\n"; - m_assembly << "_start:\n"; - - // Generate entry point code - for (const auto& root : roots) { - GenerateNodeCode(root); - } - - // Add exit syscall - m_assembly << " mov eax, 1\n"; // exit syscall - m_assembly << " mov ebx, 0\n"; // return 0 - m_assembly << " int 0x80\n"; - - return m_assembly.str(); - } - - private: - std::stringstream m_assembly; - int m_labelCounter; - std::unordered_map m_variableAddresses; - int m_currentStackOffset; - - std::string GenerateUniqueLabel(const std::string& prefix) { - return prefix + "_" + std::to_string(m_labelCounter++); - } - - void GenerateNodeCode(std::shared_ptr node) { - if (!node) return; - - if (node->IsType()) { - // Generate code for function entry - m_assembly << " ; Function Entry\n"; - for (auto& child : node->children) { - GenerateNodeCode(child); - } - } - else if (node->IsType()) { - GenerateBranchCode(node); - } - else if (node->IsType()) { - GeneratePrintCode(node); - } - else if (node->IsType()) { - GenerateVariableCode(node); - } - else if (node->IsType()) { - GenerateOperatorCode(node); - } - } - - void GenerateBranchCode(std::shared_ptr node) { - std::string labelTrue = GenerateUniqueLabel("true"); - std::string labelFalse = GenerateUniqueLabel("false"); - std::string labelEnd = GenerateUniqueLabel("end"); - - m_assembly << " ; Branch condition evaluation\n"; - - // Generate condition code - if (auto conditionNode = node->GetDataInput(0)) { - GenerateNodeCode(conditionNode); - } - - m_assembly << " pop eax\n"; - m_assembly << " cmp eax, 0\n"; - m_assembly << " je " << labelFalse << "\n"; - - // True branch - m_assembly << labelTrue << ":\n"; - if (node->GetChildCount() > 0) { - GenerateNodeCode(node->GetChild(0)); - } - m_assembly << " jmp " << labelEnd << "\n"; - - // False branch - m_assembly << labelFalse << ":\n"; - if (node->GetChildCount() > 1) { - GenerateNodeCode(node->GetChild(1)); - } - - m_assembly << labelEnd << ":\n"; - } - - void GeneratePrintCode(std::shared_ptr node) { - auto* printNode = node->GetAs(); - if (!printNode) return; - - m_assembly << " ; Print message\n"; - if (printNode->GetText() == "Good!") { - m_assembly << " mov edx, 6\n"; // message length - m_assembly << " mov ecx, msg_good\n"; - } else { - m_assembly << " mov edx, 6\n"; // message length - m_assembly << " mov ecx, msg_bad\n"; - } - m_assembly << " mov ebx, 1\n"; // file descriptor (stdout) - m_assembly << " mov eax, 4\n"; // sys_write - m_assembly << " int 0x80\n"; - } - - void GenerateVariableCode(std::shared_ptr node) { - auto* varNode = node->GetAs(); - if (!varNode) return; - - // For this example, we'll just push a value onto the stack - std::string varName = varNode->GetVariableName(); - if (m_variableAddresses.find(varName) == m_variableAddresses.end()) { - m_variableAddresses[varName] = m_currentStackOffset; - m_currentStackOffset += 4; - } - - m_assembly << " ; Load variable " << varName << "\n"; - m_assembly << " mov eax, [ebp-" << m_variableAddresses[varName] << "]\n"; - m_assembly << " push eax\n"; - } - - void GenerateOperatorCode(std::shared_ptr node) { - auto* opNode = node->GetAs(); - if (!opNode) return; - - // Generate code for operands - for (const auto& [port, inputNode] : node->dataInputs) { - GenerateNodeCode(inputNode); - } - - m_assembly << " ; Operator " << static_cast(opNode->GetOperationType()) << "\n"; - - switch (opNode->GetOperationType()) { - case OperatorNode::ADD: - m_assembly << " pop ebx\n"; - m_assembly << " pop eax\n"; - m_assembly << " add eax, ebx\n"; - m_assembly << " push eax\n"; - break; - case OperatorNode::SUBTRACT: - m_assembly << " pop ebx\n"; - m_assembly << " pop eax\n"; - m_assembly << " sub eax, ebx\n"; - m_assembly << " push eax\n"; - break; - // Add other operators... - } - } - }; - -*/ -/* - -// Générer des labels uniques pour les nœuds - for (const auto& nodePair : m_ast.nodeMap) { - std::string label = m_ast.generateLabel(m_ast); - labels[nodePair.first] = label; - - // Générer du code pour chaque type de nœud - std::string nodeType = nodePair.second->node->GetTypeName(); - if (nodeType == "LOOP") { - // Générer du code pour une boucle - assemblyCode += " ; Loop start\n"; - // Ajouter des instructions pour la condition de la boucle - if (nodePair.second->condition) { - assemblyCode += " cmp_eq r0, " + labels[nodePair.second->condition->node->GetId()] + ", 0\n"; - assemblyCode += " skipz r0\n"; - assemblyCode += " jump " + labels[nodePair.second->body.front()->node->GetId()] + "\n"; - } - // Ajouter des instructions pour le corps de la boucle - for (const auto& bodyNode : nodePair.second->body) { - assemblyCode += " ; Loop body\n"; - // Ajouter des instructions pour chaque nœud du corps - } - assemblyCode += " jump " + label + "\n"; // Retour au début de la boucle - } else if (nodeType == "BRANCH") { - // Générer du code pour un branchement - assemblyCode += " ; Branch start\n"; - // Ajouter des instructions pour la condition du branchement - if (nodePair.second->condition) { - assemblyCode += " cmp_eq r0, " + labels[nodePair.second->condition->node->GetId()] + ", 0\n"; - assemblyCode += " skipnz r0\n"; - assemblyCode += " jump " + labels[nodePair.second->body.front()->node->GetId()] + "\n"; - } - // Ajouter des instructions pour le corps du branchement - for (const auto& bodyNode : nodePair.second->body) { - assemblyCode += " ; Branch body\n"; - // Ajouter des instructions pour chaque nœud du corps - } - // Ajouter des instructions pour le corps du else - if (nodePair.second->elseBody) { - assemblyCode += " ; Else body\n"; - // Ajouter des instructions pour chaque nœud du corps du else - } - } else { - // Générer du code pour d'autres types de nœuds - assemblyCode += " ; Other node type: " + nodeType + "\n"; - assemblyCode += nodePair.second->node->GenerateAssembly(); - - // Ajouter des instructions spécifiques au type de nœud - } - } - - - - -*/ - diff --git a/core/story-manager/src/nodes/print_node.cpp b/core/story-manager/src/nodes/print_node.cpp index 06e394f..35b0523 100644 --- a/core/story-manager/src/nodes/print_node.cpp +++ b/core/story-manager/src/nodes/print_node.cpp @@ -32,7 +32,7 @@ void PrintNode::Initialize() void PrintNode::SetText(const std::string &text) { - m_variables.at(m_label)->SetValue(text); + m_variables.at(m_label)->SetTextValue(text); SetInternalData({{"text", text}}); } diff --git a/core/story-manager/tests/CMakeLists.txt b/core/story-manager/tests/CMakeLists.txt deleted file mode 100644 index 42c3760..0000000 --- a/core/story-manager/tests/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -cmake_minimum_required(VERSION 3.5) - -project(compiler_test LANGUAGES CXX C) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -add_executable(${PROJECT_NAME} - main.cpp - test_ast.cpp - - - ../src/nodes/base_node.cpp - ../src/nodes/branch_node.cpp - ../src/nodes/print_node.cpp - ../src/nodes/variable_node.cpp - ../src/nodes/syscall_node.cpp - ../src/nodes/connection.cpp - - ../../chip32/chip32_assembler.cpp - ../../chip32/chip32_vm.c -) - -target_include_directories(${PROJECT_NAME} PRIVATE - ../../chip32 - ../src - ../interfaces - ../lib - ../../../shared - ../src/nodes - ../src/compiler -) diff --git a/core/story-manager/tests/catch.hpp b/core/story-manager/tests/catch.hpp deleted file mode 100644 index db1fed3..0000000 --- a/core/story-manager/tests/catch.hpp +++ /dev/null @@ -1,17966 +0,0 @@ -/* - * Catch v2.13.8 - * Generated: 2022-01-03 21:20:09.589503 - * ---------------------------------------------------------- - * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. - * - * Distributed under the Boost Software License, Version 1.0. (See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -// start catch.hpp - - -#define CATCH_VERSION_MAJOR 2 -#define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 8 - -#ifdef __clang__ -# pragma clang system_header -#elif defined __GNUC__ -# pragma GCC system_header -#endif - -// start catch_suppress_warnings.h - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(push) -# pragma warning(disable: 161 1682) -# else // __ICC -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wswitch-enum" -# pragma clang diagnostic ignored "-Wcovered-switch-default" -# endif -#elif defined __GNUC__ - // Because REQUIREs trigger GCC's -Wparentheses, and because still - // supported version of g++ have only buggy support for _Pragmas, - // Wparentheses have to be suppressed globally. -# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details - -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic ignored "-Wpadded" -#endif -// end catch_suppress_warnings.h -#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) -# define CATCH_IMPL -# define CATCH_CONFIG_ALL_PARTS -#endif - -// In the impl file, we want to have access to all parts of the headers -// Can also be used to sanely support PCHs -#if defined(CATCH_CONFIG_ALL_PARTS) -# define CATCH_CONFIG_EXTERNAL_INTERFACES -# if defined(CATCH_CONFIG_DISABLE_MATCHERS) -# undef CATCH_CONFIG_DISABLE_MATCHERS -# endif -# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) -# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER -# endif -#endif - -#if !defined(CATCH_CONFIG_IMPL_ONLY) -// start catch_platform.h - -// See e.g.: -// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html -#ifdef __APPLE__ -# include -# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ - (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) -# define CATCH_PLATFORM_MAC -# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) -# define CATCH_PLATFORM_IPHONE -# endif - -#elif defined(linux) || defined(__linux) || defined(__linux__) -# define CATCH_PLATFORM_LINUX - -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) -# define CATCH_PLATFORM_WINDOWS -#endif - -// end catch_platform.h - -#ifdef CATCH_IMPL -# ifndef CLARA_CONFIG_MAIN -# define CLARA_CONFIG_MAIN_NOT_DEFINED -# define CLARA_CONFIG_MAIN -# endif -#endif - -// start catch_user_interfaces.h - -namespace Catch { - unsigned int rngSeed(); -} - -// end catch_user_interfaces.h -// start catch_tag_alias_autoregistrar.h - -// start catch_common.h - -// start catch_compiler_capabilities.h - -// Detect a number of compiler features - by compiler -// The following features are defined: -// -// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? -// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? -// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? -// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? -// **************** -// Note to maintainers: if new toggles are added please document them -// in configuration.md, too -// **************** - -// In general each macro has a _NO_ form -// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. -// Many features, at point of detection, define an _INTERNAL_ macro, so they -// can be combined, en-mass, with the _NO_ forms later. - -#ifdef __cplusplus - -# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) -# define CATCH_CPP14_OR_GREATER -# endif - -# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -# define CATCH_CPP17_OR_GREATER -# endif - -#endif - -// Only GCC compiler should be used in this block, so other compilers trying to -// mask themselves as GCC should be ignored. -#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) - -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) - -#endif - -#if defined(__clang__) - -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) - -// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug -// which results in calls to destructors being emitted for each temporary, -// without a matching initialization. In practice, this can result in something -// like `std::string::~string` being called on an uninitialized value. -// -// For example, this code will likely segfault under IBM XL: -// ``` -// REQUIRE(std::string("12") + "34" == "1234") -// ``` -// -// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. -# if !defined(__ibmxl__) && !defined(__CUDACC__) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ -# endif - -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ - _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") - -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) - -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) - -#endif // __clang__ - -//////////////////////////////////////////////////////////////////////////////// -// Assume that non-Windows platforms support posix signals by default -#if !defined(CATCH_PLATFORM_WINDOWS) - #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS -#endif - -//////////////////////////////////////////////////////////////////////////////// -// We know some environments not to support full POSIX signals -#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) - #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -#endif - -#ifdef __OS400__ -# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -# define CATCH_CONFIG_COLOUR_NONE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Android somehow still does not support std::to_string -#if defined(__ANDROID__) -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING -# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Not all Windows environments support SEH properly -#if defined(__MINGW32__) -# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH -#endif - -//////////////////////////////////////////////////////////////////////////////// -// PS4 -#if defined(__ORBIS__) -# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Cygwin -#ifdef __CYGWIN__ - -// Required for some versions of Cygwin to declare gettimeofday -// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin -# define _BSD_SOURCE -// some versions of cygwin (most) do not support std::to_string. Use the libstd check. -// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 -# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ - && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) - -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING - -# endif -#endif // __CYGWIN__ - -//////////////////////////////////////////////////////////////////////////////// -// Visual C++ -#if defined(_MSC_VER) - -// Universal Windows platform does not support SEH -// Or console colours (or console at all...) -# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) -# define CATCH_CONFIG_COLOUR_NONE -# else -# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH -# endif - -# if !defined(__clang__) // Handle Clang masquerading for msvc - -// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ -// _MSVC_TRADITIONAL == 0 means new conformant preprocessor -// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) -# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -# endif // MSVC_TRADITIONAL - -// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) -# endif // __clang__ - -#endif // _MSC_VER - -#if defined(_REENTRANT) || defined(_MSC_VER) -// Enable async processing, as -pthread is specified or no additional linking is required -# define CATCH_INTERNAL_CONFIG_USE_ASYNC -#endif // _MSC_VER - -//////////////////////////////////////////////////////////////////////////////// -// Check if we are compiled with -fno-exceptions or equivalent -#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) -# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED -#endif - -//////////////////////////////////////////////////////////////////////////////// -// DJGPP -#ifdef __DJGPP__ -# define CATCH_INTERNAL_CONFIG_NO_WCHAR -#endif // __DJGPP__ - -//////////////////////////////////////////////////////////////////////////////// -// Embarcadero C++Build -#if defined(__BORLANDC__) - #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// Use of __COUNTER__ is suppressed during code analysis in -// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly -// handled by it. -// Otherwise all supported compilers support COUNTER macro, -// but user still might want to turn it off -#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) - #define CATCH_INTERNAL_CONFIG_COUNTER -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// RTX is a special version of Windows that is real time. -// This means that it is detected as Windows, but does not provide -// the same set of capabilities as real Windows does. -#if defined(UNDER_RTSS) || defined(RTX64_BUILD) - #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH - #define CATCH_INTERNAL_CONFIG_NO_ASYNC - #define CATCH_CONFIG_COLOUR_NONE -#endif - -#if !defined(_GLIBCXX_USE_C99_MATH_TR1) -#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER -#endif - -// Various stdlib support checks that require __has_include -#if defined(__has_include) - // Check if string_view is available and usable - #if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW - #endif - - // Check if optional is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - - // Check if byte is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # include - # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) - # define CATCH_INTERNAL_CONFIG_CPP17_BYTE - # endif - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - - // Check if variant is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # if defined(__clang__) && (__clang_major__ < 8) - // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 - // fix should be in clang 8, workaround in libstdc++ 8.2 - # include - # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) - # define CATCH_CONFIG_NO_CPP17_VARIANT - # else - # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT - # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) - # else - # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT - # endif // defined(__clang__) && (__clang_major__ < 8) - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) -#endif // defined(__has_include) - -#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) -# define CATCH_CONFIG_COUNTER -#endif -#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) -# define CATCH_CONFIG_WINDOWS_SEH -#endif -// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. -#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_CONFIG_POSIX_SIGNALS -#endif -// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. -#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) -# define CATCH_CONFIG_WCHAR -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) -# define CATCH_CONFIG_CPP11_TO_STRING -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) -# define CATCH_CONFIG_CPP17_OPTIONAL -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) -# define CATCH_CONFIG_CPP17_STRING_VIEW -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) -# define CATCH_CONFIG_CPP17_VARIANT -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) -# define CATCH_CONFIG_CPP17_BYTE -#endif - -#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) -# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE -#endif - -#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) -# define CATCH_CONFIG_NEW_CAPTURE -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -# define CATCH_CONFIG_DISABLE_EXCEPTIONS -#endif - -#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) -# define CATCH_CONFIG_POLYFILL_ISNAN -#endif - -#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) -# define CATCH_CONFIG_USE_ASYNC -#endif - -#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) -# define CATCH_CONFIG_ANDROID_LOGWRITE -#endif - -#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) -# define CATCH_CONFIG_GLOBAL_NEXTAFTER -#endif - -// Even if we do not think the compiler has that warning, we still have -// to provide a macro that can be used by the code. -#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION -#endif -#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS -#endif - -// The goal of this macro is to avoid evaluation of the arguments, but -// still have the compiler warn on problems inside... -#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) -#endif - -#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) -# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#elif defined(__clang__) && (__clang_major__ < 5) -# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#endif - -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#endif - -#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -#define CATCH_TRY if ((true)) -#define CATCH_CATCH_ALL if ((false)) -#define CATCH_CATCH_ANON(type) if ((false)) -#else -#define CATCH_TRY try -#define CATCH_CATCH_ALL catch (...) -#define CATCH_CATCH_ANON(type) catch (type) -#endif - -#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) -#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#endif - -// end catch_compiler_capabilities.h -#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line -#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) -#ifdef CATCH_CONFIG_COUNTER -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) -#else -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) -#endif - -#include -#include -#include - -// We need a dummy global operator<< so we can bring it into Catch namespace later -struct Catch_global_namespace_dummy {}; -std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); - -namespace Catch { - - struct CaseSensitive { enum Choice { - Yes, - No - }; }; - - class NonCopyable { - NonCopyable( NonCopyable const& ) = delete; - NonCopyable( NonCopyable && ) = delete; - NonCopyable& operator = ( NonCopyable const& ) = delete; - NonCopyable& operator = ( NonCopyable && ) = delete; - - protected: - NonCopyable(); - virtual ~NonCopyable(); - }; - - struct SourceLineInfo { - - SourceLineInfo() = delete; - SourceLineInfo( char const* _file, std::size_t _line ) noexcept - : file( _file ), - line( _line ) - {} - - SourceLineInfo( SourceLineInfo const& other ) = default; - SourceLineInfo& operator = ( SourceLineInfo const& ) = default; - SourceLineInfo( SourceLineInfo&& ) noexcept = default; - SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; - - bool empty() const noexcept { return file[0] == '\0'; } - bool operator == ( SourceLineInfo const& other ) const noexcept; - bool operator < ( SourceLineInfo const& other ) const noexcept; - - char const* file; - std::size_t line; - }; - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); - - // Bring in operator<< from global namespace into Catch namespace - // This is necessary because the overload of operator<< above makes - // lookup stop at namespace Catch - using ::operator<<; - - // Use this in variadic streaming macros to allow - // >> +StreamEndStop - // as well as - // >> stuff +StreamEndStop - struct StreamEndStop { - std::string operator+() const; - }; - template - T const& operator + ( T const& value, StreamEndStop ) { - return value; - } -} - -#define CATCH_INTERNAL_LINEINFO \ - ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) - -// end catch_common.h -namespace Catch { - - struct RegistrarForTagAliases { - RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); - }; - -} // end namespace Catch - -#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ - CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ - CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION - -// end catch_tag_alias_autoregistrar.h -// start catch_test_registry.h - -// start catch_interfaces_testcase.h - -#include - -namespace Catch { - - class TestSpec; - - struct ITestInvoker { - virtual void invoke () const = 0; - virtual ~ITestInvoker(); - }; - - class TestCase; - struct IConfig; - - struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(); - virtual std::vector const& getAllTests() const = 0; - virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; - }; - - bool isThrowSafe( TestCase const& testCase, IConfig const& config ); - bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); - std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); - std::vector const& getAllTestCasesSorted( IConfig const& config ); - -} - -// end catch_interfaces_testcase.h -// start catch_stringref.h - -#include -#include -#include -#include - -namespace Catch { - - /// A non-owning string class (similar to the forthcoming std::string_view) - /// Note that, because a StringRef may be a substring of another string, - /// it may not be null terminated. - class StringRef { - public: - using size_type = std::size_t; - using const_iterator = const char*; - - private: - static constexpr char const* const s_empty = ""; - - char const* m_start = s_empty; - size_type m_size = 0; - - public: // construction - constexpr StringRef() noexcept = default; - - StringRef( char const* rawChars ) noexcept; - - constexpr StringRef( char const* rawChars, size_type size ) noexcept - : m_start( rawChars ), - m_size( size ) - {} - - StringRef( std::string const& stdString ) noexcept - : m_start( stdString.c_str() ), - m_size( stdString.size() ) - {} - - explicit operator std::string() const { - return std::string(m_start, m_size); - } - - public: // operators - auto operator == ( StringRef const& other ) const noexcept -> bool; - auto operator != (StringRef const& other) const noexcept -> bool { - return !(*this == other); - } - - auto operator[] ( size_type index ) const noexcept -> char { - assert(index < m_size); - return m_start[index]; - } - - public: // named queries - constexpr auto empty() const noexcept -> bool { - return m_size == 0; - } - constexpr auto size() const noexcept -> size_type { - return m_size; - } - - // Returns the current start pointer. If the StringRef is not - // null-terminated, throws std::domain_exception - auto c_str() const -> char const*; - - public: // substrings and searches - // Returns a substring of [start, start + length). - // If start + length > size(), then the substring is [start, size()). - // If start > size(), then the substring is empty. - auto substr( size_type start, size_type length ) const noexcept -> StringRef; - - // Returns the current start pointer. May not be null-terminated. - auto data() const noexcept -> char const*; - - constexpr auto isNullTerminated() const noexcept -> bool { - return m_start[m_size] == '\0'; - } - - public: // iterators - constexpr const_iterator begin() const { return m_start; } - constexpr const_iterator end() const { return m_start + m_size; } - }; - - auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; - auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; - - constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { - return StringRef( rawChars, size ); - } -} // namespace Catch - -constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { - return Catch::StringRef( rawChars, size ); -} - -// end catch_stringref.h -// start catch_preprocessor.hpp - - -#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ -#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) - -#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ -// MSVC needs more evaluations -#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) -#else -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) -#endif - -#define CATCH_REC_END(...) -#define CATCH_REC_OUT - -#define CATCH_EMPTY() -#define CATCH_DEFER(id) id CATCH_EMPTY() - -#define CATCH_REC_GET_END2() 0, CATCH_REC_END -#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 -#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 -#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT -#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) -#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) - -#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) - -#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) - -// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, -// and passes userdata as the first parameter to each invocation, -// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) -#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) -#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ -#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ -#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF -#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) -#else -// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF -#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) -#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) -#endif - -#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ -#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) - -#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) - -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) -#else -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) -#endif - -#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ - CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) - -#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) -#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) -#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) -#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) -#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) -#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) -#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) -#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) -#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) -#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) -#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) - -#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N - -#define INTERNAL_CATCH_TYPE_GEN\ - template struct TypeList {};\ - template\ - constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ - template class...> struct TemplateTypeList{};\ - template class...Cs>\ - constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ - template\ - struct append;\ - template\ - struct rewrap;\ - template class, typename...>\ - struct create;\ - template class, typename>\ - struct convert;\ - \ - template \ - struct append { using type = T; };\ - template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ - struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ - template< template class L1, typename...E1, typename...Rest>\ - struct append, TypeList, Rest...> { using type = L1; };\ - \ - template< template class Container, template class List, typename...elems>\ - struct rewrap, List> { using type = TypeList>; };\ - template< template class Container, template class List, class...Elems, typename...Elements>\ - struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ - \ - template