File indexing completed on 2024-04-21 03:41:33

0001 /*************************************************************************************
0002  *  Copyright (C) 2007 by Aleix Pol <aleixpol@kde.org>                               *
0003  *                                                                                   *
0004  *  This program is free software; you can redistribute it and/or                    *
0005  *  modify it under the terms of the GNU General Public License                      *
0006  *  as published by the Free Software Foundation; either version 2                   *
0007  *  of the License, or (at your option) any later version.                           *
0008  *                                                                                   *
0009  *  This program is distributed in the hope that it will be useful,                  *
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
0012  *  GNU General Public License for more details.                                     *
0013  *                                                                                   *
0014  *  You should have received a copy of the GNU General Public License                *
0015  *  along with this program; if not, write to the Free Software                      *
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0017  *************************************************************************************/
0018 
0019 #include <analitza/expression.h>
0020 #include <analitza/analyzer.h>
0021 
0022 #include <readline/readline.h>
0023 #include <readline/history.h>
0024 #include <QElapsedTimer>
0025 #include <QFile>
0026 
0027 using namespace std;
0028 
0029 using Analitza::Expression;
0030 
0031 Analitza::Analyzer a;
0032 
0033 enum CalcType { Evaluate, Calculate };
0034 
0035 static const char* prompt=">>> ";
0036 static const char* insidePrompt="... ";
0037 
0038 struct Config {
0039     CalcType calcType;
0040     bool showElapsedType;
0041 };
0042 static Config configuration;
0043 
0044 void calculate(const Expression& e, CalcType t)
0045 {
0046     Expression ans;
0047     a.setExpression(e);
0048     if(e.isCorrect()) {
0049         QElapsedTimer time;
0050         if(configuration.showElapsedType) time.start();
0051         
0052         if(t==Calculate)
0053             ans=a.calculate();
0054         else
0055             ans=a.evaluate();
0056         
0057         if(configuration.showElapsedType) qDebug() << "Ellapsed time: " << time.elapsed();
0058     }
0059     
0060     if(a.isCorrect()) {
0061         qDebug() << qPrintable(ans.toString());
0062         a.insertVariable(QStringLiteral("ans"), ans);
0063     } else {
0064         const QStringList errors = a.errors();
0065         qDebug() << "Error:";
0066         for (const QString &err : errors)
0067             qDebug() << " -" << qPrintable(err);
0068     }
0069 }
0070 
0071 int main(int argc, char *argv[])
0072 {
0073     configuration.calcType=Evaluate;
0074     configuration.showElapsedType=false;
0075     
0076     for(int i=1; i<argc; ++i) {
0077         QByteArray arg=argv[i];
0078         if(arg=="--print-time")
0079             configuration.showElapsedType=true;
0080         else if(arg=="--calculate")
0081             configuration.calcType=Calculate;
0082         else if(arg=="--evaluate")
0083             configuration.calcType=Evaluate;
0084         else if(arg=="--help" || arg=="-h") {
0085             qDebug() << "This is KAlgebra console version";
0086             qDebug() << "Use: " << argv[0] << "[Options] ...";
0087             qDebug() << "\t--evaluate:\tTries to simplify symbolically before calculating";
0088             qDebug() << "\t--calculate:\tCalculates straight away. If some symbol is missing, it will fail";
0089             qDebug() << "\t--print-time:\tOutputs the ellapsed time of an operation";
0090             qDebug() << "\t--help:\t\twill print this help";
0091             qDebug() << "\t...\t\tfiles that will be executed first";
0092             return 0;
0093         } else {
0094             QFile f(QString::fromUtf8(arg));
0095             if(!f.open(QIODevice::ReadOnly)) {
0096                 qWarning() << "File not found: " << arg;
0097                 return 1;
0098             }
0099             
0100             QTextStream str(&f);
0101             a.importScript(&str);
0102             
0103             if(!a.isCorrect()) {
0104                 const QStringList errors = a.errors();
0105                 qDebug() << "Error:";
0106                 for(const QString &err : errors)
0107                     qDebug() << " -" << qPrintable(err);
0108             }
0109         }
0110     }
0111     
0112     bool done=false;
0113     bool inside=false;
0114     
0115     using_history();
0116     QString entry;
0117     while(!done) {
0118         char * expr;
0119         if(inside)
0120             expr=readline(insidePrompt);
0121         else
0122             expr=readline(prompt);
0123         
0124         if(!expr)
0125             done=true;
0126         else if(*expr==0) {
0127             inside=false;
0128             entry.clear();
0129         } else {
0130             add_history(expr);
0131             entry+=QString::fromUtf8(expr);
0132             
0133             if(Expression::isCompleteExpression(entry)) {
0134                 Expression e(entry);
0135 //                 qDebug() << entry << e.toString();
0136                 calculate(e, configuration.calcType);
0137                 inside =false;
0138                 entry.clear();
0139             } else {
0140                 inside =true;
0141             }
0142         }
0143     }
0144     
0145     for(int i=0; i<history_get_history_state()->length; i++) {
0146         HIST_ENTRY *he = remove_history(i);
0147 #ifdef HAVE_FREE_HISTORY_ENTRY
0148         free_history_entry(he);
0149 #else
0150         free((void*)he->line);
0151         free(he);
0152 #endif
0153     }
0154     qDebug("\nExit.");
0155     return 0;
0156 }