Move error handling and interpreter functionality to different files

This commit is contained in:
Abdelrahman Said 2025-06-08 15:09:15 +01:00
parent cd7ce538b6
commit 1a0207687c
5 changed files with 85 additions and 62 deletions

View 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;
}

View 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
View 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
View File

@ -0,0 +1,3 @@
#pragma once
void run_interpreter(int argc, char *argv[]);

View File

@ -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;
}