File indexing completed on 2024-05-12 05:26:19
0001 /* 0002 * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org> 0003 * 0004 * This program is free software; you can redistribute it and/or modify 0005 * it under the terms of the GNU General Public License as published by 0006 * the Free Software Foundation; either version 2 of the License, or 0007 * (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 0016 * Free Software Foundation, Inc., 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 0018 */ 0019 0020 #include <QtGlobal> //For Q_OS_WIN 0021 #ifdef Q_OS_WIN 0022 #include <io.h> 0023 #else 0024 #include <unistd.h> 0025 #endif 0026 0027 #include <QCoreApplication> 0028 #include <QDebug> 0029 #include <QFile> 0030 #include <QTextStream> 0031 0032 #include "syntaxtree.h" 0033 // #include "jsonlistener.h" 0034 #include "repl/repl.h" 0035 0036 /* 0037 * modes of operation: 0038 * 0039 * 1. called with no commands: start the REPL 0040 * 2. called with -: listen for commands on stdin 0041 * 3. called with a filename: try to run it as a script 0042 * 4. called with commands: try to match to syntax and run the result 0043 */ 0044 0045 int enterRepl() 0046 { 0047 if (State::hasEventLoop()) { 0048 return 0; 0049 } 0050 0051 Repl *repl = new Repl; 0052 QObject::connect(repl, &QStateMachine::finished, repl, &QObject::deleteLater); 0053 QObject::connect(repl, &QStateMachine::finished, QCoreApplication::instance(), &QCoreApplication::quit); 0054 0055 State::setHasEventLoop(true); 0056 int rv = QCoreApplication::instance()->exec(); 0057 State::setHasEventLoop(false); 0058 return rv; 0059 } 0060 0061 bool goInteractive(const QStringList &, State &) 0062 { 0063 enterRepl(); 0064 return true; 0065 } 0066 0067 Syntax::List goInteractiveSyntax() 0068 { 0069 Syntax interactive("go_interactive", QString(), &goInteractive); 0070 return Syntax::List() << interactive; 0071 } 0072 0073 void processCommandStream(QTextStream &stream) 0074 { 0075 SyntaxTree::self()->registerSyntax(&goInteractiveSyntax); 0076 QString line = stream.readLine(); 0077 while (!line.isEmpty()) { 0078 line = line.trimmed(); 0079 0080 if (!line.isEmpty() && !line.startsWith('#')) { 0081 SyntaxTree::self()->run(SyntaxTree::tokenize(line)); 0082 } 0083 0084 line = stream.readLine(); 0085 } 0086 } 0087 0088 int main(int argc, char *argv[]) 0089 { 0090 const bool interactive = isatty(fileno(stdin)); 0091 const bool startRepl = (argc == 1) && interactive; 0092 // TODO: make a json command parse cause that would be awesomesauce 0093 const bool fromScript = !startRepl && QFile::exists(argv[1]); 0094 0095 // qDebug() << "state at startup is" << interactive << startRepl << fromScript; 0096 0097 QCoreApplication app(argc, argv); 0098 app.setApplicationName(fromScript ? "interactive-app-shell" : argv[0]); 0099 0100 if (startRepl) { 0101 return enterRepl(); 0102 } else if (fromScript) { 0103 QFile f(argv[1]); 0104 if (!f.open(QIODevice::ReadOnly)) { 0105 return 1; 0106 } 0107 0108 QTextStream inputStream(&f); 0109 processCommandStream(inputStream); 0110 } else if (!interactive) { 0111 QTextStream inputStream(stdin); 0112 processCommandStream(inputStream); 0113 } else { 0114 QStringList commands = app.arguments(); 0115 commands.removeFirst(); 0116 return SyntaxTree::self()->run(commands); 0117 } 0118 }