diff options
author | David Robillard <d@drobilla.net> | 2010-04-08 20:09:16 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-04-08 20:09:16 +0000 |
commit | 55b6a3f313670d2cb13847d1f1b04fe3e4b21d63 (patch) | |
tree | 200b7dbe00107507e8111b07747bef2cd3f6a958 /src/resp.cpp | |
parent | 9d9fa6162295f3813d20f7a3ad4e07ccd6087c3c (diff) | |
download | resp-55b6a3f313670d2cb13847d1f1b04fe3e4b21d63.tar.gz resp-55b6a3f313670d2cb13847d1f1b04fe3e4b21d63.tar.bz2 resp-55b6a3f313670d2cb13847d1f1b04fe3e4b21d63.zip |
Tuplr -> Resp (RESource Processing).
git-svn-id: http://svn.drobilla.net/resp/resp@252 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/resp.cpp')
-rw-r--r-- | src/resp.cpp | 149 |
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; +} |