Version 2 Release!
- Added GUI - Added Evaluation - Added Recursive brackets support - Added Two way evaluation - Added ExprTreeReveresed - Fixed bracket matching - Fixed Log - Fixed Error Reporting
This commit is contained in:
parent
818d12fcf2
commit
b76971ad82
|
@ -2,4 +2,5 @@
|
|||
|
||||
bin-int/
|
||||
bin/
|
||||
x64/
|
||||
x64/
|
||||
release/
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
10
QuicMaf.sln
10
QuicMaf.sln
|
@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.28307.329
|
|||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuicMaf", "QuicMaf\QuicMaf.vcxproj", "{EA73D661-B6EB-4156-AC92-A470A6683307}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuicMafGui", "QuicMafGui\QuicMafGui.vcxproj", "{7CDC5570-9785-446C-8CB9-C03E6D98927F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
|
@ -21,6 +23,14 @@ Global
|
|||
{EA73D661-B6EB-4156-AC92-A470A6683307}.Release|x64.Build.0 = Release|x64
|
||||
{EA73D661-B6EB-4156-AC92-A470A6683307}.Release|x86.ActiveCfg = Release|Win32
|
||||
{EA73D661-B6EB-4156-AC92-A470A6683307}.Release|x86.Build.0 = Release|Win32
|
||||
{7CDC5570-9785-446C-8CB9-C03E6D98927F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7CDC5570-9785-446C-8CB9-C03E6D98927F}.Debug|x64.Build.0 = Debug|x64
|
||||
{7CDC5570-9785-446C-8CB9-C03E6D98927F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{7CDC5570-9785-446C-8CB9-C03E6D98927F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{7CDC5570-9785-446C-8CB9-C03E6D98927F}.Release|x64.ActiveCfg = Release|x64
|
||||
{7CDC5570-9785-446C-8CB9-C03E6D98927F}.Release|x64.Build.0 = Release|x64
|
||||
{7CDC5570-9785-446C-8CB9-C03E6D98927F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{7CDC5570-9785-446C-8CB9-C03E6D98927F}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* File: Log.h
|
||||
* Author: Alberto Lepe <dev@alepe.com>
|
||||
* Edited By: Ayham Mamoun <ayhamaboualfadl@gmail.com>
|
||||
*
|
||||
* Created on December 1, 2015, 6:00 PM
|
||||
*/
|
||||
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class LOG {
|
||||
public:
|
||||
vector<string>* qm_log = new vector<string>();
|
||||
LOG() {}
|
||||
LOG &operator<<(const string &msg) {
|
||||
qm_log->push_back(msg);
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
};
|
||||
|
||||
#endif /* LOG_H */
|
|
@ -26,26 +26,26 @@
|
|||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
|
@ -70,8 +70,24 @@
|
|||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)bin\$(Configuration)-$(Platform)\</OutDir>
|
||||
<IntDir>$(SolutionDir)bin-int\$(Configuration)-$(Platform)\</IntDir>
|
||||
<OutDir>$(SolutionDir)bin/$(Configuration)-$(Platform)/</OutDir>
|
||||
<IntDir>$(SolutionDir)bin-int/$(Configuration)-$(Platform)/</IntDir>
|
||||
<IncludePath>$(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)bin/$(Configuration)-$(Platform)/</OutDir>
|
||||
<IntDir>$(SolutionDir)bin-int/$(Configuration)-$(Platform)/</IntDir>
|
||||
<IncludePath>$(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)bin/$(Configuration)-$(Platform)/</OutDir>
|
||||
<IntDir>$(SolutionDir)bin-int/$(Configuration)-$(Platform)/</IntDir>
|
||||
<IncludePath>$(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)bin/$(Configuration)-$(Platform)/</OutDir>
|
||||
<IntDir>$(SolutionDir)bin-int/$(Configuration)-$(Platform)/</IntDir>
|
||||
<IncludePath>$(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -79,6 +95,7 @@
|
|||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -87,6 +104,7 @@
|
|||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -97,6 +115,7 @@
|
|||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
|
@ -111,6 +130,7 @@
|
|||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
|
@ -126,6 +146,7 @@
|
|||
<ClCompile Include="maths\solver\term_rewriter\ds\TermPool.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Log.h" />
|
||||
<ClInclude Include="maths\solver\term_rewriter\ds\ExprTree.h" />
|
||||
<ClInclude Include="maths\defines.h" />
|
||||
<ClInclude Include="maths\Equations.h" />
|
||||
|
@ -144,6 +165,7 @@
|
|||
<ClInclude Include="maths\solver\Solver.h" />
|
||||
<ClInclude Include="maths\solver\term_rewriter\QMEvaluator.h" />
|
||||
<ClInclude Include="maths\solver\term_rewriter\ds\TermPool.h" />
|
||||
<ClInclude Include="qm.h" />
|
||||
<ClInclude Include="vendor\lexertk.hpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
@ -92,5 +92,11 @@
|
|||
<ClInclude Include="maths\solver\term_rewriter\QMEvalHelper.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="qm.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Log.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -13,9 +13,10 @@
|
|||
|
||||
#include "maths/solver/term_rewriter/ds/ExprTree.h"
|
||||
|
||||
#define MAIN_APP
|
||||
//#define APP_TEST
|
||||
#include "Log.h"
|
||||
|
||||
//#define MAIN_APP
|
||||
//#define APP_TEST
|
||||
|
||||
#ifdef MAIN_APP
|
||||
|
||||
|
@ -31,6 +32,7 @@ int main() {
|
|||
cout << "Solution: " << endl;
|
||||
|
||||
Solver solver;
|
||||
solver.CheckEqu(input);
|
||||
solver.Parse(input);
|
||||
solver.Solve();
|
||||
|
||||
|
@ -54,24 +56,6 @@ int main() {
|
|||
#ifdef APP_TEST
|
||||
|
||||
int main() {
|
||||
lexertk::generator lexer;
|
||||
lexer.process("12341-(2x+3)");
|
||||
|
||||
auto result = tokenize(lexer);
|
||||
|
||||
Solver solver;
|
||||
solver.Parse("4+3=4x+6");
|
||||
solver.Solve();
|
||||
|
||||
for (auto *lwing : solver.mEquation->lwing)
|
||||
cout << lwing->to_str();
|
||||
cout << "=";
|
||||
for (auto *rwing : solver.mEquation->rwing)
|
||||
cout << rwing->to_str();
|
||||
|
||||
cout << endl;
|
||||
|
||||
system("PAUSE");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,12 @@ struct Equation {
|
|||
vector<Term*> lwing;
|
||||
vector<Term*> rwing;
|
||||
|
||||
LOG* log = nullptr;
|
||||
|
||||
// TODO: Optimize this mess
|
||||
void Parse(lexertk::generator expression) {
|
||||
tok_log = log;
|
||||
|
||||
string lwing_str;
|
||||
string rwing_str;
|
||||
|
||||
|
@ -38,10 +42,18 @@ struct Equation {
|
|||
lexertk::generator lwing_lexer;
|
||||
lwing_lexer.process(lwing_str);
|
||||
lwing = tokenize(lwing_lexer);
|
||||
if (lwing.empty()) {
|
||||
return; // error occured
|
||||
}
|
||||
|
||||
lexertk::generator rwing_lexer;
|
||||
rwing_lexer.process(rwing_str);
|
||||
rwing = tokenize(rwing_lexer);
|
||||
if (lwing.empty()) {
|
||||
return; // error occured
|
||||
}
|
||||
|
||||
tok_log = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef DEFINES_H
|
||||
#define DEFINES_H
|
||||
#include "../Log.h"
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
@ -17,6 +18,7 @@
|
|||
|
||||
#include <functional>
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define DEF_C -999
|
||||
|
|
|
@ -4,10 +4,48 @@ void Solver::Parse(string equation) {
|
|||
mEquation = new Equation();
|
||||
lexertk::generator lexer;
|
||||
lexer.process(equation);
|
||||
mEquation->log = log;
|
||||
mEquation->Parse(lexer);
|
||||
if (mEquation->lwing.empty() || mEquation->rwing.empty()) {
|
||||
mIncorrect = true;
|
||||
}
|
||||
else mIncorrect = false;
|
||||
}
|
||||
|
||||
Equation * Solver::Solve() {
|
||||
if (mIncorrect) return nullptr;
|
||||
// Break Brackets
|
||||
// Lwing
|
||||
mEquation->lwing = RemoveBrackets(mEquation->lwing);
|
||||
// Rwing
|
||||
mEquation->rwing = RemoveBrackets(mEquation->rwing);
|
||||
|
||||
if (mEquation->lwing.empty() ||
|
||||
mEquation->rwing.empty())
|
||||
return {};
|
||||
|
||||
// Add operators
|
||||
mEquation->lwing = AddNonEssientalOps(mEquation->lwing);
|
||||
mEquation->rwing = AddNonEssientalOps(mEquation->rwing);
|
||||
|
||||
// Remove Exponenets
|
||||
// Lwing
|
||||
for (int i = 0; i < mEquation->lwing.size(); i++) {
|
||||
if (mEquation->lwing[i]->mType == TermTypes::Const) {
|
||||
mEquation->lwing[i] = QMEvalHelper::ReducePower(mEquation->lwing[i])[0];
|
||||
}
|
||||
}
|
||||
// Rwing
|
||||
for (int i = 0; i < mEquation->rwing.size(); i++) {
|
||||
if (mEquation->rwing[i]->mType == TermTypes::Const) {
|
||||
mEquation->rwing[i] = QMEvalHelper::ReducePower(mEquation->rwing[i])[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate
|
||||
mEquation->lwing = evaluate(mEquation->lwing);
|
||||
mEquation->rwing = evaluate(mEquation->rwing);
|
||||
|
||||
// Put vars on one side and consts on another
|
||||
mEquation = PutVarsInOneSide(mEquation);
|
||||
mEquation = PutConstsInOneSide(mEquation);
|
||||
|
@ -22,6 +60,21 @@ Equation * Solver::Solve() {
|
|||
return mEquation;
|
||||
}
|
||||
|
||||
bool Solver::CheckEqu(string equation) {
|
||||
|
||||
if (!isContain(equation, '=')) {
|
||||
log->operator<< ("Must Have Equal Sign for Correct Equation!");
|
||||
system("PAUSE");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
Equation* equ = new Equation();
|
||||
lexertk::generator gen;
|
||||
gen.process(equation);
|
||||
equ->Parse(gen);
|
||||
return CheckValidOps(equ);
|
||||
}
|
||||
|
||||
vector<Term*> Solver::FlipTermSigns(vector<Term*> terms) {
|
||||
vector<Term*> res;
|
||||
|
||||
|
@ -34,8 +87,8 @@ vector<Term*> Solver::FlipTermSigns(vector<Term*> terms) {
|
|||
if (brack->mConstant == nullptr) {
|
||||
brack->mConstant = new Constant(-1, 1);
|
||||
}
|
||||
else
|
||||
brack->mConstant->mValue = -brack->mConstant->mValue;
|
||||
else
|
||||
brack->mConstant->mValue = -brack->mConstant->mValue;
|
||||
res.push_back(brack);
|
||||
}
|
||||
else {
|
||||
|
@ -49,21 +102,59 @@ vector<Term*> Solver::FlipTermSigns(vector<Term*> terms) {
|
|||
}
|
||||
|
||||
Equation * Solver::ApplyDiversionCalcs(Equation * equ) {
|
||||
// Situations
|
||||
// Situations:
|
||||
// 2x = 50 -> x = 50/2, applies only if one var
|
||||
// 4/3x=4 -> 4=4*4x -> 12x=4 -> x=4/12
|
||||
|
||||
auto lwing = RemNonEssientalOps(equ->lwing);
|
||||
auto rwing = RemNonEssientalOps(equ->rwing);
|
||||
auto lwing = RemoveBundle(equ->lwing);
|
||||
auto rwing = RemoveBundle(equ->rwing);
|
||||
|
||||
if (lwing.size() == 3) {
|
||||
if (rwing.size() == 1) {
|
||||
if (lwing[1]->mOperator == '/') {
|
||||
auto nomin = lwing[0];
|
||||
auto domin = lwing[2];
|
||||
auto right = rwing[0];
|
||||
|
||||
auto final_right = QMEvalHelper::Mul(domin, right);
|
||||
lwing.clear();
|
||||
rwing.clear();
|
||||
lwing.push_back(nomin);
|
||||
for (auto rwing_terms : final_right)
|
||||
rwing.push_back(rwing_terms);
|
||||
|
||||
lwing.swap(rwing);
|
||||
|
||||
|
||||
auto _domin = lwing[0]->mValue;
|
||||
Bracket* brack = new Bracket();
|
||||
for (int i = 0; i < rwing.size(); i++)
|
||||
brack->mTerms.push_back(rwing[i]);
|
||||
auto term = QMEvalHelper::Div(brack, new Constant(_domin, 1));
|
||||
rwing.clear();
|
||||
rwing = term;
|
||||
lwing[0]->mValue = 1;
|
||||
|
||||
equ->lwing = lwing;
|
||||
equ->rwing = rwing;
|
||||
return equ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lwing = RemNonEssientalOps(equ->lwing);
|
||||
rwing = RemNonEssientalOps(equ->rwing);
|
||||
|
||||
if (lwing.size() == 1) {
|
||||
// Check if x's coeffiecent is higher than 1 or lower
|
||||
if (lwing[0]->mValue != 1 && lwing[0]->mPower == 1) {
|
||||
// situation of "2x = 50 -> x = 50/2" is confirmed
|
||||
|
||||
auto domin = lwing[0]->mValue;
|
||||
Bracket* brack = new Bracket();
|
||||
for (int i = 0; i < rwing.size(); i++)
|
||||
brack->mTerms.push_back(rwing[i]);
|
||||
auto term = QMEvalHelper::Div(brack, new Constant(domin));
|
||||
auto term = QMEvalHelper::Div(brack, new Constant((long double)domin, 1));
|
||||
rwing.clear();
|
||||
rwing = term;
|
||||
lwing[0]->mValue = 1;
|
||||
|
@ -79,59 +170,85 @@ Equation * Solver::ApplyDiversionCalcs(Equation * equ) {
|
|||
bool Solver::CheckValidOps(Equation * equ) {
|
||||
|
||||
// Check Lwing
|
||||
for (int i = 0; i < equ->lwing.size() - 1; i++) {
|
||||
auto term = equ->lwing[i];
|
||||
if (term->mType == TermTypes::Op) {
|
||||
if (i == 0) {
|
||||
if (term->mOperator == '/' || term->mOperator == '*') {
|
||||
cout << "Can't have division or multiplication at the begining!" << endl;
|
||||
system("PUASE");
|
||||
exit(0);
|
||||
if (!equ->lwing.empty()) {
|
||||
// Check Ending
|
||||
if (equ->lwing[equ->lwing.size() - 1]->mType == TermTypes::Op) {
|
||||
log->operator<<("Can't have operatos at the end!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < equ->lwing.size() - 1; i++) {
|
||||
auto term = equ->lwing[i];
|
||||
if (term->mType == TermTypes::Op) {
|
||||
if (i == 0) {
|
||||
if (term->mOperator == '/' || term->mOperator == '*') {
|
||||
log->operator<<("Can't have division or multiplication at the begining!");
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
auto before_Term = equ->lwing[i - 1];
|
||||
auto after_Term = equ->lwing[i + 1];
|
||||
auto before_Term = equ->lwing[i - 1];
|
||||
auto after_Term = equ->lwing[i + 1];
|
||||
|
||||
if (before_Term->mType == TermTypes::Op ||
|
||||
after_Term->mType == TermTypes::Op) {
|
||||
cout << "Can't have trialing operators!" << endl;
|
||||
system("PUASE");
|
||||
exit(0);
|
||||
if (before_Term->mType == TermTypes::Op ||
|
||||
after_Term->mType == TermTypes::Op) {
|
||||
log->operator<<("Can't have trialing operators!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check Rwing
|
||||
for (int i = 0; i < equ->rwing.size() - 1; i++) {
|
||||
auto term = equ->rwing[i];
|
||||
if (term->mType == TermTypes::Op) {
|
||||
if (i == 0) {
|
||||
if (term->mOperator == '/' || term->mOperator == '*') {
|
||||
cout << "Can't have division or multiplication at the begining!" << endl;
|
||||
if (!equ->rwing.empty()) {
|
||||
// Check Ending
|
||||
if (equ->rwing[equ->rwing.size() - 1]->mType == TermTypes::Op) {
|
||||
log->operator<<("Can't have operatos at the end!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < equ->rwing.size() - 1; i++) {
|
||||
auto term = equ->rwing[i];
|
||||
if (term->mType == TermTypes::Op) {
|
||||
if (i == 0) {
|
||||
if (term->mOperator == '/' || term->mOperator == '*') {
|
||||
log->operator<<("Can't have division or multiplication at the begining!");
|
||||
system("PUASE");
|
||||
exit(0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
auto before_Term = equ->rwing[i - 1];
|
||||
auto after_Term = equ->rwing[i + 1];
|
||||
|
||||
if (before_Term->mType == TermTypes::Op ||
|
||||
after_Term->mType == TermTypes::Op) {
|
||||
log->operator<<("Can't have trialing operators!");
|
||||
system("PUASE");
|
||||
exit(0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
auto before_Term = equ->rwing[i - 1];
|
||||
auto after_Term = equ->rwing[i + 1];
|
||||
|
||||
if (before_Term->mType == TermTypes::Op ||
|
||||
after_Term->mType == TermTypes::Op) {
|
||||
cout << "Can't have trialing operators!" << endl;
|
||||
system("PUASE");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Solver::CheckValidOps(vector<Term*> terms) {
|
||||
Equation* equ = new Equation();
|
||||
equ->lwing = terms;
|
||||
return CheckValidOps(equ);
|
||||
}
|
||||
|
||||
bool Solver::IsVarAval(vector<Term*> terms) {
|
||||
for (auto term : terms)
|
||||
if (term->mType == TermTypes::Var)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Equation * Solver::PutVarsInOneSide(Equation * equ) {
|
||||
Equation* res = new Equation();
|
||||
|
||||
|
@ -228,13 +345,16 @@ Equation * Solver::PutConstsInOneSide(Equation * equ) {
|
|||
if (lwing[i]->mType == TermTypes::Bund) {
|
||||
// check if it has a constant
|
||||
Bundle* bundle = static_cast<Bundle*>(lwing[i]);
|
||||
bool contains = false;
|
||||
for (auto *term : bundle->mTerms)
|
||||
if (term->mType == TermTypes::Const) { contains = true; continue; }
|
||||
|
||||
if (contains)
|
||||
lwing_const.push_back(i);
|
||||
continue;
|
||||
if (!IsVarAval(bundle->mTerms)) {
|
||||
bool contains = false;
|
||||
for (auto *term : bundle->mTerms)
|
||||
if (term->mType == TermTypes::Const) { contains = true; continue; }
|
||||
|
||||
if (contains)
|
||||
lwing_const.push_back(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (lwing[i]->mType == TermTypes::Const)
|
||||
lwing_const.push_back(i);
|
||||
|
@ -294,6 +414,11 @@ vector<Term*> Solver::RemNonEssientalOps(vector<Term*> terms) {
|
|||
vector<Term*> res;
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
auto term = terms[i];
|
||||
if (term->mType == TermTypes::Brack) {
|
||||
auto resultant = RemNonEssientalOps(QMEvalHelper::BreakBracket(static_cast<Bracket*>(term)));
|
||||
for (auto __term : resultant) res.push_back(__term);
|
||||
continue;
|
||||
}
|
||||
if (term->mType == TermTypes::Op) {
|
||||
if (term->mOperator == '+') {
|
||||
auto after_term = terms[i + 1];
|
||||
|
@ -303,15 +428,15 @@ vector<Term*> Solver::RemNonEssientalOps(vector<Term*> terms) {
|
|||
continue;
|
||||
}
|
||||
if (term->mOperator == '-') {
|
||||
auto after_term = terms[i+1];
|
||||
auto after_term = terms[i + 1];
|
||||
after_term->mValue = after_term->mValue * -1;
|
||||
res.push_back(after_term);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (term->mOperator == '*') {
|
||||
auto before_term = *res.end();
|
||||
auto before_term = *(res.end() - 1);
|
||||
res.pop_back();
|
||||
auto after_term = terms[i + 1];
|
||||
Bundle* bundle = new Bundle();
|
||||
|
@ -324,9 +449,9 @@ vector<Term*> Solver::RemNonEssientalOps(vector<Term*> terms) {
|
|||
}
|
||||
|
||||
if (term->mOperator == '/') {
|
||||
auto before_term = *(--res.end());
|
||||
auto before_term = *(res.end() - 1);
|
||||
res.pop_back();
|
||||
auto after_term = terms[i+1];
|
||||
auto after_term = terms[i + 1];
|
||||
Bundle* bundle = new Bundle();
|
||||
bundle->mTerms.push_back(before_term);
|
||||
bundle->mTerms.push_back(term);
|
||||
|
@ -338,7 +463,7 @@ vector<Term*> Solver::RemNonEssientalOps(vector<Term*> terms) {
|
|||
}
|
||||
res.push_back(term);
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
vector<Term*> Solver::AddNonEssientalOps(vector<Term*> terms) {
|
||||
|
@ -358,10 +483,13 @@ vector<Term*> Solver::AddNonEssientalOps(vector<Term*> terms) {
|
|||
}
|
||||
|
||||
if (term->mType == TermTypes::Brack) {
|
||||
res.push_back(term);
|
||||
auto resultant =
|
||||
AddNonEssientalOps(QMEvalHelper::BreakBracket(static_cast<Bracket*>(term)));
|
||||
|
||||
for (auto *__term : resultant) res.push_back(__term);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// check if term was positive
|
||||
if (term->mValue > 0) {
|
||||
res.push_back(new Operator('+'));
|
||||
|
@ -401,12 +529,12 @@ vector<Term*> Solver::BundleTermsDuo(vector<Term*> terms) {
|
|||
if (term->mOperator == '/') {
|
||||
if (i == 0) {
|
||||
// invalid cant have division at begining
|
||||
cout << "Can't have division at begining!" << endl;
|
||||
log->operator<<("Can't have division at begining!");
|
||||
system("PAUSE");
|
||||
exit(0);
|
||||
}
|
||||
auto before_term = terms[i-1];
|
||||
auto after_term = terms[i +1];
|
||||
auto before_term = terms[i - 1];
|
||||
auto after_term = terms[i + 1];
|
||||
Bundle* bundle = new Bundle();
|
||||
bundle->mTerms.push_back(before_term); // t1
|
||||
bundle->mTerms.push_back(term); // op
|
||||
|
@ -420,11 +548,11 @@ vector<Term*> Solver::BundleTermsDuo(vector<Term*> terms) {
|
|||
if (term->mOperator == '*') {
|
||||
if (i == 0) {
|
||||
// invalid cant have multiplication at begining
|
||||
cout << "Can't have multiplication at begining!" << endl;
|
||||
log->operator<<("Can't have multiplication at begining!");
|
||||
system("PAUSE");
|
||||
exit(0);
|
||||
}
|
||||
auto before_term = terms[i-1];
|
||||
auto before_term = terms[i - 1];
|
||||
auto after_term = terms[i + 1];
|
||||
Bundle* bundle = new Bundle();
|
||||
bundle->mTerms.push_back(before_term); // t1
|
||||
|
@ -459,7 +587,7 @@ vector<Term*> Solver::BundleTermsTri(vector<Term*> terms) {
|
|||
if (term->mOperator == '/') {
|
||||
if (i == 0) {
|
||||
// invalid cant have division at begining
|
||||
cout << "Can't have division at begining!" << endl;
|
||||
log->operator<<("Can't have division at begining!");
|
||||
system("PUASE");
|
||||
exit(0);
|
||||
}
|
||||
|
@ -478,7 +606,7 @@ vector<Term*> Solver::BundleTermsTri(vector<Term*> terms) {
|
|||
if (term->mOperator == '*') {
|
||||
if (i == 0) {
|
||||
// invalid cant habe multiplication at begining
|
||||
cout << "Can't have multiplication at beginign!" << endl;
|
||||
log->operator<<("Can't have multiplication at beginign!");
|
||||
system("PAUSE");
|
||||
exit(0);
|
||||
}
|
||||
|
@ -518,7 +646,7 @@ bool Solver::IsEqualBundle(Bundle * b1, Bundle * b2) {
|
|||
if (b1_copy.size() != b2_copy.size()) return false;
|
||||
|
||||
for (int i = 0; i < b1_copy.size(); i++)
|
||||
if (!QMEvalHelper::IsEquTerms(b1_copy[i], b2_copy[i]))
|
||||
if (!QMEvalHelper::IsEquTerms(b1_copy[i], b2_copy[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef SOLVER_H
|
||||
#define SOLVER_H
|
||||
#pragma once
|
||||
#include "../Equations.h"
|
||||
#include "../defines.h"
|
||||
#include "../Equations.h"
|
||||
#include "../terms/Brackets.h"
|
||||
#include "../terms/Constant.h"
|
||||
#include "../terms/Equal.h"
|
||||
|
@ -20,19 +20,61 @@
|
|||
|
||||
class Solver {
|
||||
public:
|
||||
Solver(LOG* _log = nullptr) {
|
||||
log = _log;
|
||||
}
|
||||
void Parse(string equation);
|
||||
Equation* Solve();
|
||||
|
||||
bool CheckEqu(string equation);
|
||||
|
||||
bool CheckValidOps(Equation* equ);
|
||||
bool CheckValidOps(vector<Term*> terms);
|
||||
vector<Term*> RemoveBrackets(vector<Term*> terms) {
|
||||
vector<Term*> res;
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
auto term = terms[i];
|
||||
if (terms[i]->mType == TermTypes::Brack) {
|
||||
auto _terms = QMEvalHelper::BreakBracket(static_cast<Bracket*>(term));
|
||||
if (!CheckValidOps(_terms)) {
|
||||
return {};
|
||||
}
|
||||
_terms = RemoveBrackets(_terms);
|
||||
for (auto item : _terms) res.push_back(item);
|
||||
}
|
||||
else
|
||||
res.push_back(term);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public: // PRIVATE MEMBERS TODO: MARK PRIVATE IN FINAL BUILD
|
||||
Equation* mEquation = nullptr;
|
||||
bool mIncorrect = false;
|
||||
LOG* log = nullptr;
|
||||
|
||||
private: // Mathematics Side Class Todo: Mark Private in final build
|
||||
vector<Term*> FlipTermSigns(vector<Term*> terms);
|
||||
|
||||
Equation* ApplyDiversionCalcs(Equation* equ);
|
||||
|
||||
private: // Program Side Calcs TODO: MARK PRIVATE IN FINAL BUILD
|
||||
bool CheckValidOps(Equation* equ);
|
||||
public: // Program Side Calcs TODO: MARK PRIVATE IN FINAL BUILD
|
||||
|
||||
bool IsVarAval(vector<Term*> terms);
|
||||
|
||||
vector<Term*> RemoveBundle(vector<Term*> res) {
|
||||
vector<Term*> final_res;
|
||||
|
||||
for (int i = 0; i < res.size(); i++) {
|
||||
if (res[i]->mType == TermTypes::Bund) {
|
||||
auto result = BreakBundle(static_cast<Bundle*>(res[i]));
|
||||
for (int j = 0; j < result.size(); j++)
|
||||
final_res.push_back(result[j]);
|
||||
}
|
||||
else
|
||||
final_res.push_back(res[i]);
|
||||
}
|
||||
return final_res;
|
||||
}
|
||||
|
||||
Equation* PutVarsInOneSide(Equation* equ);
|
||||
Equation* PutConstsInOneSide(Equation* equ);
|
||||
|
|
|
@ -48,12 +48,16 @@ vector<Term*> QMEvalHelper::BreakBracket(Bracket * brack, bool order, Identifier
|
|||
for (int i = 0; i < brack->mTerms.size(); i++)
|
||||
res.push_back(brack->mTerms[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < brack->mTerms.size(); i++) {
|
||||
auto returns = Mul(brack->mConstant, brack->mTerms[i]);
|
||||
for (int j = 0; j < returns.size(); j++)
|
||||
res.push_back(returns[j]);
|
||||
}
|
||||
else
|
||||
for (int i = 0; i < brack->mTerms.size(); i++) {
|
||||
if (brack->mTerms[i]->mType != TermTypes::Op) {
|
||||
auto returns = Mul(brack->mConstant, brack->mTerms[i]);
|
||||
for (int j = 0; j < returns.size(); j++)
|
||||
res.push_back(returns[j]);
|
||||
}
|
||||
else
|
||||
res.push_back(brack->mTerms[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -107,7 +111,7 @@ bool QMEvalHelper::IsHigherSig(Term * t1, Term * t2) { // x^2 > x : true
|
|||
return t1->mValue >= t2->mValue;
|
||||
}
|
||||
// if t1 has higher or equal power
|
||||
if (t1->mPower >= t2->mPower)
|
||||
if (t1->mPower >= t2->mPower)
|
||||
return true;
|
||||
else return false; // t2 is higher
|
||||
}
|
||||
|
@ -174,7 +178,7 @@ vector<Term*> QMEvalHelper::Add(Term * t1, Term * t2, Identifier_t order) {
|
|||
// check if one of the terms were brackets
|
||||
if (IsBracket(t1) || IsBracket(t2)) {
|
||||
// check which term is bracket
|
||||
if (IsBracket(t1) && !IsBracket(t2)) {
|
||||
if (IsBracket(t1) && IsBracket(t2)) {
|
||||
auto brokenbrack = BreakBracket(convertToBracket(t1));
|
||||
auto brokenbrack2 = BreakBracket(convertToBracket(t2));
|
||||
for (int i = 0; i < brokenbrack2.size(); i++)
|
||||
|
@ -243,7 +247,6 @@ vector<Term*> QMEvalHelper::Add(Term * t1, Term * t2, Identifier_t order) {
|
|||
vector<Term*> QMEvalHelper::Sub(Term * t1, Term * t2, Identifier_t order) {
|
||||
vector<Term*> res;
|
||||
|
||||
|
||||
// check if one of the terms were brackets
|
||||
if (IsBracket(t1) || IsBracket(t2)) {
|
||||
// check which term is bracket
|
||||
|
@ -325,7 +328,7 @@ vector<Term*> QMEvalHelper::Mul(Term * t1, Term * t2, Identifier_t order) {
|
|||
// brack, var
|
||||
// brack, const
|
||||
|
||||
if (IsBracket(t1) || IsBracket(t2)) {
|
||||
if (IsBracket(t1) && IsBracket(t2)) {
|
||||
auto t1_brokenbrack = BreakBracket(convertToBracket(t1), true, order);
|
||||
auto t2_brokenbrack = BreakBracket(convertToBracket(t2), true, order);
|
||||
|
||||
|
@ -539,8 +542,6 @@ bool QMEvalHelper::TermsMatch(vector<Term*> terms1, vector<Term*> terms2) {
|
|||
}
|
||||
// WARNING: Make sure that t1 and t2 are in the simplest form.
|
||||
vector<Term*> QMEvalHelper::Div(Term * t1, Term * t2, Identifier_t order) {
|
||||
|
||||
|
||||
// Check if division is solvable
|
||||
if (IsDivSolvable(t1, t2)) {
|
||||
// only two situations
|
||||
|
@ -615,12 +616,7 @@ vector<Term*> QMEvalHelper::Div(Term * t1, Term * t2, Identifier_t order) {
|
|||
auto t1_const = convertToConstant(ReducePower(t1)[0]);
|
||||
auto t2_var = convertToVariable(t2);
|
||||
|
||||
Variable* var = new Variable();
|
||||
var->mVariable = t2_var->mVariable;
|
||||
var->mValue = t1_const->mValue / t2_var->mValue;
|
||||
var->mPower = t2_var->mPower;
|
||||
|
||||
return { var };
|
||||
return { t1_const, new Operator('/'), t2_var };
|
||||
}
|
||||
else if (t1->mType == TermTypes::Var && t2->mType == TermTypes::Const) {
|
||||
// var / const
|
||||
|
|
|
@ -91,9 +91,52 @@ static vector<Term*> getPool() {
|
|||
return res;
|
||||
}
|
||||
|
||||
static vector<Term*> evaluateRight(vector<Term*> terms) {
|
||||
TermPool mPool;
|
||||
mPool.set(terms);
|
||||
|
||||
// Step 1:
|
||||
// Reduce Powers except for variables
|
||||
for (int i = 0; i < mPool.size(); i++)
|
||||
if (mPool[i]->mType == TermTypes::Const)
|
||||
*mPool[i] = *QMEvalHelper::ReducePower(mPool[i])[0];
|
||||
|
||||
// Step 2:
|
||||
// Remove begining sign, if any
|
||||
if (mPool[0]->mType == TermTypes::Op) {
|
||||
auto op = mPool.pop_back(); // remove op
|
||||
auto res = *mPool.begin();
|
||||
res->mValue = res->mValue * (op->mOperator == '+') ? 1 : -1; // multiply
|
||||
|
||||
mPool.pop_front(); // remove term going to be modified
|
||||
mPool.push_front(res);
|
||||
}
|
||||
|
||||
// Step 3:
|
||||
// Generate ExpressionTree
|
||||
ExprTreeReversed tree;
|
||||
tree.setPool(mPool.vec());
|
||||
tree.GenerateTree();
|
||||
|
||||
// Step 4: Evaluate!!!
|
||||
mPool.set(solveNode(tree.getHead()));
|
||||
vector<Term*> res;
|
||||
for (int i = 0; i < mPool.size(); i++)
|
||||
res.push_back(mPool[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
static vector<Term*> evaluate(vector<Term*> term) {
|
||||
if (term.empty()) return term;
|
||||
mPool.set(term);
|
||||
evaluate();
|
||||
|
||||
auto second_pool = evaluateRight(term);
|
||||
|
||||
if (second_pool.size() < mPool.size()) {
|
||||
mPool.set(second_pool);
|
||||
}
|
||||
|
||||
return getPool();
|
||||
}
|
||||
|
||||
|
|
|
@ -101,3 +101,111 @@ void ExprTree::_print(const std::string prefix, const TreeNode* node, bool isLef
|
|||
_print(prefix + (isLeft ? "| " : " "), node->_right, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ExprTreeReversed::setPool(vector<Term*> pool) {
|
||||
mPool.set(pool);
|
||||
mHead = new TreeNode();
|
||||
}
|
||||
|
||||
void ExprTreeReversed::GenerateTree() {
|
||||
mHead = _genTree(mPool);
|
||||
}
|
||||
|
||||
void ExprTreeReversed::print() {
|
||||
_print("", mHead, false);
|
||||
}
|
||||
|
||||
TreeNode * ExprTreeReversed::_genTree(TermPool pool) {
|
||||
if (pool.size() == 0) return nullptr;
|
||||
if (pool.size() == 1) {
|
||||
TreeNode* node = new TreeNode();
|
||||
node->_term = pool[0];
|
||||
node->_left = nullptr;
|
||||
node->_right = nullptr;
|
||||
return node;
|
||||
}
|
||||
|
||||
// Number operations
|
||||
std::vector<pair<int, int>> operators;
|
||||
int counter = 0;
|
||||
|
||||
// DIV, MUL first
|
||||
for (int i = pool.size()-1; i != 0; i--) {
|
||||
if (pool[i]->mType == TermTypes::Op) {
|
||||
if (pool[i]->mOperator == '/') {
|
||||
pair<int, int> resultant;
|
||||
resultant.first = i;
|
||||
resultant.second = counter++;
|
||||
operators.push_back(resultant);
|
||||
}
|
||||
if (pool[i]->mOperator == '*') {
|
||||
pair <int, int> resultant;
|
||||
resultant.first = i;
|
||||
resultant.second = counter++;
|
||||
operators.push_back(resultant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ADD, SUB Second
|
||||
for (int i = pool.size() - 1; i != 0; i--) {
|
||||
if (pool[i]->mType == TermTypes::Op) {
|
||||
if (pool[i]->mOperator == '+') {
|
||||
pair<int, int> resultant;
|
||||
resultant.first = i;
|
||||
resultant.second = counter++;
|
||||
operators.push_back(resultant);
|
||||
}
|
||||
else if (pool[i]->mOperator == '-') {
|
||||
pair<int, int> resultant;
|
||||
resultant.first = i;
|
||||
resultant.second = counter++;
|
||||
operators.push_back(resultant);
|
||||
}
|
||||
}
|
||||
}
|
||||
stable_sort(operators.begin(), operators.end(),
|
||||
[this](pair<int, int> arg1, pair<int, int> arg2) {
|
||||
return arg1.second < arg2.second;
|
||||
});
|
||||
|
||||
// Split upon op, recurse
|
||||
TermPool left, right;
|
||||
// dont get the op to left
|
||||
auto ptr1 = operators[operators.size() - 1].first;
|
||||
left.set(
|
||||
pool.getRange(0, ptr1 - 1)
|
||||
);
|
||||
// dont get the op to right
|
||||
right.set(
|
||||
pool.getRange(ptr1 + 1, pool.size() - 1)
|
||||
);
|
||||
|
||||
// get the op here
|
||||
Term* op = pool[left.size()];
|
||||
TreeNode* node = new TreeNode();
|
||||
node->_term = op;
|
||||
node->_left = _genTree(left);
|
||||
node->_right = _genTree(right);
|
||||
return node;
|
||||
}
|
||||
|
||||
void ExprTreeReversed::_print(const std::string prefix, const TreeNode * node, bool isLeft)
|
||||
{
|
||||
if (node != nullptr) {
|
||||
cout << prefix;
|
||||
|
||||
cout << (isLeft ? "|--" : "^--");
|
||||
|
||||
// print the value of the node
|
||||
cout << node->_term->to_str() << endl;
|
||||
|
||||
_print(prefix + (isLeft ? "| " : " "), node->_left, true);
|
||||
_print(prefix + (isLeft ? "| " : " "), node->_right, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,4 +40,24 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class ExprTreeReversed {
|
||||
public:
|
||||
void setPool(vector<Term*> pool);
|
||||
void GenerateTree();
|
||||
|
||||
void print();
|
||||
|
||||
TreeNode* getHead() { return mHead; }
|
||||
|
||||
private:
|
||||
TreeNode* _genTree(TermPool pool);
|
||||
void _print(const std::string prefix, const TreeNode* node, bool isLeft);
|
||||
|
||||
TreeNode* mHead = nullptr;
|
||||
TermPool mPool;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // !EXPR_TREE_H
|
||||
|
|
|
@ -67,6 +67,8 @@ static lexertk::generator retriveSubLexer(lexertk::generator gen, Token tok) {
|
|||
// Paranthesis(bool is, int _pos) : isOpening(is), pos(_pos) {}
|
||||
//};
|
||||
|
||||
static LOG* tok_log = nullptr;
|
||||
|
||||
vector<Term*> tokenize(lexertk::generator lexed);
|
||||
|
||||
static Bracket* tokenize_bracket(lexertk::generator gen, Token* token, string coefficient) {
|
||||
|
@ -78,19 +80,21 @@ static Bracket* tokenize_bracket(lexertk::generator gen, Token* token, string co
|
|||
|
||||
// DETERMINE THE ENDING OF THE BRACKETS
|
||||
int counter = 0;
|
||||
bool state = false;
|
||||
int index = token->begin;
|
||||
do {
|
||||
if (isBracketsOpening(gen[index].value[0])) {
|
||||
counter++;
|
||||
state = true;
|
||||
}
|
||||
else if (isBracketsClosing(gen[index].value[0])) {
|
||||
counter--;
|
||||
state = false;
|
||||
}
|
||||
index++;
|
||||
} while (!(!state && counter == 0));
|
||||
if (index > gen.size()) {
|
||||
// end of string
|
||||
tok_log->operator<<("Unbalanced Paranthesis!");
|
||||
return nullptr;
|
||||
}
|
||||
} while (counter != 0);
|
||||
|
||||
bracks = retriveSubLexer(gen, Token(token->begin, index - 1));
|
||||
token->end = index - 1; // to make sure we move the token pointer to the end of bracks
|
||||
|
@ -101,12 +105,15 @@ static Bracket* tokenize_bracket(lexertk::generator gen, Token* token, string co
|
|||
// Tokenize its term
|
||||
// first make sure it is not empty
|
||||
if (bracks.empty()) {
|
||||
cout << "Brackets can't be empty!" << endl;
|
||||
system("PAUSE");
|
||||
exit(0);
|
||||
tok_log->operator<<("Bracket can't be empty!");
|
||||
return nullptr;
|
||||
}
|
||||
// tokenize terms
|
||||
auto terms = tokenize(bracks);
|
||||
if (terms.empty()) {
|
||||
tok_log->operator<<("Failed to tokenize bracket's coefficient!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
result->mTerms = terms;
|
||||
|
||||
|
@ -127,44 +134,50 @@ static vector<Term*> combineBrackets(vector<Term*> terms) {
|
|||
|
||||
if (term->mType == TermTypes::Op &&
|
||||
(term->mOperator == '-' || term->mOperator == '+')) {
|
||||
// if after it was a number
|
||||
if (terms[i + 1]->mType == TermTypes::Const || terms[i + 1]->mType == TermTypes::Var) {
|
||||
// check for safety
|
||||
if (!(terms.size() <= i + 2))
|
||||
// if after it was a bracket too
|
||||
if (terms[i + 2]->mType == TermTypes::Brack) {
|
||||
if (i + 1 >= terms.size()) {
|
||||
// cant check after it
|
||||
result.push_back(terms[i]);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
// if after it was a number
|
||||
if (terms[i + 1]->mType == TermTypes::Const || terms[i + 1]->mType == TermTypes::Var) {
|
||||
// check for safety
|
||||
if (!(terms.size() <= i + 2))
|
||||
// if after it was a bracket too
|
||||
if (terms[i + 2]->mType == TermTypes::Brack) {
|
||||
// if so combine the terms
|
||||
Bracket* brack = new Bracket();
|
||||
brack->mTerms = static_cast<Bracket*>(terms[i + 2])->mTerms;
|
||||
auto constant = static_cast<Bracket*>(terms[i + 2])->mConstant;
|
||||
constant->mValue *= (term->mOperator == '+') ? +1 : -1;
|
||||
brack->mConstant = constant;
|
||||
result.push_back(brack);
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (terms[i + 1]->mType == TermTypes::Brack) {
|
||||
// if so combine the terms
|
||||
Bracket* brack = new Bracket();
|
||||
brack->mTerms = static_cast<Bracket*>(terms[i + 2])->mTerms;
|
||||
auto constant = static_cast<Bracket*>(terms[i + 2])->mConstant;
|
||||
constant->mValue *= (term->mOperator == '+') ? +1 : -1;
|
||||
brack->mConstant = constant;
|
||||
brack->mTerms = static_cast<Bracket*>(terms[i + 1])->mTerms;
|
||||
auto constant = static_cast<Bracket*>(terms[i + 1])->mConstant;
|
||||
if (constant == nullptr) { // 1
|
||||
Constant* Const = new Constant();
|
||||
if (term->mOperator == '+')
|
||||
Const->mValue = 1;
|
||||
else Const->mValue = -1;
|
||||
}
|
||||
else {
|
||||
constant->mValue *= (term->mOperator == '+') ? +1 : -1;
|
||||
brack->mConstant = constant;
|
||||
}
|
||||
result.push_back(brack);
|
||||
i += 2;
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (terms[i + 1]->mType == TermTypes::Brack) {
|
||||
// if so combine the terms
|
||||
Bracket* brack = new Bracket();
|
||||
brack->mTerms = static_cast<Bracket*>(terms[i + 1])->mTerms;
|
||||
auto constant = static_cast<Bracket*>(terms[i + 1])->mConstant;
|
||||
if (constant == nullptr) { // 1
|
||||
Constant* Const = new Constant();
|
||||
if (term->mOperator == '+')
|
||||
Const->mValue = 1;
|
||||
else Const->mValue = -1;
|
||||
}
|
||||
else {
|
||||
constant->mValue *= (term->mOperator == '+') ? +1 : -1;
|
||||
brack->mConstant = constant;
|
||||
}
|
||||
result.push_back(brack);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push_back(term);
|
||||
}
|
||||
|
@ -217,6 +230,16 @@ static vector<Term*> tokenize(lexertk::generator lexed) {
|
|||
Token tok;
|
||||
tok.begin = i;
|
||||
|
||||
if (lex.value == "^") {
|
||||
// invalid
|
||||
tok_log->operator<<("There can't be a stranded power sign!");
|
||||
return {};
|
||||
}
|
||||
if (lex.value == ")") {
|
||||
// invalid
|
||||
tok_log->operator<<("There can't be an ending without a begining!");
|
||||
return {};
|
||||
}
|
||||
if (is_all_digits(lex.value)) {
|
||||
// number
|
||||
|
||||
|
@ -230,17 +253,27 @@ static vector<Term*> tokenize(lexertk::generator lexed) {
|
|||
// powers ONLY can be numbers no evaluation is done in the power
|
||||
// ex: 5^2*3 // the expression will be 5 by 5 then multiply 3
|
||||
if (!is_all_digits(lexed[i + 3].value)) {
|
||||
cout << "ONLY numbers are allowed in powers!" << endl;
|
||||
system("PAUSE");
|
||||
exit(0);
|
||||
tok_log->operator<<("ONLY numbers are allowed in powers!");
|
||||
return {};
|
||||
/////// ENDING OF TREE
|
||||
}
|
||||
|
||||
// check for bracket
|
||||
if (lexed[i + 4].value == "(") {
|
||||
// check for brackets at the end
|
||||
if (i + 5 >= lexed.size()) {
|
||||
// invalid, having opening bracks at the end
|
||||
tok_log->operator<<("There can't be opening bracks at the end!");
|
||||
return {};
|
||||
}
|
||||
|
||||
// bracket detected
|
||||
tok.begin += 4; // consume coefficient
|
||||
result.push_back(tokenize_bracket(lexed, &tok, lex.value + after_lex.value + lexed[i + 2].value + lexed[i + 3].value));
|
||||
auto brack = tokenize_bracket(lexed, &tok, lex.value + after_lex.value + lexed[i + 2].value + lexed[i + 3].value);
|
||||
if (brack == nullptr) {
|
||||
return {};
|
||||
}
|
||||
result.push_back(brack);
|
||||
/////// ENDING OF TREE
|
||||
}
|
||||
else {
|
||||
|
@ -255,9 +288,19 @@ static vector<Term*> tokenize(lexertk::generator lexed) {
|
|||
else {
|
||||
|
||||
if (lexed[i + 2].value == "(") {
|
||||
// check for brackets at the end
|
||||
if (i + 3 >= lexed.size()) {
|
||||
// invalid, having opening bracks at the end
|
||||
tok_log->operator<<("There can't be opening bracks at the end!");
|
||||
return {};
|
||||
}
|
||||
// bracket detected
|
||||
tok.begin += 2;
|
||||
result.push_back(tokenize_bracket(lexed, &tok, lex.value + after_lex.value));
|
||||
auto brack = tokenize_bracket(lexed, &tok, lex.value + after_lex.value);
|
||||
if (brack == nullptr) {
|
||||
return {};
|
||||
}
|
||||
result.push_back(brack);
|
||||
/////// ENDING OF TREE
|
||||
}
|
||||
else {
|
||||
|
@ -271,10 +314,20 @@ static vector<Term*> tokenize(lexertk::generator lexed) {
|
|||
}
|
||||
}
|
||||
else if (isBrackets(after_lex.value[0]) && isBracketsOpening(after_lex.value[0])) {
|
||||
// check for brackets at the end
|
||||
if (i + 2 >= lexed.size()) {
|
||||
// invalid, having opening bracks at the end
|
||||
tok_log->operator<<("There can't be opening bracks at the end!");
|
||||
return {};
|
||||
}
|
||||
// check for brackets,
|
||||
// if so tokenize the brackets
|
||||
tok.begin++; // consume the coefficient
|
||||
result.push_back(tokenize_bracket(lexed, &tok, lex.value));
|
||||
auto brack = tokenize_bracket(lexed, &tok, lex.value);
|
||||
if (brack == nullptr) {
|
||||
return {};
|
||||
}
|
||||
result.push_back(brack);
|
||||
/////// ENDING OF TREE
|
||||
}
|
||||
else if (isPower(after_lex.value[0])) {
|
||||
|
@ -282,17 +335,26 @@ static vector<Term*> tokenize(lexertk::generator lexed) {
|
|||
// if so read the power and its constant
|
||||
// powers ONLY can be numbers no evaluation is done in the power
|
||||
// ex: 5^2*3 // the expression will be 5 by 5 then multiply 3
|
||||
if (!is_all_digits(lexed[i + 2].value)) {
|
||||
cout << "ONLY numbers are allowed in powers!" << endl;
|
||||
system("PAUSE");
|
||||
exit(0);
|
||||
if (!is_all_digits(lexed[i + 3].value)) {
|
||||
tok_log->operator<<("ONLY numbers are allowed in powers!");
|
||||
return {};
|
||||
/////// ENDING OF TREE
|
||||
}
|
||||
|
||||
// check for brackets
|
||||
if (lexed[i + 3].value == "(") {
|
||||
// check for brackets at the end
|
||||
if (i + 5 >= lexed.size()) {
|
||||
// invalid, having opening bracks at the end
|
||||
tok_log->operator<<("There can't be opening bracks at the end!");
|
||||
return {};
|
||||
}
|
||||
tok.begin += 3;
|
||||
result.push_back(tokenize_bracket(lexed, &tok, lex.value + after_lex.value + lexed[i + 2].value));
|
||||
auto brack = tokenize_bracket(lexed, &tok, lex.value + after_lex.value + lexed[i + 2].value);
|
||||
if (brack == nullptr) {
|
||||
return {};
|
||||
}
|
||||
result.push_back(brack);
|
||||
}
|
||||
else {
|
||||
Constant* Const = nullptr;
|
||||
|
@ -319,15 +381,14 @@ static vector<Term*> tokenize(lexertk::generator lexed) {
|
|||
if (isPower(after_lex.value[0])) {
|
||||
// powers ONLY can be numbers no evaluation is done in the power
|
||||
// ex: 5^2*3 // the expression will be 5 by 5 then multiply 3
|
||||
if (!is_all_digits(lexed[i + 2].value)) {
|
||||
cout << "ONLY numbers are allowed in powers!" << endl;
|
||||
system("PAUSE");
|
||||
exit(0);
|
||||
if (!is_all_digits(lexed[i + 3].value)) {
|
||||
tok_log->operator<<("ONLY numbers are allowed in powers!");
|
||||
return {};
|
||||
/////// ENDING OF TREE
|
||||
}
|
||||
|
||||
Variable* Var = nullptr;
|
||||
Var = new Variable(1.0, lex.value[0], lexed[i + 2].value[0]);
|
||||
Var = new Variable(1.0, lex.value[0], atof(&lexed[i + 3].value[0]));
|
||||
result.push_back(Var);
|
||||
tok.end = i + 2;
|
||||
/////// ENDING OF TREE
|
||||
|
@ -342,8 +403,17 @@ static vector<Term*> tokenize(lexertk::generator lexed) {
|
|||
}
|
||||
}
|
||||
else if (isBracketsOpening(lex.value[0])) {
|
||||
// check for brackets at the end
|
||||
if (i+1 >= lexed.size()) {
|
||||
// invalid, having opening bracks at the end
|
||||
tok_log->operator<<("There can't be opening bracks at the end!");
|
||||
return {};
|
||||
}
|
||||
// bracket
|
||||
result.push_back(tokenize_bracket(lexed, &tok, ""));
|
||||
auto brack = tokenize_bracket(lexed, &tok, "");
|
||||
if (brack == nullptr)
|
||||
return {};
|
||||
result.push_back(brack);
|
||||
}
|
||||
else if (isArithmitic(lex.value[0])) {
|
||||
// operator
|
||||
|
@ -352,7 +422,6 @@ static vector<Term*> tokenize(lexertk::generator lexed) {
|
|||
op = new Operator(lex.value[0]);
|
||||
result.push_back(op);
|
||||
tok.end = i;
|
||||
|
||||
}
|
||||
else if (isEqualChar(lex.value[0])) {
|
||||
// equal sign
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef QM_H
|
||||
#define QM_H
|
||||
#include "Log.h"
|
||||
|
||||
#include "maths/defines.h"
|
||||
#include "maths/Equations.h"
|
||||
#include "maths/tokenizer.h"
|
||||
|
||||
#include "maths/terms/Brackets.h"
|
||||
#include "maths/terms/Bundle.h"
|
||||
#include "maths/terms/Constant.h"
|
||||
#include "maths/terms/Equal.h"
|
||||
#include "maths/terms/Operator.h"
|
||||
#include "maths/terms/Paranthesis.h"
|
||||
#include "maths/terms/Term.h"
|
||||
#include "maths/terms/Variable.h"
|
||||
|
||||
#include "maths/solver/Solver.h"
|
||||
#include "maths/solver/term_rewriter/QMEvalHelper.h"
|
||||
#include "maths/solver/term_rewriter/QMEvaluator.h"
|
||||
|
||||
#include "maths/solver/term_rewriter/ds/ExprTree.h"
|
||||
#include "maths/solver/term_rewriter/ds/TermPool.h"
|
||||
|
||||
#endif // !QM_H
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 053d5ad24d9a58063f2bd71c186cb6adf807ea0a
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,19 +0,0 @@
|
|||
QMReducerHelper.cpp
|
||||
r:\projects\quicmaf\quicmaf\maths\terms\term.h(10): warning C4309: 'default argument': truncation of constant value
|
||||
r:\projects\quicmaf\quicmaf\maths\terms\term.h(22): warning C4305: 'initializing': truncation from 'int' to 'CValue'
|
||||
r:\projects\quicmaf\quicmaf\maths\terms\term.h(22): warning C4309: 'initializing': truncation of constant value
|
||||
r:\projects\quicmaf\quicmaf\maths\terms\term.h(24): warning C4305: 'initializing': truncation from 'int' to 'CValue'
|
||||
r:\projects\quicmaf\quicmaf\maths\terms\term.h(24): warning C4309: 'initializing': truncation of constant value
|
||||
r:\projects\quicmaf\quicmaf\maths\terms\variable.h(11): warning C4309: 'default argument': truncation of constant value
|
||||
r:\projects\quicmaf\quicmaf\maths\tokenizer.h(99): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
|
||||
r:\projects\quicmaf\quicmaf\maths\solver\term_rewriter\qmruleset.h(34): warning C4267: 'return': conversion from 'size_t' to 'int', possible loss of data
|
||||
r:\projects\quicmaf\quicmaf\maths\solver\term_rewriter\qmreducerhelper.cpp(445): warning C4244: 'argument': conversion from 'NValue' to 'int', possible loss of data
|
||||
r:\projects\quicmaf\quicmaf\maths\solver\term_rewriter\qmreducerhelper.cpp(453): warning C4244: 'argument': conversion from 'NValue' to 'int', possible loss of data
|
||||
r:\projects\quicmaf\quicmaf\maths\solver\term_rewriter\qmreducerhelper.cpp(464): warning C4244: 'argument': conversion from 'NValue' to 'int', possible loss of data
|
||||
r:\projects\quicmaf\quicmaf\maths\solver\term_rewriter\qmreducerhelper.cpp(472): warning C4244: 'argument': conversion from 'NValue' to 'int', possible loss of data
|
||||
Generating code
|
||||
2 of 790 functions ( 0.3%) were compiled, the rest were copied from previous compilation.
|
||||
0 functions were new in current compilation
|
||||
1 functions had inline decision re-evaluated but remain unchanged
|
||||
Finished generating code
|
||||
QuicMaf.vcxproj -> R:\Projects\QuicMaf\x64\Release\QuicMaf.exe
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,66 @@
|
|||
#include "Dashboard.h"
|
||||
|
||||
Dashboard::Dashboard(LOG* _log) :
|
||||
wxFrame(nullptr, wxID_ANY, "QuicMaf", wxDefaultPosition,
|
||||
wxSize(230, 200), wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxMINIMIZE_BOX) {
|
||||
this->SetMinSize(this->GetSize());
|
||||
this->SetMaxSize(this->GetSize());
|
||||
CreateControls();
|
||||
SizeControls();
|
||||
Center();
|
||||
log = _log;
|
||||
}
|
||||
|
||||
void Dashboard::CreateControls() {
|
||||
mPanel = new wxPanel(this, dsh_panel);
|
||||
|
||||
mEvalPg = new wxButton(mPanel, dsh_eval_btn, "Evaluate");
|
||||
mSolverPg = new wxButton(mPanel, dsh_solver_btn, "Solver");
|
||||
}
|
||||
|
||||
void Dashboard::SizeControls() {
|
||||
|
||||
mEvalPg->SetSize(wxSize(
|
||||
GetClientSize().x-4,
|
||||
(GetClientSize().y / 2) - 4
|
||||
));
|
||||
|
||||
mSolverPg->SetSize(wxSize(
|
||||
GetClientSize().x-4,
|
||||
(GetClientSize().y / 2) - 4
|
||||
));
|
||||
|
||||
mEvalPg->SetPosition(
|
||||
wxPoint(
|
||||
(GetClientSize().x/2)-(mEvalPg->GetSize().x/2),
|
||||
0.15*GetClientSize().y
|
||||
)
|
||||
);
|
||||
|
||||
mEvalPg->SetPosition(wxPoint(2, 0));
|
||||
|
||||
mSolverPg->SetPosition(wxPoint(
|
||||
2,
|
||||
mEvalPg->GetSize().y + 4
|
||||
));
|
||||
}
|
||||
|
||||
void Dashboard::OnEvalBtn(wxCommandEvent & evt) {
|
||||
this->Hide();
|
||||
Evaluator *eval = new Evaluator(this, log);
|
||||
eval->Show(true);
|
||||
}
|
||||
|
||||
void Dashboard::OnSolverBtn(wxCommandEvent & evt) {
|
||||
this->Hide();
|
||||
Solve* solve = new Solve(this, log);
|
||||
solve->Show(true);
|
||||
}
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE(Dashboard, wxFrame)
|
||||
|
||||
EVT_BUTTON(dsh_eval_btn, Dashboard::OnEvalBtn)
|
||||
EVT_BUTTON(dsh_solver_btn, Dashboard::OnSolverBtn)
|
||||
|
||||
END_EVENT_TABLE()
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef DASHBOARD_H
|
||||
#define DASHBOARD_H
|
||||
#pragma once
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include "dlgs/evaluator.h"
|
||||
#include "dlgs/Solve_dlg.h"
|
||||
|
||||
class Dashboard : public wxFrame {
|
||||
public:
|
||||
Dashboard(LOG* log = nullptr);
|
||||
void CreateControls();
|
||||
void SizeControls();
|
||||
|
||||
|
||||
private:
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
|
||||
wxPanel* mPanel = nullptr;
|
||||
wxButton* mEvalPg = nullptr;
|
||||
wxButton* mSolverPg = nullptr;
|
||||
|
||||
void OnEvalBtn(wxCommandEvent& evt);
|
||||
void OnSolverBtn(wxCommandEvent& evt);
|
||||
LOG* log = nullptr;
|
||||
};
|
||||
|
||||
enum {
|
||||
dsh_panel,
|
||||
dsh_eval_btn,
|
||||
dsh_solver_btn
|
||||
};
|
||||
|
||||
#endif // !DASHBOARD_H
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
r:\projects\quicmaf\quicmafgui\debug\vc141.idb
|
||||
r:\projects\quicmaf\quicmafgui\debug\vc141.pdb
|
||||
r:\projects\quicmaf\debug\quicmafgui.pdb
|
||||
r:\projects\quicmaf\quicmafgui\debug\quicmafgui.tlog\cl.command.1.tlog
|
|
@ -0,0 +1,2 @@
|
|||
qmgui.cpp
|
||||
QuicMafGui.vcxproj -> R:\Projects\QuicMaf\Debug\QuicMafGui.exe
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,2 +1,2 @@
|
|||
#TargetFrameworkVersion=v4.0:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0.17763.0
|
||||
Release|x64|R:\Projects\QuicMaf\|
|
||||
Debug|Win32|R:\Projects\QuicMaf\|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,176 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{7CDC5570-9785-446C-8CB9-C03E6D98927F}</ProjectGuid>
|
||||
<RootNamespace>QuicMafGui</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)bin/$(Configuration)-$(Platform)/</OutDir>
|
||||
<IntDir>$(SolutionDir)bin-int/$(Configuration)-$(Platform)/</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)bin/$(Configuration)-$(Platform)/</OutDir>
|
||||
<IntDir>$(SolutionDir)bin-int/$(Configuration)-$(Platform)/</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)bin/$(Configuration)-$(Platform)/</OutDir>
|
||||
<IntDir>$(SolutionDir)bin-int/$(Configuration)-$(Platform)/</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)bin/$(Configuration)-$(Platform)/</OutDir>
|
||||
<IntDir>$(SolutionDir)bin-int/$(Configuration)-$(Platform)/</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include;$(WXWIN)\include\msvc;$(SolutionDir)\QuicMaf</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;WINVER=0x0400;__WXMSW__;_WINDOWS;wxUSE_GUI=1;_UNICODE;_DEBUG;__WXDEBUG__;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>wxmsw31ud_core.lib;wxbase31ud.lib;comctl32.lib;rpcrt4.lib;winmm.lib;advapi32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include;$(WXWIN)\include\msvc;$(SolutionDir)\QuicMaf</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>WIN32;WINVER=0x0400;__WXMSW__;_WINDOWS;wxUSE_GUI=1;_UNICODE;_DEBUG;__WXDEBUG__;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_lib;</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>wxmsw31ud_core.lib;wxbase31ud.lib;comctl32.lib;rpcrt4.lib;winmm.lib;advapi32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include;$(WXWIN)\include\msvc;$(SolutionDir)\QuicMaf</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;WINVER=0x0400;__WXMSW__;_WINDOWS;wxUSE_GUI=1;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>wxmsw31u_core.lib;wxbase31u.lib;comctl32.lib;rpcrt4.lib;winmm.lib;advapi32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(WXWIN)\include;$(WXWIN)\include\msvc;$(SolutionDir)\QuicMaf</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>WIN32;WINVER=0x0400;__WXMSW__;_WINDOWS;wxUSE_GUI=1;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_lib;</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>wxmsw31u_core.lib;wxbase31u.lib;comctl32.lib;rpcrt4.lib;winmm.lib;advapi32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Dashboard.cpp" />
|
||||
<ClCompile Include="dlgs\Evaluator.cpp" />
|
||||
<ClCompile Include="qmgui.cpp" />
|
||||
<ClCompile Include="dlgs\Solve_dlg.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Dashboard.h" />
|
||||
<ClInclude Include="dlgs\evaluator.h" />
|
||||
<ClInclude Include="dlgs\Solve_dlg.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\QuicMaf\QuicMaf.vcxproj">
|
||||
<Project>{ea73d661-b6eb-4156-ac92-a470a6683307}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="qmgui.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Dashboard.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dlgs\Evaluator.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dlgs\Solve_dlg.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Dashboard.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dlgs\evaluator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dlgs\Solve_dlg.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ShowAllFiles>true</ShowAllFiles>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,154 @@
|
|||
#include "evaluator.h"
|
||||
|
||||
Evaluator::Evaluator(wxWindow* pId, LOG* _log) :
|
||||
wxDialog(pId, wxID_ANY, "QuicMaf | Evaluator",
|
||||
wxDefaultPosition, wxSize(400, 200), wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxMINIMIZE_BOX) {
|
||||
CreateControls();
|
||||
SizeControls();
|
||||
Center();
|
||||
log = _log;
|
||||
solver = new Solver(log);
|
||||
}
|
||||
|
||||
void Evaluator::CreateControls() {
|
||||
mPanel = new wxPanel(this, eval_panel);
|
||||
|
||||
mInput = new wxTextCtrl(mPanel, eval_input);
|
||||
mOutput = new wxListBox(mPanel, eval_output);
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Enter an expression to evaluate!");
|
||||
}
|
||||
|
||||
void Evaluator::SizeControls() {
|
||||
mInput->SetSize(wxSize(
|
||||
GetClientSize().x-4,
|
||||
(GetClientSize().y/2)-4
|
||||
));
|
||||
mOutput->SetSize(wxSize(
|
||||
GetClientSize().x-4,
|
||||
(GetClientSize().y / 2) - 4
|
||||
));
|
||||
|
||||
mInput->SetPosition(wxPoint(2, 0));
|
||||
mOutput->SetPosition(wxPoint(2, mInput->GetPosition().y+mInput->GetSize().y+4));
|
||||
}
|
||||
|
||||
void Evaluator::OnInputChange(wxCommandEvent & evt) {
|
||||
// Check for emptyness
|
||||
if (mInput->GetValue().empty()) {
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Enter an expression to evaluate!");
|
||||
return;
|
||||
}
|
||||
// Check for blank
|
||||
if (mInput->GetValue() == " ") {
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("I wonder what a blank evaluates to!");
|
||||
return;
|
||||
}
|
||||
// Check for illegal chars
|
||||
for (auto c : mInput->GetValue().ToStdString()) {
|
||||
switch (c) {
|
||||
case '!':
|
||||
case '@':
|
||||
case '#':
|
||||
case '$':
|
||||
case '%':
|
||||
case '&':
|
||||
case '*':
|
||||
case '|':
|
||||
case '{':
|
||||
case '}':
|
||||
case '[':
|
||||
case ']':
|
||||
case '>':
|
||||
case '<':
|
||||
case '~':
|
||||
case '?':
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Illegal character!");
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (CheckExpr(mInput->GetValue().ToStdString())) {
|
||||
vector<Term*> terms;
|
||||
string input = mInput->GetValue().ToStdString();
|
||||
lexertk::generator gen;
|
||||
gen.process(input);
|
||||
tok_log = log;
|
||||
terms = tokenize(gen);
|
||||
if (terms.empty()) {
|
||||
// error occured
|
||||
mOutput->Clear();
|
||||
for (auto item : *log->qm_log)
|
||||
mOutput->AppendString(item);
|
||||
log->qm_log->clear();
|
||||
return;
|
||||
}
|
||||
if (!solver->CheckValidOps(terms)) {
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Operators are not correct!");
|
||||
}
|
||||
else {
|
||||
// check for ending operators
|
||||
if (terms[terms.size() - 1]->mType == TermTypes::Op) {
|
||||
// there can't be ending operators
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Operators can't be at the end!");
|
||||
}
|
||||
else {
|
||||
// Break brackets
|
||||
terms = solver->RemoveBrackets(terms);
|
||||
|
||||
// Remove Exponents
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
if (terms[i]->mType == TermTypes::Const) {
|
||||
terms[i] = QMEvalHelper::ReducePower(terms[i])[0];
|
||||
}
|
||||
}
|
||||
|
||||
terms = evaluate(terms);
|
||||
terms = solver->AddNonEssientalOps(terms);
|
||||
if (terms.empty()) {
|
||||
// error occured
|
||||
mOutput->Clear();
|
||||
for (auto item : *log->qm_log)
|
||||
mOutput->AppendString(item);
|
||||
log->qm_log->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
string output = "";
|
||||
for (int i = 0; i < terms.size(); i++)
|
||||
output.append(terms[i]->to_str());
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("There can't be an equal sign!");
|
||||
}
|
||||
}
|
||||
|
||||
void Evaluator::OnClose(wxCloseEvent & evt) {
|
||||
this->GetParent()->Show(true);
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool Evaluator::CheckExpr(string str) {
|
||||
if (isContain(str, '=')) return false;
|
||||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(Evaluator, wxDialog)
|
||||
|
||||
EVT_TEXT(eval_input, Evaluator::OnInputChange)
|
||||
EVT_CLOSE(Evaluator::OnClose)
|
||||
|
||||
END_EVENT_TABLE()
|
|
@ -0,0 +1,134 @@
|
|||
#include "Solve_dlg.h"
|
||||
|
||||
Solve::Solve(wxWindow* pID, LOG* _log)
|
||||
: wxDialog(pID, wxID_ANY,
|
||||
"QuicMaf | Solver", wxDefaultPosition,
|
||||
wxSize(400, 200), wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxMINIMIZE_BOX) {
|
||||
CreateControls();
|
||||
SizeControls();
|
||||
Center();
|
||||
log = _log;
|
||||
solver = new Solver(log);
|
||||
}
|
||||
|
||||
void Solve::CreateControls() {
|
||||
mPanel = new wxPanel(this, solve_panel);
|
||||
mInput = new wxTextCtrl(mPanel, solve_input);
|
||||
mOutput = new wxListBox(mPanel, solve_output);
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Enter an equation to solve!");
|
||||
}
|
||||
|
||||
void Solve::SizeControls() {
|
||||
mInput->SetSize(wxSize(
|
||||
GetClientSize().x - 4,
|
||||
(GetClientSize().y / 2) - 4
|
||||
));
|
||||
mOutput->SetSize(wxSize(
|
||||
GetClientSize().x - 4,
|
||||
(GetClientSize().y / 2) - 4
|
||||
));
|
||||
|
||||
mInput->SetPosition(wxPoint(2, 0));
|
||||
mOutput->SetPosition(wxPoint(2, mInput->GetPosition().y + mInput->GetSize().y + 4));
|
||||
}
|
||||
|
||||
void Solve::OnInputChange(wxCommandEvent & evt) {
|
||||
// Check for emptyness
|
||||
if (mInput->GetValue().empty()) {
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Enter an equation to solve!");
|
||||
return;
|
||||
}
|
||||
// Check for blank
|
||||
if (mInput->GetValue() == " ") {
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("I wonder what a blank evaluates to!");
|
||||
return;
|
||||
}
|
||||
// Check for equal only
|
||||
if (mInput->GetValue() == "=") {
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Equal is an Equal.");
|
||||
return;
|
||||
}
|
||||
// Check if there isnt an equal
|
||||
if (!isContain(mInput->GetValue().ToStdString(), '=')) {
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("There must be an equal sign!");
|
||||
return;
|
||||
}
|
||||
// Check for illegal chars
|
||||
for (auto c : mInput->GetValue().ToStdString()) {
|
||||
switch (c) {
|
||||
case '!':
|
||||
case '@':
|
||||
case '#':
|
||||
case '$':
|
||||
case '%':
|
||||
case '&':
|
||||
case '*':
|
||||
case '|':
|
||||
case '{':
|
||||
case '}':
|
||||
case '[':
|
||||
case ']':
|
||||
case '>':
|
||||
case '<':
|
||||
case '~':
|
||||
case '?':
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Illegal character!");
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
solver->Parse(mInput->GetValue().ToStdString());
|
||||
auto equ = solver->Solve();
|
||||
|
||||
if (equ == nullptr) {
|
||||
// error occured
|
||||
mOutput->Clear();
|
||||
for (auto item : *log->qm_log)
|
||||
mOutput->AppendString(item);
|
||||
log->qm_log->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (equ->lwing.empty()) {
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Left wing must not be empty!");
|
||||
}
|
||||
if (equ->rwing.empty()) {
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString("Right wing must not be empty!");
|
||||
}
|
||||
|
||||
|
||||
string str;
|
||||
|
||||
for (auto lwing_term : equ->lwing)
|
||||
str.append(lwing_term->to_str());
|
||||
|
||||
str.append("=");
|
||||
|
||||
for (auto rwing_term : equ->rwing)
|
||||
str.append(rwing_term->to_str());
|
||||
|
||||
mOutput->Clear();
|
||||
mOutput->AppendString(str);
|
||||
}
|
||||
|
||||
void Solve::OnClose(wxCloseEvent & evt) {
|
||||
this->GetParent()->Show(true);
|
||||
Destroy();
|
||||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(Solve, wxDialog)
|
||||
EVT_TEXT(solve_input, Solve::OnInputChange)
|
||||
EVT_CLOSE(Solve::OnClose)
|
||||
END_EVENT_TABLE()
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef SOLVE_DLG_H
|
||||
#define SOLVE_DLG_H
|
||||
#pragma once
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include "qm.h"
|
||||
|
||||
class Solve : public wxDialog {
|
||||
public:
|
||||
Solve(wxWindow* pID, LOG* log = nullptr);
|
||||
void CreateControls();
|
||||
void SizeControls();
|
||||
|
||||
private:
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
|
||||
wxPanel *mPanel = nullptr;
|
||||
|
||||
wxTextCtrl* mInput = nullptr;
|
||||
wxListBox* mOutput = nullptr;
|
||||
|
||||
void OnInputChange(wxCommandEvent& evt);
|
||||
void OnClose(wxCloseEvent& evt);
|
||||
|
||||
Solver* solver = nullptr;
|
||||
LOG* log = nullptr;
|
||||
};
|
||||
|
||||
enum {
|
||||
solve_panel,
|
||||
solve_input,
|
||||
solve_output
|
||||
};
|
||||
|
||||
#endif // !SOLVE_DLG
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef EVALUATOR_H
|
||||
#define EVALUATOR_H
|
||||
#pragma once
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include "qm.h"
|
||||
|
||||
class Evaluator : public wxDialog {
|
||||
public:
|
||||
Evaluator(wxWindow* pId, LOG* _log = nullptr);
|
||||
void CreateControls();
|
||||
void SizeControls();
|
||||
|
||||
private:
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
wxPanel* mPanel = nullptr;
|
||||
|
||||
wxTextCtrl *mInput = nullptr;
|
||||
wxListBox *mOutput = nullptr;
|
||||
|
||||
void OnInputChange(wxCommandEvent& evt);
|
||||
void OnClose(wxCloseEvent& evt);
|
||||
|
||||
bool CheckExpr(string str);
|
||||
Solver* solver = nullptr;
|
||||
LOG* log = nullptr;
|
||||
};
|
||||
|
||||
enum {
|
||||
eval_panel,
|
||||
eval_input,
|
||||
eval_output,
|
||||
};
|
||||
|
||||
#endif // !EVALUATOR_H
|
|
@ -0,0 +1,17 @@
|
|||
#include <wx/wx.h>
|
||||
#include "Dashboard.h"
|
||||
|
||||
class MyApp : public wxApp {
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
};
|
||||
|
||||
bool MyApp::OnInit() {
|
||||
LOG* log = new LOG();
|
||||
Dashboard *dash = new Dashboard(log);
|
||||
dash->Show(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
wxIMPLEMENT_APP(MyApp);
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue