Initial commit
[minnow.git] / src / minnow / main.cpp
blob32e017b57cd70d972015803ebc0ba8b2f8e2d327
1 #include <iostream>
2 #include <fstream>
3 #include <vector>
5 #include <stdlib.h>
7 #include <boost/program_options.hpp>
9 #include "parser.hpp"
10 #include "analyser.hpp"
11 #include "codegen_cppoutput.hpp"
13 namespace po = boost::program_options;
15 int main(int argc, char *argv[]) {
16 std::string outfile_name = "";
17 std::string outexe_name = "";
18 bool output_debug = false;
19 std::vector<Token*> allToks;
20 CodegenCPPOutput cppoutput;
21 Analyser analyser;
23 po::options_description general_opts("General options");
24 general_opts.add_options()
25 ("help,h", "help message")
26 ("debugtree,t", "output debug parse tree")
27 ("tocppfile,c", po::value<std::string>(), "output to C++ file")
28 ("toexe,o", po::value<std::string>(), "(attempt to) compile to an exe")
30 po::options_description hidden_opts("Hidden options");
31 hidden_opts.add_options()
32 ("input-file", po::value< std::vector<std::string> >(), "input file")
34 po::positional_options_description p;
35 p.add("input-file", -1);
37 po::options_description visible_opts("");
38 visible_opts.add(general_opts);
40 po::options_description all_opts("All options");
41 all_opts.add(general_opts).add(hidden_opts);
44 po::variables_map vm;
45 //po::store(po::parse_command_line(argc, argv, desc), vm);
46 po::store(po::command_line_parser(argc, argv).options(all_opts).positional(p).run(), vm);
47 po::notify(vm);
49 std::ostringstream headerBlock;
50 headerBlock << "extern int convertToInt(string s)" << std::endl;
51 headerBlock << "extern void puti(int i)" << std::endl;
52 headerBlock << "extern void putstring(string s)" << std::endl;
53 headerBlock << "extern void exit(int i)" << std::endl;
54 std::vector<Token*> toksPrelude = tokenize(headerBlock.str(), "standard include");
55 allToks.insert(allToks.end(), toksPrelude.begin(), toksPrelude.end());
57 if (vm.count("help")) {
58 std::cout << "Usage: minnow <options> <input files>" << std::endl;
59 std::cout << visible_opts << std::endl;
60 return 0;
63 if (vm.count("debugtree")) {
64 output_debug = true;
67 if (vm.count("tocppfile")) {
68 //std::cout << "Outputing to: " << vm["tocppfile"].as<std::string>() << std::endl;
69 outfile_name = vm["tocppfile"].as<std::string>();
72 if (vm.count("toexe")) {
73 //std::cout << "Outputing to: " << vm["tocppfile"].as<std::string>() << std::endl;
74 outexe_name = vm["toexe"].as<std::string>();
77 if (vm.count("input-file")) {
78 //std::cout << "Input files are: " << std::endl;
79 std::vector<std::string> files = vm["input-file"].as< std::vector<std::string> >();
80 for (std::vector<std::string>::iterator iter = files.begin(), end = files.end(); iter != end; ++iter) {
81 std::ifstream sourceFile(iter->c_str(), std::ios::binary);
82 if (sourceFile.good()) {
83 // get length of file:
84 sourceFile.seekg (0, std::ios::end);
85 int length = sourceFile.tellg();
86 sourceFile.seekg (0, std::ios::beg);
88 char *fBuffer = new char[length+1];
89 sourceFile.read(fBuffer, length);
90 fBuffer[length] = 0;
91 std::string sourceCode(fBuffer);
93 //std::string sourceFilename(argv[i]);
95 //printf("Size: %i %i\n", length, strlen(fBuffer));
96 //puts(fBuffer);
98 std::vector<Token*> toks = tokenize(sourceCode, *iter);
99 if (output_debug) {
100 std::vector<Token*>::iterator beginToks = toks.begin(), endToks = toks.end();
101 ASTNode *astDebug = parse(beginToks, endToks);
102 std::cout << "Source file: " << *iter << std::endl;
103 analyser.debugOutputPass(astDebug, 0);
106 allToks.insert(allToks.end(), toks.begin(), toks.end());
109 else {
110 std::cout << "Can not find file: " << *iter << std::endl;
111 exit(1);
115 else {
116 std::cout << "Usage: minnow <options> <input files>" << std::endl;
117 std::cout << visible_opts << std::endl;
118 return 0;
121 std::vector<Token*>::iterator beginToks = allToks.begin(), endToks = allToks.end();
123 try {
125 ASTNode *ast = parse(beginToks, endToks);
126 ast = analyser.scopeAndTypesPass(ast);
127 std::string output = cppoutput.translate(ast);
129 if (outexe_name != "") {
130 std::ofstream outfile;
131 outfile.open("tmpXXXXX.cpp");
132 outfile << output;
133 outfile.close();
134 std::ostringstream exe_cmdline;
136 //Linux (tested on Ubuntu w/ boost 1.35 packages)
137 //exe_cmdline << "g++ -O3 -o " << outexe_name << " tmpXXXXX.cpp -Isrc/aquarium -L. -laquarium -lboost_thread";
139 //OS X + MacPorts
140 exe_cmdline << "g++ -O3 -o " << outexe_name << " tmpXXXXX.cpp -Isrc/aquarium -L. -laquarium -I/opt/local/include/boost-1_35 -L/opt/local/lib -lboost_thread-mt -lboost_program_options-mt";
142 //MinGW+Boost setup
143 //exe_cmdline << "g++ -O3 -o " << outexe_name << " tmpXXXXX.cpp -Isrc/aquarium -L. -laquarium -I/mingw/include -L/mingw/lib -lboost_thread -lboost_program_options";
144 //exe_cmdline << "g++ -ggdb -O3 -o " << outexe_name << " tmpXXXXX.cpp -I../../aquarium -L. -laquarium -I/mingw/include -L/mingw/lib -lboost_thread -lboost_program_options";
146 if (system(exe_cmdline.str().c_str()) == 0) {
147 //remove("tmpXXXXX.cpp");
149 else {
150 std::cout << "Used cmdline: " << exe_cmdline.str() << std::endl;
153 else if (outfile_name != "") {
154 std::ofstream outfile;
155 outfile.open(outfile_name.c_str());
156 outfile << output;
157 outfile.close();
159 else {
160 //std::cout << output;
163 catch (CompilerException &ce) {
164 std::cout << "Error: " << ce.what() << std::endl;