diff --git a/.gitignore b/.gitignore index d7f9a4b..f33c48e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ bin-int/ bin/ -x64/ \ No newline at end of file +x64/ +release/ \ No newline at end of file diff --git a/Debug/QuicMafGui.exe b/Debug/QuicMafGui.exe new file mode 100644 index 0000000..80138af Binary files /dev/null and b/Debug/QuicMafGui.exe differ diff --git a/Debug/QuicMafGui.ilk b/Debug/QuicMafGui.ilk new file mode 100644 index 0000000..b4c541c Binary files /dev/null and b/Debug/QuicMafGui.ilk differ diff --git a/Debug/QuicMafGui.pdb b/Debug/QuicMafGui.pdb new file mode 100644 index 0000000..54b197a Binary files /dev/null and b/Debug/QuicMafGui.pdb differ diff --git a/QuicMaf.sln b/QuicMaf.sln index b25ee7f..aff9587 100644 --- a/QuicMaf.sln +++ b/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 diff --git a/QuicMaf/Log.h b/QuicMaf/Log.h new file mode 100644 index 0000000..402e331 --- /dev/null +++ b/QuicMaf/Log.h @@ -0,0 +1,28 @@ +/* + * File: Log.h + * Author: Alberto Lepe + * Edited By: Ayham Mamoun + * + * Created on December 1, 2015, 6:00 PM + */ + +#ifndef LOG_H +#define LOG_H +#include +#include +#include + +using namespace std; + +class LOG { +public: + vector* qm_log = new vector(); + LOG() {} + LOG &operator<<(const string &msg) { + qm_log->push_back(msg); + return *this; + } +private: +}; + +#endif /* LOG_H */ \ No newline at end of file diff --git a/QuicMaf/QuicMaf.vcxproj b/QuicMaf/QuicMaf.vcxproj index a30709c..fdc0888 100644 --- a/QuicMaf/QuicMaf.vcxproj +++ b/QuicMaf/QuicMaf.vcxproj @@ -26,26 +26,26 @@ - Application + StaticLibrary true v141 MultiByte - Application + StaticLibrary false v141 true MultiByte - Application + StaticLibrary true v141 MultiByte - Application + StaticLibrary false v141 true @@ -70,8 +70,24 @@ - $(SolutionDir)bin\$(Configuration)-$(Platform)\ - $(SolutionDir)bin-int\$(Configuration)-$(Platform)\ + $(SolutionDir)bin/$(Configuration)-$(Platform)/ + $(SolutionDir)bin-int/$(Configuration)-$(Platform)/ + $(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath) + + + $(SolutionDir)bin/$(Configuration)-$(Platform)/ + $(SolutionDir)bin-int/$(Configuration)-$(Platform)/ + $(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath) + + + $(SolutionDir)bin/$(Configuration)-$(Platform)/ + $(SolutionDir)bin-int/$(Configuration)-$(Platform)/ + $(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath) + + + $(SolutionDir)bin/$(Configuration)-$(Platform)/ + $(SolutionDir)bin-int/$(Configuration)-$(Platform)/ + $(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath) @@ -79,6 +95,7 @@ Disabled true true + $(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath);%(AdditionalIncludeDirectories) @@ -87,6 +104,7 @@ Disabled true true + $(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath);%(AdditionalIncludeDirectories) @@ -97,6 +115,7 @@ true true true + $(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath);%(AdditionalIncludeDirectories) true @@ -111,6 +130,7 @@ true true true + $(SolutionDir)\QuicMaf\vendor\spdlog\include;$(IncludePath);%(AdditionalIncludeDirectories) true @@ -126,6 +146,7 @@ + @@ -144,6 +165,7 @@ + diff --git a/QuicMaf/QuicMaf.vcxproj.filters b/QuicMaf/QuicMaf.vcxproj.filters index 17ade45..339cddf 100644 --- a/QuicMaf/QuicMaf.vcxproj.filters +++ b/QuicMaf/QuicMaf.vcxproj.filters @@ -92,5 +92,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/QuicMaf/app.cpp b/QuicMaf/app.cpp index 53cf2d2..4a32ff1 100644 --- a/QuicMaf/app.cpp +++ b/QuicMaf/app.cpp @@ -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; } diff --git a/QuicMaf/maths/Equations.h b/QuicMaf/maths/Equations.h index a4fef7e..c1707b3 100644 --- a/QuicMaf/maths/Equations.h +++ b/QuicMaf/maths/Equations.h @@ -17,8 +17,12 @@ struct Equation { vector lwing; vector 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; } }; diff --git a/QuicMaf/maths/defines.h b/QuicMaf/maths/defines.h index 58dd249..04b4484 100644 --- a/QuicMaf/maths/defines.h +++ b/QuicMaf/maths/defines.h @@ -1,5 +1,6 @@ #ifndef DEFINES_H #define DEFINES_H +#include "../Log.h" #include #include @@ -17,6 +18,7 @@ #include + using namespace std; #define DEF_C -999 diff --git a/QuicMaf/maths/solver/Solver.cpp b/QuicMaf/maths/solver/Solver.cpp index 65b5a49..76d9d0b 100644 --- a/QuicMaf/maths/solver/Solver.cpp +++ b/QuicMaf/maths/solver/Solver.cpp @@ -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 Solver::FlipTermSigns(vector terms) { vector res; @@ -34,8 +87,8 @@ vector Solver::FlipTermSigns(vector 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 Solver::FlipTermSigns(vector 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 terms) { + Equation* equ = new Equation(); + equ->lwing = terms; + return CheckValidOps(equ); +} + +bool Solver::IsVarAval(vector 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(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 Solver::RemNonEssientalOps(vector terms) { vector 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(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 Solver::RemNonEssientalOps(vector 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 Solver::RemNonEssientalOps(vector 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 Solver::RemNonEssientalOps(vector terms) { } res.push_back(term); } - + return res; } vector Solver::AddNonEssientalOps(vector terms) { @@ -358,10 +483,13 @@ vector Solver::AddNonEssientalOps(vector terms) { } if (term->mType == TermTypes::Brack) { - res.push_back(term); + auto resultant = + AddNonEssientalOps(QMEvalHelper::BreakBracket(static_cast(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 Solver::BundleTermsDuo(vector 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 Solver::BundleTermsDuo(vector 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 Solver::BundleTermsTri(vector 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 Solver::BundleTermsTri(vector 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; diff --git a/QuicMaf/maths/solver/Solver.h b/QuicMaf/maths/solver/Solver.h index 267e7b6..5fea2e4 100644 --- a/QuicMaf/maths/solver/Solver.h +++ b/QuicMaf/maths/solver/Solver.h @@ -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 terms); + vector RemoveBrackets(vector terms) { + vector 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(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 FlipTermSigns(vector 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 terms); + + vector RemoveBundle(vector res) { + vector final_res; + + for (int i = 0; i < res.size(); i++) { + if (res[i]->mType == TermTypes::Bund) { + auto result = BreakBundle(static_cast(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); diff --git a/QuicMaf/maths/solver/term_rewriter/QMEvalHelper.cpp b/QuicMaf/maths/solver/term_rewriter/QMEvalHelper.cpp index d318070..51e5d7d 100644 --- a/QuicMaf/maths/solver/term_rewriter/QMEvalHelper.cpp +++ b/QuicMaf/maths/solver/term_rewriter/QMEvalHelper.cpp @@ -48,12 +48,16 @@ vector 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 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 QMEvalHelper::Add(Term * t1, Term * t2, Identifier_t order) { vector QMEvalHelper::Sub(Term * t1, Term * t2, Identifier_t order) { vector res; - // check if one of the terms were brackets if (IsBracket(t1) || IsBracket(t2)) { // check which term is bracket @@ -325,7 +328,7 @@ vector 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 terms1, vector terms2) { } // WARNING: Make sure that t1 and t2 are in the simplest form. vector 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 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 diff --git a/QuicMaf/maths/solver/term_rewriter/QMEvaluator.h b/QuicMaf/maths/solver/term_rewriter/QMEvaluator.h index 59b9437..5eadab5 100644 --- a/QuicMaf/maths/solver/term_rewriter/QMEvaluator.h +++ b/QuicMaf/maths/solver/term_rewriter/QMEvaluator.h @@ -91,9 +91,52 @@ static vector getPool() { return res; } +static vector evaluateRight(vector 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 res; + for (int i = 0; i < mPool.size(); i++) + res.push_back(mPool[i]); + return res; +} + static vector evaluate(vector 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(); } diff --git a/QuicMaf/maths/solver/term_rewriter/ds/ExprTree.cpp b/QuicMaf/maths/solver/term_rewriter/ds/ExprTree.cpp index 16cfb8f..35b8a7c 100644 --- a/QuicMaf/maths/solver/term_rewriter/ds/ExprTree.cpp +++ b/QuicMaf/maths/solver/term_rewriter/ds/ExprTree.cpp @@ -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 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> 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 resultant; + resultant.first = i; + resultant.second = counter++; + operators.push_back(resultant); + } + if (pool[i]->mOperator == '*') { + pair 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 resultant; + resultant.first = i; + resultant.second = counter++; + operators.push_back(resultant); + } + else if (pool[i]->mOperator == '-') { + pair resultant; + resultant.first = i; + resultant.second = counter++; + operators.push_back(resultant); + } + } + } + stable_sort(operators.begin(), operators.end(), + [this](pair arg1, pair 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); + } +} diff --git a/QuicMaf/maths/solver/term_rewriter/ds/ExprTree.h b/QuicMaf/maths/solver/term_rewriter/ds/ExprTree.h index d2356bb..42be0f1 100644 --- a/QuicMaf/maths/solver/term_rewriter/ds/ExprTree.h +++ b/QuicMaf/maths/solver/term_rewriter/ds/ExprTree.h @@ -40,4 +40,24 @@ private: }; +class ExprTreeReversed { +public: + void setPool(vector 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 diff --git a/QuicMaf/maths/tokenizer.h b/QuicMaf/maths/tokenizer.h index 5b7f12f..c39918d 100644 --- a/QuicMaf/maths/tokenizer.h +++ b/QuicMaf/maths/tokenizer.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 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 combineBrackets(vector 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(terms[i + 2])->mTerms; + auto constant = static_cast(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(terms[i + 2])->mTerms; - auto constant = static_cast(terms[i + 2])->mConstant; - constant->mValue *= (term->mOperator == '+') ? +1 : -1; - brack->mConstant = constant; + brack->mTerms = static_cast(terms[i + 1])->mTerms; + auto constant = static_cast(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(terms[i + 1])->mTerms; - auto constant = static_cast(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 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 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 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 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 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 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 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 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 diff --git a/QuicMaf/qm.h b/QuicMaf/qm.h new file mode 100644 index 0000000..8c6e374 --- /dev/null +++ b/QuicMaf/qm.h @@ -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 diff --git a/QuicMaf/vendor/spdlog b/QuicMaf/vendor/spdlog deleted file mode 160000 index 053d5ad..0000000 --- a/QuicMaf/vendor/spdlog +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 053d5ad24d9a58063f2bd71c186cb6adf807ea0a diff --git a/QuicMaf/x64/Release/ExprTree.obj b/QuicMaf/x64/Release/ExprTree.obj deleted file mode 100644 index 7a5ea3e..0000000 Binary files a/QuicMaf/x64/Release/ExprTree.obj and /dev/null differ diff --git a/QuicMaf/x64/Release/QMReducerHelper.obj b/QuicMaf/x64/Release/QMReducerHelper.obj deleted file mode 100644 index b4fccfb..0000000 Binary files a/QuicMaf/x64/Release/QMReducerHelper.obj and /dev/null differ diff --git a/QuicMaf/x64/Release/QMRule.obj b/QuicMaf/x64/Release/QMRule.obj deleted file mode 100644 index 987c3f4..0000000 Binary files a/QuicMaf/x64/Release/QMRule.obj and /dev/null differ diff --git a/QuicMaf/x64/Release/QuicMaf.log b/QuicMaf/x64/Release/QuicMaf.log deleted file mode 100644 index 010a57e..0000000 --- a/QuicMaf/x64/Release/QuicMaf.log +++ /dev/null @@ -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 diff --git a/QuicMaf/x64/Release/QuicMaf.tlog/CL.command.1.tlog b/QuicMaf/x64/Release/QuicMaf.tlog/CL.command.1.tlog deleted file mode 100644 index 344ba31..0000000 Binary files a/QuicMaf/x64/Release/QuicMaf.tlog/CL.command.1.tlog and /dev/null differ diff --git a/QuicMaf/x64/Release/QuicMaf.tlog/CL.read.1.tlog b/QuicMaf/x64/Release/QuicMaf.tlog/CL.read.1.tlog deleted file mode 100644 index bed40a7..0000000 Binary files a/QuicMaf/x64/Release/QuicMaf.tlog/CL.read.1.tlog and /dev/null differ diff --git a/QuicMaf/x64/Release/QuicMaf.tlog/CL.write.1.tlog b/QuicMaf/x64/Release/QuicMaf.tlog/CL.write.1.tlog deleted file mode 100644 index 0bd0ac5..0000000 Binary files a/QuicMaf/x64/Release/QuicMaf.tlog/CL.write.1.tlog and /dev/null differ diff --git a/QuicMaf/x64/Release/QuicMaf.tlog/QuicMaf.write.1u.tlog b/QuicMaf/x64/Release/QuicMaf.tlog/QuicMaf.write.1u.tlog deleted file mode 100644 index e8b38c6..0000000 Binary files a/QuicMaf/x64/Release/QuicMaf.tlog/QuicMaf.write.1u.tlog and /dev/null differ diff --git a/QuicMaf/x64/Release/QuicMaf.tlog/link.command.1.tlog b/QuicMaf/x64/Release/QuicMaf.tlog/link.command.1.tlog deleted file mode 100644 index 2576013..0000000 Binary files a/QuicMaf/x64/Release/QuicMaf.tlog/link.command.1.tlog and /dev/null differ diff --git a/QuicMaf/x64/Release/QuicMaf.tlog/link.read.1.tlog b/QuicMaf/x64/Release/QuicMaf.tlog/link.read.1.tlog deleted file mode 100644 index a681786..0000000 Binary files a/QuicMaf/x64/Release/QuicMaf.tlog/link.read.1.tlog and /dev/null differ diff --git a/QuicMaf/x64/Release/QuicMaf.tlog/link.write.1.tlog b/QuicMaf/x64/Release/QuicMaf.tlog/link.write.1.tlog deleted file mode 100644 index 6d2a79b..0000000 Binary files a/QuicMaf/x64/Release/QuicMaf.tlog/link.write.1.tlog and /dev/null differ diff --git a/QuicMaf/x64/Release/Solver.obj b/QuicMaf/x64/Release/Solver.obj deleted file mode 100644 index 4aab0bd..0000000 Binary files a/QuicMaf/x64/Release/Solver.obj and /dev/null differ diff --git a/QuicMaf/x64/Release/TermPool.obj b/QuicMaf/x64/Release/TermPool.obj deleted file mode 100644 index 8f75e59..0000000 Binary files a/QuicMaf/x64/Release/TermPool.obj and /dev/null differ diff --git a/QuicMaf/x64/Release/app.obj b/QuicMaf/x64/Release/app.obj deleted file mode 100644 index 0fda97b..0000000 Binary files a/QuicMaf/x64/Release/app.obj and /dev/null differ diff --git a/QuicMaf/x64/Release/vc141.pdb b/QuicMaf/x64/Release/vc141.pdb deleted file mode 100644 index 67efd68..0000000 Binary files a/QuicMaf/x64/Release/vc141.pdb and /dev/null differ diff --git a/QuicMafGui/Dashboard.cpp b/QuicMafGui/Dashboard.cpp new file mode 100644 index 0000000..a54b48d --- /dev/null +++ b/QuicMafGui/Dashboard.cpp @@ -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() \ No newline at end of file diff --git a/QuicMafGui/Dashboard.h b/QuicMafGui/Dashboard.h new file mode 100644 index 0000000..e947a05 --- /dev/null +++ b/QuicMafGui/Dashboard.h @@ -0,0 +1,34 @@ +#ifndef DASHBOARD_H +#define DASHBOARD_H +#pragma once +#include + +#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 diff --git a/QuicMafGui/Debug/Dashboard.obj b/QuicMafGui/Debug/Dashboard.obj new file mode 100644 index 0000000..4bcd9bd Binary files /dev/null and b/QuicMafGui/Debug/Dashboard.obj differ diff --git a/QuicMafGui/Debug/QuicMafGui.Build.CppClean.log b/QuicMafGui/Debug/QuicMafGui.Build.CppClean.log new file mode 100644 index 0000000..4c4ac78 --- /dev/null +++ b/QuicMafGui/Debug/QuicMafGui.Build.CppClean.log @@ -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 diff --git a/QuicMafGui/Debug/QuicMafGui.log b/QuicMafGui/Debug/QuicMafGui.log new file mode 100644 index 0000000..b22749e --- /dev/null +++ b/QuicMafGui/Debug/QuicMafGui.log @@ -0,0 +1,2 @@ + qmgui.cpp + QuicMafGui.vcxproj -> R:\Projects\QuicMaf\Debug\QuicMafGui.exe diff --git a/QuicMafGui/Debug/QuicMafGui.tlog/CL.command.1.tlog b/QuicMafGui/Debug/QuicMafGui.tlog/CL.command.1.tlog new file mode 100644 index 0000000..6b63b90 Binary files /dev/null and b/QuicMafGui/Debug/QuicMafGui.tlog/CL.command.1.tlog differ diff --git a/QuicMafGui/Debug/QuicMafGui.tlog/CL.read.1.tlog b/QuicMafGui/Debug/QuicMafGui.tlog/CL.read.1.tlog new file mode 100644 index 0000000..f39533f Binary files /dev/null and b/QuicMafGui/Debug/QuicMafGui.tlog/CL.read.1.tlog differ diff --git a/QuicMafGui/Debug/QuicMafGui.tlog/CL.write.1.tlog b/QuicMafGui/Debug/QuicMafGui.tlog/CL.write.1.tlog new file mode 100644 index 0000000..13a57d0 Binary files /dev/null and b/QuicMafGui/Debug/QuicMafGui.tlog/CL.write.1.tlog differ diff --git a/QuicMaf/x64/Release/QuicMaf.tlog/QuicMaf.lastbuildstate b/QuicMafGui/Debug/QuicMafGui.tlog/QuicMafGui.lastbuildstate similarity index 82% rename from QuicMaf/x64/Release/QuicMaf.tlog/QuicMaf.lastbuildstate rename to QuicMafGui/Debug/QuicMafGui.tlog/QuicMafGui.lastbuildstate index 7102a94..950b7c7 100644 --- a/QuicMaf/x64/Release/QuicMaf.tlog/QuicMaf.lastbuildstate +++ b/QuicMafGui/Debug/QuicMafGui.tlog/QuicMafGui.lastbuildstate @@ -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\| diff --git a/QuicMafGui/Debug/QuicMafGui.tlog/link.command.1.tlog b/QuicMafGui/Debug/QuicMafGui.tlog/link.command.1.tlog new file mode 100644 index 0000000..c8042af Binary files /dev/null and b/QuicMafGui/Debug/QuicMafGui.tlog/link.command.1.tlog differ diff --git a/QuicMafGui/Debug/QuicMafGui.tlog/link.read.1.tlog b/QuicMafGui/Debug/QuicMafGui.tlog/link.read.1.tlog new file mode 100644 index 0000000..2694f77 Binary files /dev/null and b/QuicMafGui/Debug/QuicMafGui.tlog/link.read.1.tlog differ diff --git a/QuicMafGui/Debug/QuicMafGui.tlog/link.write.1.tlog b/QuicMafGui/Debug/QuicMafGui.tlog/link.write.1.tlog new file mode 100644 index 0000000..8b3fb3f Binary files /dev/null and b/QuicMafGui/Debug/QuicMafGui.tlog/link.write.1.tlog differ diff --git a/QuicMafGui/Debug/Source.obj b/QuicMafGui/Debug/Source.obj new file mode 100644 index 0000000..c8f9587 Binary files /dev/null and b/QuicMafGui/Debug/Source.obj differ diff --git a/QuicMafGui/Debug/qmgui.obj b/QuicMafGui/Debug/qmgui.obj new file mode 100644 index 0000000..4f1e216 Binary files /dev/null and b/QuicMafGui/Debug/qmgui.obj differ diff --git a/QuicMafGui/Debug/vc141.idb b/QuicMafGui/Debug/vc141.idb new file mode 100644 index 0000000..a1d5aca Binary files /dev/null and b/QuicMafGui/Debug/vc141.idb differ diff --git a/QuicMafGui/Debug/vc141.pdb b/QuicMafGui/Debug/vc141.pdb new file mode 100644 index 0000000..96678ac Binary files /dev/null and b/QuicMafGui/Debug/vc141.pdb differ diff --git a/QuicMafGui/QuicMafGui.vcxproj b/QuicMafGui/QuicMafGui.vcxproj new file mode 100644 index 0000000..1002890 --- /dev/null +++ b/QuicMafGui/QuicMafGui.vcxproj @@ -0,0 +1,176 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {7CDC5570-9785-446C-8CB9-C03E6D98927F} + QuicMafGui + 10.0.17763.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)bin/$(Configuration)-$(Platform)/ + $(SolutionDir)bin-int/$(Configuration)-$(Platform)/ + + + $(SolutionDir)bin/$(Configuration)-$(Platform)/ + $(SolutionDir)bin-int/$(Configuration)-$(Platform)/ + + + $(SolutionDir)bin/$(Configuration)-$(Platform)/ + $(SolutionDir)bin-int/$(Configuration)-$(Platform)/ + + + $(SolutionDir)bin/$(Configuration)-$(Platform)/ + $(SolutionDir)bin-int/$(Configuration)-$(Platform)/ + + + + Level3 + Disabled + true + true + $(WXWIN)\include;$(WXWIN)\include\msvc;$(SolutionDir)\QuicMaf + WIN32;WINVER=0x0400;__WXMSW__;_WINDOWS;wxUSE_GUI=1;_UNICODE;_DEBUG;__WXDEBUG__;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + wxmsw31ud_core.lib;wxbase31ud.lib;comctl32.lib;rpcrt4.lib;winmm.lib;advapi32.lib;wsock32.lib;%(AdditionalDependencies) + $(WXWIN)\lib\vc_lib;%(AdditionalLibraryDirectories) + Windows + + + + + Level3 + Disabled + true + true + $(WXWIN)\include;$(WXWIN)\include\msvc;$(SolutionDir)\QuicMaf + MultiThreadedDebugDLL + WIN32;WINVER=0x0400;__WXMSW__;_WINDOWS;wxUSE_GUI=1;_UNICODE;_DEBUG;__WXDEBUG__;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + + + $(WXWIN)\lib\vc_x64_lib; + wxmsw31ud_core.lib;wxbase31ud.lib;comctl32.lib;rpcrt4.lib;winmm.lib;advapi32.lib;wsock32.lib;%(AdditionalDependencies) + Windows + + + + + Level3 + MaxSpeed + true + true + true + $(WXWIN)\include;$(WXWIN)\include\msvc;$(SolutionDir)\QuicMaf + WIN32;WINVER=0x0400;__WXMSW__;_WINDOWS;wxUSE_GUI=1;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + true + true + wxmsw31u_core.lib;wxbase31u.lib;comctl32.lib;rpcrt4.lib;winmm.lib;advapi32.lib;wsock32.lib;%(AdditionalDependencies) + $(WXWIN)\lib\vc_lib;%(AdditionalLibraryDirectories) + + + + + Level3 + MaxSpeed + true + true + true + true + $(WXWIN)\include;$(WXWIN)\include\msvc;$(SolutionDir)\QuicMaf + MultiThreadedDLL + WIN32;WINVER=0x0400;__WXMSW__;_WINDOWS;wxUSE_GUI=1;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + + + true + true + $(WXWIN)\lib\vc_x64_lib; + wxmsw31u_core.lib;wxbase31u.lib;comctl32.lib;rpcrt4.lib;winmm.lib;advapi32.lib;wsock32.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + {ea73d661-b6eb-4156-ac92-a470a6683307} + + + + + + \ No newline at end of file diff --git a/QuicMafGui/QuicMafGui.vcxproj.filters b/QuicMafGui/QuicMafGui.vcxproj.filters new file mode 100644 index 0000000..94ea749 --- /dev/null +++ b/QuicMafGui/QuicMafGui.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/QuicMafGui/QuicMafGui.vcxproj.user b/QuicMafGui/QuicMafGui.vcxproj.user new file mode 100644 index 0000000..66eed93 --- /dev/null +++ b/QuicMafGui/QuicMafGui.vcxproj.user @@ -0,0 +1,9 @@ + + + + true + + + WindowsLocalDebugger + + \ No newline at end of file diff --git a/QuicMafGui/dlgs/Evaluator.cpp b/QuicMafGui/dlgs/Evaluator.cpp new file mode 100644 index 0000000..b8b9438 --- /dev/null +++ b/QuicMafGui/dlgs/Evaluator.cpp @@ -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 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() \ No newline at end of file diff --git a/QuicMafGui/dlgs/Solve_dlg.cpp b/QuicMafGui/dlgs/Solve_dlg.cpp new file mode 100644 index 0000000..70fc693 --- /dev/null +++ b/QuicMafGui/dlgs/Solve_dlg.cpp @@ -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() \ No newline at end of file diff --git a/QuicMafGui/dlgs/Solve_dlg.h b/QuicMafGui/dlgs/Solve_dlg.h new file mode 100644 index 0000000..4fc74e9 --- /dev/null +++ b/QuicMafGui/dlgs/Solve_dlg.h @@ -0,0 +1,35 @@ +#ifndef SOLVE_DLG_H +#define SOLVE_DLG_H +#pragma once +#include + +#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 diff --git a/QuicMafGui/dlgs/evaluator.h b/QuicMafGui/dlgs/evaluator.h new file mode 100644 index 0000000..bf93ffa --- /dev/null +++ b/QuicMafGui/dlgs/evaluator.h @@ -0,0 +1,35 @@ +#ifndef EVALUATOR_H +#define EVALUATOR_H +#pragma once +#include + +#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 diff --git a/QuicMafGui/qmgui.cpp b/QuicMafGui/qmgui.cpp new file mode 100644 index 0000000..bf8c90b --- /dev/null +++ b/QuicMafGui/qmgui.cpp @@ -0,0 +1,17 @@ +#include +#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); diff --git a/releases/v1.0/QuicMaf-v1.0.zip b/releases/v1.0/QuicMaf-v1.0.zip new file mode 100644 index 0000000..56ce2cb Binary files /dev/null and b/releases/v1.0/QuicMaf-v1.0.zip differ diff --git a/releases/v1.0/Release-Win32/QuicMaf-x86.exe b/releases/v1.0/Release-Win32/QuicMaf-x86.exe new file mode 100644 index 0000000..5060d9c Binary files /dev/null and b/releases/v1.0/Release-Win32/QuicMaf-x86.exe differ diff --git a/releases/v1.0/Release-Win32/QuicMaf.iobj b/releases/v1.0/Release-Win32/QuicMaf.iobj new file mode 100644 index 0000000..050887f Binary files /dev/null and b/releases/v1.0/Release-Win32/QuicMaf.iobj differ diff --git a/releases/v1.0/Release-Win32/QuicMaf.ipdb b/releases/v1.0/Release-Win32/QuicMaf.ipdb new file mode 100644 index 0000000..f9b4d06 Binary files /dev/null and b/releases/v1.0/Release-Win32/QuicMaf.ipdb differ diff --git a/releases/v1.0/Release-Win32/QuicMaf.pdb b/releases/v1.0/Release-Win32/QuicMaf.pdb new file mode 100644 index 0000000..95b8024 Binary files /dev/null and b/releases/v1.0/Release-Win32/QuicMaf.pdb differ diff --git a/releases/v1.0/Release-x64/QuicMaf-x64.exe b/releases/v1.0/Release-x64/QuicMaf-x64.exe new file mode 100644 index 0000000..cb7dac5 Binary files /dev/null and b/releases/v1.0/Release-x64/QuicMaf-x64.exe differ diff --git a/releases/v1.0/Release-x64/QuicMaf.iobj b/releases/v1.0/Release-x64/QuicMaf.iobj new file mode 100644 index 0000000..a0cf815 Binary files /dev/null and b/releases/v1.0/Release-x64/QuicMaf.iobj differ diff --git a/releases/v1.0/Release-x64/QuicMaf.ipdb b/releases/v1.0/Release-x64/QuicMaf.ipdb new file mode 100644 index 0000000..417b16b Binary files /dev/null and b/releases/v1.0/Release-x64/QuicMaf.ipdb differ diff --git a/releases/v1.0/Release-x64/QuicMaf.pdb b/releases/v1.0/Release-x64/QuicMaf.pdb new file mode 100644 index 0000000..c59a45b Binary files /dev/null and b/releases/v1.0/Release-x64/QuicMaf.pdb differ diff --git a/releases/v1.0r1/QuicMaf-v1.0r1.zip b/releases/v1.0r1/QuicMaf-v1.0r1.zip new file mode 100644 index 0000000..7a1c4b3 Binary files /dev/null and b/releases/v1.0r1/QuicMaf-v1.0r1.zip differ diff --git a/releases/v1.0r1/Release-Win32/QuicMaf-v1.0r1-x86.exe b/releases/v1.0r1/Release-Win32/QuicMaf-v1.0r1-x86.exe new file mode 100644 index 0000000..b09185e Binary files /dev/null and b/releases/v1.0r1/Release-Win32/QuicMaf-v1.0r1-x86.exe differ diff --git a/releases/v1.0r1/Release-Win32/QuicMaf.iobj b/releases/v1.0r1/Release-Win32/QuicMaf.iobj new file mode 100644 index 0000000..43d1beb Binary files /dev/null and b/releases/v1.0r1/Release-Win32/QuicMaf.iobj differ diff --git a/releases/v1.0r1/Release-Win32/QuicMaf.ipdb b/releases/v1.0r1/Release-Win32/QuicMaf.ipdb new file mode 100644 index 0000000..13b3129 Binary files /dev/null and b/releases/v1.0r1/Release-Win32/QuicMaf.ipdb differ diff --git a/releases/v1.0r1/Release-Win32/QuicMaf.pdb b/releases/v1.0r1/Release-Win32/QuicMaf.pdb new file mode 100644 index 0000000..5243401 Binary files /dev/null and b/releases/v1.0r1/Release-Win32/QuicMaf.pdb differ diff --git a/releases/v1.0r1/Release-x64/QuicMaf-v1.0r1-x64.exe b/releases/v1.0r1/Release-x64/QuicMaf-v1.0r1-x64.exe new file mode 100644 index 0000000..e39e0e4 Binary files /dev/null and b/releases/v1.0r1/Release-x64/QuicMaf-v1.0r1-x64.exe differ diff --git a/releases/v1.0r1/Release-x64/QuicMaf.iobj b/releases/v1.0r1/Release-x64/QuicMaf.iobj new file mode 100644 index 0000000..b80d7cf Binary files /dev/null and b/releases/v1.0r1/Release-x64/QuicMaf.iobj differ diff --git a/releases/v1.0r1/Release-x64/QuicMaf.ipdb b/releases/v1.0r1/Release-x64/QuicMaf.ipdb new file mode 100644 index 0000000..2790407 Binary files /dev/null and b/releases/v1.0r1/Release-x64/QuicMaf.ipdb differ diff --git a/releases/v1.0r1/Release-x64/QuicMaf.pdb b/releases/v1.0r1/Release-x64/QuicMaf.pdb new file mode 100644 index 0000000..990a332 Binary files /dev/null and b/releases/v1.0r1/Release-x64/QuicMaf.pdb differ