Move error handling and interpreter functionality to different files
This commit is contained in:
		
							
								
								
									
										11
									
								
								cclox_src/error_handler.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								cclox_src/error_handler.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					#include "error_handler.hh"
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ErrorHandler::error(int line, const std::string &message) {
 | 
				
			||||||
 | 
					  report(line, "", message);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ErrorHandler::report(int line, const std::string &where, const std::string &message) {
 | 
				
			||||||
 | 
					  std::cout << "[line " << line << "] Error" << where << ": " << message << '\n';
 | 
				
			||||||
 | 
					  had_error = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								cclox_src/error_handler.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								cclox_src/error_handler.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ErrorHandler {
 | 
				
			||||||
 | 
					  ErrorHandler() : had_error{false} {};
 | 
				
			||||||
 | 
					  void error(int line, const std::string &message);
 | 
				
			||||||
 | 
					  void report(int line, const std::string &where, const std::string &message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool had_error;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										56
									
								
								cclox_src/interpreter.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								cclox_src/interpreter.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					#include "interpreter.hh"
 | 
				
			||||||
 | 
					#include "error_handler.hh"
 | 
				
			||||||
 | 
					#include "scanner.hh"
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <sysexits.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PROMPT "> "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern ErrorHandler error_handler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void run_file(const char *path);
 | 
				
			||||||
 | 
					void run_prompt();
 | 
				
			||||||
 | 
					void run(const std::string &code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void run_interpreter(int argc, char *argv[]) {
 | 
				
			||||||
 | 
					  if (argc == 2) {
 | 
				
			||||||
 | 
					    run_file(argv[1]);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    run_prompt();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void run_file(const char *path) {
 | 
				
			||||||
 | 
					  if (std::ifstream source_code{path, std::ios::ate}) {
 | 
				
			||||||
 | 
					    uint64_t size = source_code.tellg();
 | 
				
			||||||
 | 
					    std::string code(size, '\0');
 | 
				
			||||||
 | 
					    source_code.seekg(0);
 | 
				
			||||||
 | 
					    source_code.read(&code[0], size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    run(code);
 | 
				
			||||||
 | 
					    if (error_handler.had_error) {
 | 
				
			||||||
 | 
					      exit(EX_DATAERR);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void run_prompt() {
 | 
				
			||||||
 | 
					  std::string line{};
 | 
				
			||||||
 | 
					  std::cout << PROMPT;
 | 
				
			||||||
 | 
					  while (std::getline(std::cin, line)) {
 | 
				
			||||||
 | 
					    run(line);
 | 
				
			||||||
 | 
					    std::cout << PROMPT;
 | 
				
			||||||
 | 
					    error_handler.had_error = false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void run(const std::string &code) {
 | 
				
			||||||
 | 
					  Scanner scanner{code};
 | 
				
			||||||
 | 
					  std::vector<Token> tokens = scanner.scan_tokens();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (const auto &token : tokens) {
 | 
				
			||||||
 | 
					    std::cout << token << '\n';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								cclox_src/interpreter.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								cclox_src/interpreter.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void run_interpreter(int argc, char *argv[]);
 | 
				
			||||||
@@ -1,21 +1,9 @@
 | 
				
			|||||||
#include "token.hh"
 | 
					#include "interpreter.hh"
 | 
				
			||||||
#include "scanner.hh"
 | 
					#include "error_handler.hh"
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
#include <fstream>
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <sysexits.h>
 | 
					#include <sysexits.h>
 | 
				
			||||||
#include <cstdint>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PROMPT "> "
 | 
					ErrorHandler error_handler{};
 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool had_error = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void run_file(const char *path);
 | 
					 | 
				
			||||||
void run_prompt();
 | 
					 | 
				
			||||||
void run(const std::string &code);
 | 
					 | 
				
			||||||
void error(int line, const std::string &message);
 | 
					 | 
				
			||||||
void report(int line, const std::string &where, const std::string &message);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char *argv[]) {
 | 
					int main(int argc, char *argv[]) {
 | 
				
			||||||
  if (argc > 2) {
 | 
					  if (argc > 2) {
 | 
				
			||||||
@@ -23,53 +11,7 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
    exit(EX_USAGE);
 | 
					    exit(EX_USAGE);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (argc == 2) {
 | 
					  run_interpreter(argc, argv);
 | 
				
			||||||
    run_file(argv[1]);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    run_prompt();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
void run_file(const char *path) {
 | 
					 | 
				
			||||||
  if (std::ifstream source_code{path, std::ios::ate}) {
 | 
					 | 
				
			||||||
    uint64_t size = source_code.tellg();
 | 
					 | 
				
			||||||
    std::string code(size, '\0');
 | 
					 | 
				
			||||||
    source_code.seekg(0);
 | 
					 | 
				
			||||||
    source_code.read(&code[0], size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    run(code);
 | 
					 | 
				
			||||||
    if (had_error) {
 | 
					 | 
				
			||||||
      exit(EX_DATAERR);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void run_prompt() {
 | 
					 | 
				
			||||||
  std::string line{};
 | 
					 | 
				
			||||||
  std::cout << PROMPT;
 | 
					 | 
				
			||||||
  while (std::getline(std::cin, line)) {
 | 
					 | 
				
			||||||
    run(line);
 | 
					 | 
				
			||||||
    std::cout << PROMPT;
 | 
					 | 
				
			||||||
    had_error = false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void run(const std::string &code) {
 | 
					 | 
				
			||||||
  Scanner scanner{code};
 | 
					 | 
				
			||||||
  std::vector<Token> tokens = scanner.scan_tokens();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for (auto token : tokens) {
 | 
					 | 
				
			||||||
    std::cout << token << '\n';
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void error(int line, const std::string &message) {
 | 
					 | 
				
			||||||
  report(line, "", message);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void report(int line, const std::string &where, const std::string &message) {
 | 
					 | 
				
			||||||
  std::cout << "[line " << line << "] Error" << where << ": " << message << '\n';
 | 
					 | 
				
			||||||
  had_error = true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user