• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*=============================================================================
2      Copyright (c) 2001-2011 Joel de Guzman
3      Copyright (c) 2001-2011 Hartmut Kaiser
4  
5      Distributed under the Boost Software License, Version 1.0. (See accompanying
6      file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  =============================================================================*/
8  ///////////////////////////////////////////////////////////////////////////////
9  //
10  //  Not a calculator anymore, right? :-)
11  //
12  //  [ JDG April 10, 2007 ]      spirit2
13  //  [ JDG February 18, 2011 ]   Pure attributes. No semantic actions.
14  //  [ HK June 3, 2011 ]         Adding lexer
15  //
16  ///////////////////////////////////////////////////////////////////////////////
17  
18  #include "config.hpp"
19  #include "function.hpp"
20  #include "vm.hpp"
21  #include "compiler.hpp"
22  #include "lexer.hpp"
23  #include <boost/lexical_cast.hpp>
24  #include <fstream>
25  
26  ///////////////////////////////////////////////////////////////////////////////
27  //  Main program
28  ///////////////////////////////////////////////////////////////////////////////
main(int argc,char ** argv)29  int main(int argc, char **argv)
30  {
31      char const* filename;
32      if (argc > 1)
33      {
34          filename = argv[1];
35      }
36      else
37      {
38          std::cerr << "Error: No input file provided." << std::endl;
39          return 1;
40      }
41  
42      std::ifstream in(filename, std::ios_base::in);
43  
44      if (!in)
45      {
46          std::cerr << "Error: Could not open input file: "
47              << filename << std::endl;
48          return 1;
49      }
50  
51      std::string source_code; // We will read the contents here.
52      in.unsetf(std::ios::skipws); // No white space skipping!
53      std::copy(
54          std::istream_iterator<char>(in),
55          std::istream_iterator<char>(),
56          std::back_inserter(source_code));
57  
58      typedef std::string::const_iterator base_iterator_type;
59      typedef client::lexer::conjure_tokens<base_iterator_type> lexer_type;
60      typedef lexer_type::iterator_type iterator_type;
61  
62      lexer_type lexer;                           // Our lexer
63  
64      base_iterator_type first = source_code.begin();
65      base_iterator_type last = source_code.end();
66  
67      iterator_type iter = lexer.begin(first, last);
68      iterator_type end = lexer.end();
69  
70      client::vmachine vm;                        // Our virtual machine
71      client::ast::function_list ast;             // Our AST
72  
73      client::error_handler<base_iterator_type, iterator_type>
74          error_handler(first, last);             // Our error handler
75      client::parser::function<iterator_type, lexer_type>
76          function(error_handler, lexer);         // Our parser
77      client::code_gen::compiler
78          compiler(error_handler);                // Our compiler
79  
80      // note: we don't need a skipper
81      bool success = parse(iter, end, +function, ast);
82  
83      std::cout << "-------------------------\n";
84  
85      if (success && iter == end)
86      {
87          if (compiler(ast))
88          {
89              boost::shared_ptr<client::code_gen::function>
90                  p  = compiler.find_function("main");
91              if (!p)
92                  return 1;
93  
94              int nargs = argc-2;
95              if (p->nargs() != nargs)
96              {
97                  std::cerr << "Error: main function requires " << p->nargs() << " arguments." << std::endl;
98                  std::cerr << nargs << " supplied." << std::endl;
99                  return 1;
100              }
101  
102              std::cout << "Success\n";
103              std::cout << "-------------------------\n";
104              std::cout << "Assembler----------------\n\n";
105              compiler.print_assembler();
106  
107              // Push the arguments into our stack
108              for (int i = 0; i < nargs; ++i)
109                  vm.get_stack()[i] = boost::lexical_cast<int>(argv[i+2]);
110  
111              // Call the interpreter
112              int r = vm.execute(compiler.get_code());
113  
114              std::cout << "-------------------------\n";
115              std::cout << "Result: " << r << std::endl;
116              std::cout << "-------------------------\n\n";
117          }
118          else
119          {
120              std::cout << "Compile failure\n";
121          }
122      }
123      else
124      {
125          error_handler.dump_error_line(first);
126          std::cout << "Parse failure\n";
127      }
128      return 0;
129  }
130  
131  
132