aboutsummaryrefslogtreecommitdiffstats
path: root/tuplr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tuplr.cpp')
-rw-r--r--tuplr.cpp87
1 files changed, 87 insertions, 0 deletions
diff --git a/tuplr.cpp b/tuplr.cpp
index 6df6fec..121bd6d 100644
--- a/tuplr.cpp
+++ b/tuplr.cpp
@@ -15,6 +15,11 @@
* along with Tuplr. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <cerrno>
+#include <cstring>
+#include <fstream>
+#include <set>
+#include <sstream>
#include <stack>
#include "tuplr.hpp"
@@ -88,3 +93,85 @@ readExpression(Cursor& cur, std::istream& in)
return SExp(cur);
}
+
+/***************************************************************************
+ * EVAL/REPL/MAIN *
+ ***************************************************************************/
+
+int
+print_usage(char* name, bool error)
+{
+ std::ostream& os = error ? std::cerr : std::cout;
+ os << "Usage: " << name << " [OPTION]... [FILE]..." << endl;
+ os << "Evaluate and/or compile Tuplr code" << endl;
+ os << endl;
+ os << " -h Display this help and exit" << endl;
+ os << " -r Enter REPL after evaluating files" << endl;
+ os << " -e EXPRESSION Evaluate EXPRESSION" << endl;
+ os << " -o FILE Write assembly output to FILE" << endl;
+ return error ? 1 : 0;
+}
+
+int
+main(int argc, char** argv)
+{
+ PEnv penv;
+ TEnv tenv(penv);
+ initLang(penv, tenv);
+
+ CEnv* cenv = newCenv(penv, tenv);
+
+ 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)) {
+ 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;
+ }
+ }
+
+ int ret = 0;
+ map<string,string>::iterator a = args.find("-e");
+ if (a != args.end()) {
+ istringstream is(a->second);
+ ret = eval(*cenv, "(command line)", is);
+ }
+
+ 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);
+ } else {
+ std::cerr << argv[0] << ": " << *f << ": " << strerror(errno) << endl;
+ ++ret;
+ }
+ is.close();
+ }
+
+ if (files.empty() || args.find("-r") != args.end())
+ ret = repl(*cenv);
+
+ a = args.find("-o");
+ if (a != args.end()) {
+ std::ofstream os(a->second.c_str());
+ if (os.good()) {
+ cenv->write(os);
+ } else {
+ cerr << argv[0] << ": " << a->second << ": " << strerror(errno) << endl;
+ ++ret;
+ }
+ os.close();
+ }
+
+ delete cenv;
+ return ret;
+}
+