Refactor interpreter: parse all files before executing them & improve error reporting
This commit is contained in:
parent
39de1cd73c
commit
6aaa58f518
1 changed files with 58 additions and 14 deletions
|
|
@ -5,16 +5,45 @@
|
||||||
#include <pslang/ast/print.hpp>
|
#include <pslang/ast/print.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
int main(int argc, char ** argv) try
|
std::string extract_nth_line(std::filesystem::path const & path, std::size_t n)
|
||||||
|
{
|
||||||
|
std::ifstream file(path);
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
for (size_t i = 1; i <= n && std::getline(file, line); ++i) {
|
||||||
|
if (i == n) {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_error_context(std::filesystem::path const & file, pslang::ast::location const & location)
|
||||||
|
{
|
||||||
|
if (location.begin.line == location.end.line)
|
||||||
|
{
|
||||||
|
std::size_t max_line_number_digits = std::floor(std::log10(location.begin.line)) + 1;
|
||||||
|
|
||||||
|
std::cerr << std::endl;
|
||||||
|
std::cerr << "line " << std::setw(max_line_number_digits) << std::right << location.begin.line << ": ";
|
||||||
|
std::cerr << extract_nth_line(file, location.begin.line) << std::endl;
|
||||||
|
std::cerr << std::string(std::max<std::size_t>(location.begin.column, 1) - 1 + max_line_number_digits + 7, ' ') << std::string(location.end.column - location.begin.column, '^') << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
std::cout << "Usage: psli [ options ] <file1> [ <file2> ... ]\n";
|
std::cout << "Usage: psli [ options ] <file1> [ <file2> ... ]\n";
|
||||||
std::cout << "Available options:\n";
|
std::cout << "Available options:\n";
|
||||||
std::cout << " -t, --trace Trace each line of execution\n";
|
std::cout << " -t, --trace Trace each line of execution\n";
|
||||||
std::cout << " -d, --dump Dump all variables after processing each file\n";
|
std::cout << " -d, --dump Dump all variables after processing all files\n";
|
||||||
std::cout << " -p, --print Print the AST after parsing each file\n";
|
std::cout << " -p, --print Print the AST after parsing each file\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -26,6 +55,9 @@ int main(int argc, char ** argv) try
|
||||||
bool dump = false;
|
bool dump = false;
|
||||||
bool dump_ast = false;
|
bool dump_ast = false;
|
||||||
|
|
||||||
|
std::vector<std::string> filenames;
|
||||||
|
std::vector<ast::statement_list_ptr> parsed;
|
||||||
|
|
||||||
for (int arg = 1; arg < argc; ++arg)
|
for (int arg = 1; arg < argc; ++arg)
|
||||||
{
|
{
|
||||||
if (std::strcmp(argv[arg], "-d") == 0 || std::strcmp(argv[arg], "--dump") == 0)
|
if (std::strcmp(argv[arg], "-d") == 0 || std::strcmp(argv[arg], "--dump") == 0)
|
||||||
|
|
@ -46,21 +78,33 @@ int main(int argc, char ** argv) try
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ast = parser::parse(argv[arg]);
|
try
|
||||||
|
|
||||||
if (dump_ast)
|
|
||||||
{
|
{
|
||||||
ast::print(std::cout, ast);
|
filenames.push_back(argv[arg]);
|
||||||
std::cout << std::flush;
|
parsed.push_back(parser::parse(argv[arg]));
|
||||||
}
|
}
|
||||||
|
catch (pslang::parser::parse_error const & error)
|
||||||
|
{
|
||||||
|
std::cerr << "Parse error at " << error.location() << ":\n " << error.what() << std::endl;
|
||||||
|
print_error_context(argv[arg], error.location());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dump_ast)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < filenames.size(); ++i)
|
||||||
|
{
|
||||||
|
std::cout << "Input file " << filenames[i] << " AST dump:\n\n";
|
||||||
|
ast::print(std::cout, parsed[i]);
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
std::cout << std::flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const & ast : parsed)
|
||||||
interpreter::exec(context, ast);
|
interpreter::exec(context, ast);
|
||||||
|
|
||||||
if (dump)
|
if (dump)
|
||||||
interpreter::dump(std::cout, context);
|
interpreter::dump(std::cout, context);
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (pslang::parser::parse_error const & error)
|
|
||||||
{
|
|
||||||
std::cerr << "Parse error at " << error.location() << ":\n " << error.what() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue