Add Tests for ZCG cpp

This commit is contained in:
Jan
2021-02-10 18:03:50 +01:00
parent 31497d804c
commit f9ef7cc35b
102 changed files with 502 additions and 21 deletions

View File

@ -0,0 +1,26 @@
#pragma once
#include "Utils/ClassUtils.h"
enum class EvaluationType
{
OPERAND_DYNAMIC,
OPERAND_STATIC,
OPERATION
};
class IEvaluation
{
public:
IEvaluation() = default;
virtual ~IEvaluation() = default;
IEvaluation(const IEvaluation& other) = default;
IEvaluation(IEvaluation&& other) noexcept = default;
IEvaluation& operator=(const IEvaluation& other) = default;
IEvaluation& operator=(IEvaluation&& other) noexcept = default;
_NODISCARD virtual EvaluationType GetType() const = 0;
_NODISCARD virtual bool IsStatic() const = 0;
_NODISCARD virtual int EvaluateNumeric() const = 0;
};

View File

@ -0,0 +1,24 @@
#include "OperandDynamic.h"
#include <cassert>
OperandDynamic::OperandDynamic(StructureInformation* structure)
: m_structure(structure)
{
}
EvaluationType OperandDynamic::GetType() const
{
return EvaluationType::OPERAND_DYNAMIC;
}
bool OperandDynamic::IsStatic() const
{
return false;
}
int OperandDynamic::EvaluateNumeric() const
{
assert(false);
return 0;
}

View File

@ -0,0 +1,21 @@
#pragma once
#include <memory>
#include <vector>
#include "IEvaluation.h"
#include "Domain/Information/MemberInformation.h"
#include "Domain/Information/StructureInformation.h"
class OperandDynamic final : public IEvaluation
{
public:
StructureInformation* const m_structure;
std::vector<MemberInformation*> m_referenced_member_chain;
std::vector<std::unique_ptr<IEvaluation>> m_array_indices;
explicit OperandDynamic(StructureInformation* structure);
_NODISCARD EvaluationType GetType() const override;
_NODISCARD bool IsStatic() const override;
_NODISCARD int EvaluateNumeric() const override;
};

View File

@ -0,0 +1,28 @@
#include "OperandStatic.h"
OperandStatic::OperandStatic(const int value)
: m_value(value),
m_enum_member(nullptr)
{
}
OperandStatic::OperandStatic(const int value, EnumMember* enumMember)
: m_value(value),
m_enum_member(enumMember)
{
}
EvaluationType OperandStatic::GetType() const
{
return EvaluationType::OPERAND_STATIC;
}
bool OperandStatic::IsStatic() const
{
return true;
}
int OperandStatic::EvaluateNumeric() const
{
return m_value;
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "IEvaluation.h"
#include "Domain/Definition/EnumMember.h"
class OperandStatic final : public IEvaluation
{
public:
const int m_value;
EnumMember* const m_enum_member;
explicit OperandStatic(int value);
OperandStatic(int value, EnumMember* enumMember);
_NODISCARD EvaluationType GetType() const override;
_NODISCARD bool IsStatic() const override;
_NODISCARD int EvaluateNumeric() const override;
};

View File

@ -0,0 +1,33 @@
#include "Operation.h"
Operation::Operation(const OperationType* type)
: m_operation_type(type)
{
}
EvaluationType Operation::GetType() const
{
return EvaluationType::OPERATION;
}
bool Operation::IsStatic() const
{
return m_operand1->IsStatic() && m_operand2->IsStatic();
}
int Operation::EvaluateNumeric() const
{
return m_operation_type->m_evaluation_function(m_operand1->EvaluateNumeric(), m_operand2->EvaluateNumeric());
}
bool Operation::Operand1NeedsParenthesis() const
{
return m_operand1->GetType() == EvaluationType::OPERATION
&& dynamic_cast<Operation*>(m_operand1.get())->m_operation_type->m_precedence > m_operation_type->m_precedence;
}
bool Operation::Operand2NeedsParenthesis() const
{
return m_operand2->GetType() == EvaluationType::OPERATION
&& dynamic_cast<Operation*>(m_operand2.get())->m_operation_type->m_precedence > m_operation_type->m_precedence;
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <memory>
#include "Utils/ClassUtils.h"
#include "IEvaluation.h"
#include "OperationType.h"
class Operation final : public IEvaluation
{
public:
const OperationType* const m_operation_type;
std::unique_ptr<IEvaluation> m_operand1;
std::unique_ptr<IEvaluation> m_operand2;
explicit Operation(const OperationType* type);
_NODISCARD EvaluationType GetType() const override;
_NODISCARD bool IsStatic() const override;
_NODISCARD int EvaluateNumeric() const override;
_NODISCARD bool Operand1NeedsParenthesis() const;
_NODISCARD bool Operand2NeedsParenthesis() const;
};

View File

@ -0,0 +1,139 @@
#include "OperationType.h"
OperationType::OperationType(std::string syntax, const OperationPrecedence precedence, std::function<int(int, int)> evaluationFunction)
: m_syntax(std::move(syntax)),
m_precedence(precedence),
m_evaluation_function(std::move(evaluationFunction))
{
}
const OperationType* const OperationType::OPERATION_ADD
= new OperationType("+", OperationPrecedence::ADDITION_SUBTRACTION, [](auto op1, auto op2)
{
return op1 + op2;
});
const OperationType* const OperationType::OPERATION_SUBTRACT
= new OperationType("-", OperationPrecedence::ADDITION_SUBTRACTION, [](auto op1, auto op2)
{
return op1 - op2;
});
const OperationType* const OperationType::OPERATION_MULTIPLY
= new OperationType("*", OperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, [](auto op1, auto op2)
{
return op1 * op2;
});
const OperationType* const OperationType::OPERATION_DIVIDE
= new OperationType("/", OperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, [](auto op1, auto op2)
{
return op1 / op2;
});
const OperationType* const OperationType::OPERATION_REMAINDER
= new OperationType("%", OperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, [](auto op1, auto op2)
{
return op1 % op2;
});
const OperationType* const OperationType::OPERATION_BITWISE_AND
= new OperationType("&", OperationPrecedence::BITWISE_AND, [](auto op1, auto op2)
{
return op1 & op2;
});
const OperationType* const OperationType::OPERATION_BITWISE_XOR
= new OperationType("^", OperationPrecedence::BITWISE_XOR, [](auto op1, auto op2)
{
return op1 ^ op2;
});
const OperationType* const OperationType::OPERATION_BITWISE_OR
= new OperationType("|", OperationPrecedence::BITWISE_OR, [](auto op1, auto op2)
{
return op1 | op2;
});
const OperationType* const OperationType::OPERATION_SHIFT_LEFT
= new OperationType("<<", OperationPrecedence::BITWISE_SHIFT, [](auto op1, auto op2)
{
return op1 << op2;
});
const OperationType* const OperationType::OPERATION_SHIFT_RIGHT
= new OperationType(">>", OperationPrecedence::BITWISE_SHIFT, [](auto op1, auto op2)
{
return op1 >> op2;
});
const OperationType* const OperationType::OPERATION_GREATER_THAN
= new OperationType(">", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
{
return op1 > op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_GREATER_EQUALS_THAN
= new OperationType(">=", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
{
return op1 >= op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_LESS_THAN
= new OperationType("<", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
{
return op1 < op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_LESS_EQUALS_THAN
= new OperationType("<=", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
{
return op1 <= op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_EQUALS
= new OperationType("==", OperationPrecedence::RELATIONAL_EQUALS, [](auto op1, auto op2)
{
return op1 == op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_NOT_EQUALS
= new OperationType("!=", OperationPrecedence::RELATIONAL_EQUALS, [](auto op1, auto op2)
{
return op1 != op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_AND
= new OperationType("&&", OperationPrecedence::LOGICAL_AND, [](auto op1, auto op2)
{
return op1 > 0 && op2 > 0 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_OR
= new OperationType("||", OperationPrecedence::LOGICAL_OR, [](auto op1, auto op2)
{
return op1 > 0 || op2 > 0 ? 1 : 0;
});
const OperationType* const OperationType::ALL_OPERATION_TYPES[]
{
OPERATION_ADD,
OPERATION_SUBTRACT,
OPERATION_MULTIPLY,
OPERATION_DIVIDE,
OPERATION_REMAINDER,
OPERATION_BITWISE_AND,
OPERATION_BITWISE_XOR,
OPERATION_BITWISE_OR,
OPERATION_SHIFT_LEFT,
OPERATION_SHIFT_RIGHT,
OPERATION_GREATER_THAN,
OPERATION_GREATER_EQUALS_THAN,
OPERATION_LESS_THAN,
OPERATION_LESS_EQUALS_THAN,
OPERATION_EQUALS,
OPERATION_NOT_EQUALS,
OPERATION_AND,
OPERATION_OR
};

View File

@ -0,0 +1,52 @@
#pragma once
#include <functional>
#include <string>
// https://en.cppreference.com/w/cpp/language/operator_precedence
enum class OperationPrecedence
{
MULTIPLICATION_DIVISION_REMAINDER = 1,
ADDITION_SUBTRACTION = 2,
BITWISE_SHIFT = 3,
RELATIONAL_GREATER_LESS_THAN = 4,
RELATIONAL_EQUALS = 5,
BITWISE_AND = 6,
BITWISE_XOR = 7,
BITWISE_OR = 8,
LOGICAL_AND = 9,
LOGICAL_OR = 10
};
class OperationType
{
public:
std::string m_syntax;
OperationPrecedence m_precedence;
std::function<int(int operand1, int operand2)> m_evaluation_function;
private:
OperationType(std::string syntax, OperationPrecedence precedence, std::function<int(int, int)> evaluationFunction);
public:
static const OperationType* const OPERATION_ADD;
static const OperationType* const OPERATION_SUBTRACT;
static const OperationType* const OPERATION_MULTIPLY;
static const OperationType* const OPERATION_DIVIDE;
static const OperationType* const OPERATION_REMAINDER;
static const OperationType* const OPERATION_BITWISE_AND;
static const OperationType* const OPERATION_BITWISE_XOR;
static const OperationType* const OPERATION_BITWISE_OR;
static const OperationType* const OPERATION_SHIFT_LEFT;
static const OperationType* const OPERATION_SHIFT_RIGHT;
static const OperationType* const OPERATION_GREATER_THAN;
static const OperationType* const OPERATION_GREATER_EQUALS_THAN;
static const OperationType* const OPERATION_LESS_THAN;
static const OperationType* const OPERATION_LESS_EQUALS_THAN;
static const OperationType* const OPERATION_EQUALS;
static const OperationType* const OPERATION_NOT_EQUALS;
static const OperationType* const OPERATION_AND;
static const OperationType* const OPERATION_OR;
static const OperationType* const ALL_OPERATION_TYPES[];
};