Move error handling and interpreter functionality to different files
This commit is contained in:
parent
cd7ce538b6
commit
1a0207687c
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 "scanner.hh"
|
||||
#include "interpreter.hh"
|
||||
#include "error_handler.hh"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <sysexits.h>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#define PROMPT "> "
|
||||
|
||||
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);
|
||||
ErrorHandler error_handler{};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc > 2) {
|
||||
@ -23,53 +11,7 @@ int main(int argc, char *argv[]) {
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
run_file(argv[1]);
|
||||
} else {
|
||||
run_prompt();
|
||||
}
|
||||
run_interpreter(argc, argv);
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user