aboutsummaryrefslogtreecommitdiffstats
path: root/src/resp.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-12-01 06:06:38 +0000
committerDavid Robillard <d@drobilla.net>2010-12-01 06:06:38 +0000
commit8972c175088b1cd083989ff9c07f59143a59fb69 (patch)
tree9135a433ddc72b429c420925787bc8c5d39469c7 /src/resp.cpp
parentea984b91ae477310ac7226fb56338a40531b07cb (diff)
downloadresp-8972c175088b1cd083989ff9c07f59143a59fb69.tar.gz
resp-8972c175088b1cd083989ff9c07f59143a59fb69.tar.bz2
resp-8972c175088b1cd083989ff9c07f59143a59fb69.zip
Add -T option to type-check and pretty-print with type annotations.
Rename -p to -P (all 'stage' options, i.e. -P -T -S are uppercase for consistency). Clean up main program. Decent pretty printing. git-svn-id: http://svn.drobilla.net/resp/resp@275 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/resp.cpp')
-rw-r--r--src/resp.cpp125
1 files changed, 68 insertions, 57 deletions
diff --git a/src/resp.cpp b/src/resp.cpp
index 1f2c5c3..4da92e3 100644
--- a/src/resp.cpp
+++ b/src/resp.cpp
@@ -35,15 +35,16 @@ print_usage(char* name, bool error)
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 Use backend (llvm or c)" << endl;
- os << " -g Debug (disable optimisation)" << endl;
- os << " -d Dump generated code during compilation" << endl;
- os << " -S Stop after compilation (output assembler)" << endl;
- os << " -e EXPRESSION Evaluate EXPRESSION" << endl;
- os << " -o FILE Compile output to FILE (don't run)" << endl;
+ os << " -h Display this help and exit" << endl;
+ os << " -r Enter REPL after evaluating files" << endl;
+ os << " -b BACKEND Use backend (llvm or c)" << endl;
+ os << " -g Debug (disable optimisation)" << endl;
+ os << " -d Dump generated code during compilation" << endl;
+ os << " -P Parse and pretty-print only" << endl;
+ os << " -T Type check and annotate only" << endl;
+ os << " -S Compile to assembly only (do not evaluate)" << endl;
+ os << " -e EXPRESSION Evaluate EXPRESSION" << endl;
+ os << " -o FILE Compile output to FILE (don't run)" << endl;
return error ? 1 : 0;
}
@@ -59,10 +60,11 @@ main(int argc, char** argv)
} 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)
- || !strncmp(argv[i], "-S", 3)) {
+ || !strncmp(argv[i], "-g", 3)
+ || !strncmp(argv[i], "-d", 3)
+ || !strncmp(argv[i], "-P", 3)
+ || !strncmp(argv[i], "-T", 3)
+ || !strncmp(argv[i], "-S", 3)) {
args.insert(make_pair(argv[i], ""));
} else if (i == argc-1 || argv[i+1][0] == '-') {
return print_usage(argv[0], true);
@@ -99,58 +101,67 @@ main(int argc, char** argv)
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);
- }
- delete cenv;
- 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);
+ const bool batch = (a != args.end());
+ string output = batch ? a->second : "";
- if (cenv->args.find("-S") != cenv->args.end() || cenv->args.find("-d") != cenv->args.end()) {
+ if (args.find("-P") != args.end()) { // Pretty-print input
ofstream fs;
if (output != "")
fs.open(output.c_str());
- ostream& os = (output != "") ? fs : cout;
-
- if (os.good()) {
- cenv->engine()->writeModule(*cenv, os);
- } else {
- cerr << argv[0] << ": " << a->second << ": " << strerror(errno) << endl;
- ++ret;
+ ostream& os = (output == "") ? std::cout : fs;
+ for (list<string>::iterator f = files.begin(); f != files.end(); ++f) {
+ ifstream is(f->c_str());
+ try {
+ while (is.good() && !is.eof()) {
+ Cursor loc(*f);
+ AST* exp = readExpression(loc, is);
+ AST* ast = penv.parse(exp);
+ pprint(os, ast, cenv, false);
+ is.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Skip newlines
+ }
+ } catch (Error e) {
+ }
+ is.close();
+ }
+ ret = 0;
+
+ } else if (args.find("-e") != args.end()) { // Evaluate argument as expression
+ if (files.size() > 0) {
+ std::cerr << "Illegal options: both -e and files given" << std::endl;
+ delete cenv;
+ delete engine;
+ return print_usage(argv[0], true);
+ }
+
+ std::istringstream is(a->second);
+ Cursor cursor("(command line)");
+ ret = eval(*cenv, cursor, is, !batch);
+
+ } else if (files.size() == 0) { // Neither -e nor files given, run repl
+ ret = repl(*cenv);
+
+ } else { // Evalute (or just type check if -T, or just compile if -S all files
+ for (list<string>::iterator f = files.begin(); f != files.end(); ++f) {
+ const string& filename = *f;
+ if (!batch)
+ output = filename + ".out";
+
+ ifstream is(f->c_str());
+ if (is.good()) {
+ Cursor cursor(*f);
+ ret = ret | eval(*cenv, cursor, is, !batch);
+ } else {
+ cerr << argv[0] << ": " << *f << ": " << strerror(errno) << endl;
+ ++ret;
+ }
+ is.close();
}
- if (output != "")
- fs.close();
}
+ if (args.find("-r") != args.end()) // Run REPL after evaluations
+ ret = repl(*cenv);
+
delete cenv;
delete engine;