Skip to content
Snippets Groups Projects
Commit 80995caa authored by Mattias Ajander's avatar Mattias Ajander
Browse files

Improved main file with tokens, ast and debug settings.

parent abc49b99
Branches
No related tags found
No related merge requests found
......@@ -55,6 +55,18 @@ public:
*/
void set_file(const std::string& filePath);
/**
* @brief Gets the current log level
* @return LogLevel The current log level
*/
LogLevel get_level() const;
/**
* @brief Sets the log level
* @param level The log level to set
*/
void set_level(LogLevel level);
/**
* @brief Gets the current log file path
* @return std::string The current log file path
......@@ -94,6 +106,7 @@ private:
std::string log_path; ///< Path to the log file
std::ofstream log_file; ///< Output stream for the log file
LogLevel log_level; ///< Current log level
};
/**
......
......@@ -3,7 +3,7 @@
namespace funk
{
Logger::Logger() : log_path("funk.log")
Logger::Logger() : log_path("funk.log"), log_level(LogLevel::INFO)
{
file_open();
}
......@@ -22,6 +22,7 @@ Logger& Logger::instance()
void Logger::log(LogLevel level, const std::string& message)
{
file_open();
if (level < log_level) return;
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
......@@ -60,6 +61,16 @@ std::string Logger::get_file() const
return log_path;
}
void Logger::set_level(LogLevel level)
{
log_level = level;
}
LogLevel Logger::get_level() const
{
return log_level;
}
void Logger::file_open()
{
if (log_file.is_open()) return;
......
......@@ -5,20 +5,31 @@
using namespace funk;
// Command line options
HashMap<String, String> options{
{"--help", "Display this help message"},
{"--log <file>", "Set the log file"},
{"--debug", "Enable debug logging"},
{"--ast", "Log the AST representation"},
{"--tokens", "Log the lexical tokens"},
};
int main(int argc, char* argv[])
// Configuration for command line options
struct Config
{
ArgParser parser(argc, argv);
bool debug{false};
bool ast{false};
bool tokens{false};
};
// Process command line arguments and set up logging
bool setup(ArgParser& parser, Config& config)
{
// Print help message
if (argc == 1 || parser.has_option("--help"))
if (parser.has_option("--help"))
{
cout << ArgParser::help("funk [options] <file>", options) << "\n";
return 0;
return false;
}
// Set log file if specified
......@@ -27,27 +38,86 @@ int main(int argc, char* argv[])
if (!parser.has_value("--log"))
{
cerr << "No log file specified!\n";
return 1;
return false;
}
logger().set_file(parser.get_option("--log"));
}
// Configure logging level
if (parser.has_option("--debug"))
{
config.debug = true;
logger().set_level(LogLevel::DEBUG);
}
// Check if any files were specified
if (!parser.has_files())
{
cerr << "No files specified!\n";
return 1;
return false;
}
// Lex each file
for (const auto& file : parser.get_files())
// Set other configuration options
config.ast = parser.has_option("--ast");
config.tokens = parser.has_option("--tokens");
return true;
}
// Process a single file
void process_file(const String& file, const Config& config)
{
LOG_INFO("Processing file: " + file);
try
{
Parser parser{Parser::load(file)};
Node* result{parser.parse()};
LOG_DEBUG("Lexing file...");
Lexer lexer{read_file(file), file};
Vector<Token> tokens{lexer.tokenize()};
LOG_DEBUG("Tokens lexed!");
if (config.tokens)
{
LOG_INFO("Tokens:");
for (const auto& token : tokens) { LOG_INFO(token); }
}
cout << result->to_s() << " = " << result->evaluate()->to_s() << '\n';
LOG_DEBUG("Parsing file...");
Parser parser{tokens, file};
Node* ast = parser.parse();
LOG_DEBUG("File parsed!");
if (config.ast) { LOG_INFO("AST: " + ast->to_s()); }
LOG_DEBUG("Evaluating AST...");
Node* res{ast->evaluate()};
LOG_DEBUG("AST evaluated!");
LOG_INFO("Result: " + res->to_s());
}
catch (const FunkError& e)
{
LOG_ERROR("Error processing file " + file + ": " + e.what());
cerr << "Error: " << e.trace() << '\n';
}
}
int main(int argc, char* argv[])
{
ArgParser parser(argc, argv);
Config config;
// Show help if no arguments provided
if (argc == 1)
{
cout << ArgParser::help("funk [options] <file>", options) << "\n";
return 0;
}
// Setup and validate arguments
if (!setup(parser, config)) { return 1; }
// Process each file
for (const auto& file : parser.get_files()) { process_file(file, config); }
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment