aboutsummaryrefslogtreecommitdiffstats
path: root/src/resp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/resp.cpp')
-rw-r--r--src/resp.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/resp.cpp b/src/resp.cpp
new file mode 100644
index 0000000..003a76c
--- /dev/null
+++ b/src/resp.cpp
@@ -0,0 +1,149 @@
+/* Resp: A programming language
+ * Copyright (C) 2008-2009 David Robillard <dave@drobilla.net>
+ *
+ * Resp is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Affero General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * Resp is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Resp. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * @brief Main program
+ */
+
+#include <cerrno>
+#include <cstring>
+#include <fstream>
+#include "resp.hpp"
+
+using namespace std;
+
+GC Object::pool(8 * 1024 * 1024);
+
+int
+print_usage(char* name, bool error)
+{
+ ostream& os = error ? cerr : cout;
+ os << "Usage: " << name << " [OPTION]... [FILE]..." << endl;
+ os << "Evaluate and/or compile Resp code" << endl;
+ os << endl;
+ os << " -h Display this help and exit" << endl;
+ os << " -r Enter REPL after evaluating files" << endl;
+ os << " -p Pretty-print input only" << endl;
+ os << " -b BACKEND Backend (llvm or c)" << endl;
+ os << " -g Debug (disable optimisation)" << endl;
+ os << " -d Dump assembly output" << endl;
+ os << " -e EXPRESSION Evaluate EXPRESSION" << endl;
+ os << " -o FILE Compile output to FILE (don't run)" << endl;
+ return error ? 1 : 0;
+}
+
+int
+main(int argc, char** argv)
+{
+ // Read command line arguments
+ map<string,string> args;
+ list<string> files;
+ for (int i = 1; i < argc; ++i) {
+ if (!strncmp(argv[i], "-h", 3)) {
+ return print_usage(argv[0], false);
+ } else if (argv[i][0] != '-') {
+ files.push_back(argv[i]);
+ } else if (!strncmp(argv[i], "-r", 3)
+ || !strncmp(argv[i], "-p", 3)
+ || !strncmp(argv[i], "-g", 3)
+ || !strncmp(argv[i], "-d", 3)) {
+ args.insert(make_pair(argv[i], ""));
+ } else if (i == argc-1 || argv[i+1][0] == '-') {
+ return print_usage(argv[0], true);
+ } else {
+ args.insert(make_pair(argv[i], argv[i+1]));
+ ++i;
+ }
+ }
+
+ PEnv penv;
+ TEnv tenv(penv);
+ initLang(penv, tenv);
+
+ Engine* engine = NULL;
+
+ map<string,string>::const_iterator a = args.find("-b");
+ const string backend_name = (a != args.end() ? a->second : "llvm");
+
+ if (backend_name == "llvm")
+ engine = resp_new_llvm_engine();
+ else if (backend_name == "c")
+ engine = resp_new_c_engine();
+
+ if (!engine) {
+ std::cerr << "Unable to open backend " << backend_name << std::endl;
+ return 1;
+ }
+
+ CEnv* cenv = new CEnv(penv, tenv, engine);
+ cenv->args = args;
+
+ Object::pool.lock();
+
+ int ret = 0;
+
+ a = args.find("-o");
+ bool batch = a != args.end();
+ const string output = (a != args.end()) ? a->second : "";
+
+ if (args.find("-p") != args.end()) {
+ ifstream is(files.front().c_str());
+ if (is.good()) {
+ Cursor loc;
+ AST* exp = readExpression(loc, is);
+ AST* ast = penv.parse(exp);
+ pprint(cout, ast);
+ }
+ return 0;
+ }
+
+ a = args.find("-e");
+ if (a != args.end()) {
+ istringstream is(a->second);
+ ret = eval(*cenv, "(command line)", is, !batch);
+ }
+
+ for (list<string>::iterator f = files.begin(); f != files.end(); ++f) {
+ ifstream is(f->c_str());
+ if (is.good()) {
+ ret = ret | eval(*cenv, *f, is, !batch);
+ } else {
+ cerr << argv[0] << ": " << *f << ": " << strerror(errno) << endl;
+ ++ret;
+ }
+ is.close();
+ }
+
+ if (args.find("-r") != args.end() || (files.empty() && args.find("-e") == args.end()))
+ ret = repl(*cenv);
+
+ if (output != "") {
+ ofstream os(output.c_str());
+ if (os.good()) {
+ cenv->engine()->writeModule(*cenv, os);
+ } else {
+ cerr << argv[0] << ": " << a->second << ": " << strerror(errno) << endl;
+ ++ret;
+ }
+ os.close();
+ }
+
+ delete cenv;
+ delete engine;
+
+ return ret;
+}