Add the stracktrace to RuntimeError

This commit is contained in:
ala89 2024-01-03 20:30:37 +01:00
parent 2d8316d7ff
commit dda04d8859
8 changed files with 49 additions and 25 deletions

View File

@ -214,7 +214,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
throw RuntimeError(ErrorType::AlreadyDeclaredIdentifier, token.pos, identifier);
Type type = try_string_to_type(type_string, type_token.pos);
memory.declare(identifier, type, type_token.pos);
memory.declare(identifier, type);
return {};
} break;
@ -229,7 +229,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
throw RuntimeError(ErrorType::AlreadyDeclaredIdentifier, token.pos, identifier);
Type type = try_string_to_type(type_string, type_token.pos);
memory.declare(identifier, type, type_token.pos);
memory.declare(identifier, type);
get_cast(type, analyze(node.children[2], memory), get_node_pos(node));
@ -295,7 +295,7 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
}
}
memory.declare(function_name, type, return_type_token.pos);
memory.declare(function_name, type);
return {};
} break;
@ -335,16 +335,16 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
}
}
memory.declare(function_name, type, return_type_token.pos);
memory.declare(function_name, type);
memory.update(function_name, node.children[3]);
memory.add_scope(ScopeType::Function, token.pos, &memory.get(function_name));
memory.add_scope(ScopeType::Function, &memory.get(function_name));
for (tuple<Type, string> variable : prototype) {
Type vtype = get<0>(variable);
string vname = get<1>(variable);
memory.declare(vname, vtype, token.pos);
memory.declare(vname, vtype);
}
analyze(node.children[3], memory);
memory.remove_scope();

View File

@ -56,6 +56,18 @@ string UserError::get_message(void) const {
}
}
StackTrace& RuntimeError::get_trace(void) {
StackTraceEntry top = { "<repl>", lastPos };
trace.push_back(top);
return trace;
}
void RuntimeError::add_call(string callName, CodePosition callPos) {
StackTraceEntry entry = { callName, lastPos };
trace.push_back(entry);
lastPos = callPos;
}
void print_error_position(vector<string> history, CodePosition pos) {
if (pos.column == -1 || pos.line == -1)
return;

View File

@ -56,7 +56,8 @@ enum class ErrorType {
using ErrorData = variant<monostate, string, int>;
using StackTrace = vector<tuple<string, CodePosition>>;
using StackTraceEntry = tuple<string, CodePosition>;
using StackTrace = vector<StackTraceEntry>;
class UserError : public exception {
public:
@ -93,11 +94,17 @@ public:
};
class RuntimeError : public UserError {
private:
StackTrace trace;
CodePosition lastPos;
public:
explicit RuntimeError(ErrorType type, CodePosition pos, ErrorData data = {})
: UserError(type, pos, data), trace() {}
: UserError(type, pos, data), trace(), lastPos() {}
const StackTrace trace;
StackTrace& get_trace(void);
void add_call(string name, CodePosition pos);
};
class InternalError : public exception {

View File

@ -4,6 +4,7 @@
#include <string>
#include <iostream>
#include <iomanip>
#include <optional>
#include "types.h"
#include "colors.h"
using namespace std;
@ -12,12 +13,12 @@ class Memory {
public:
bool contains(string identifier);
bool contains_top(string identifier);
void add_scope(ScopeType type, CodePosition entry_pos = { }, MemoryVar* fn = NULL);
void add_scope(ScopeType type, MemoryVar* fn = NULL);
void remove_scope(void);
MemoryVar& get(string identifier);
Scope& get_function_scope(void);
void declare(string identifier, Type type, CodePosition pos = { });
void declare(string identifier, Type type);
void update(string identifier, EvalResult value);
Scope& _debug_top(void);

View File

@ -206,14 +206,12 @@ struct MemoryVar {
EvalResult value;
Type type;
bool initialized;
CodePosition declarationPos;
};
struct Scope {
unordered_map<string, MemoryVar> vars;
int depth;
ScopeType type;
CodePosition entry_pos;
MemoryVar* fn;
};

View File

@ -157,7 +157,7 @@ EvalResult eval(Node &ast, Memory &memory) {
memory.declare(identifier, {
.type = TypeType::Function,
.data = prototype
}, retTypeTok.pos);
});
return {};
} break;
@ -171,7 +171,7 @@ EvalResult eval(Node &ast, Memory &memory) {
memory.declare(identifier, {
.type = TypeType::Function,
.data = prototype
}, retTypeTok.pos);
});
memory.update(identifier, node.children[3]);
@ -196,7 +196,7 @@ EvalResult eval(Node &ast, Memory &memory) {
EvalResult res = {};
memory.add_scope(ScopeType::Function, identifierTok.pos, &var);
memory.add_scope(ScopeType::Function, &var);
try {
for (size_t i = 1; i < prototype.size(); i++) {
@ -221,6 +221,11 @@ EvalResult eval(Node &ast, Memory &memory) {
memory.remove_scope();
}
catch (RuntimeError& e) {
e.add_call(identifier, identifierTok.pos);
throw;
}
catch (...) {
memory.remove_scope();
@ -414,7 +419,7 @@ EvalResult eval(Node &ast, Memory &memory) {
string identifier = get<string>(identifierTok.data);
Type type = string_to_type(typeName);
memory.declare(identifier, type, typeTok.pos);
memory.declare(identifier, type);
return {};
} break;
@ -426,7 +431,7 @@ EvalResult eval(Node &ast, Memory &memory) {
EvalResult value = eval(node.children[2], memory);
Type type = string_to_type(typeName);
memory.declare(identifier, type, typeTok.pos);
memory.declare(identifier, type);
if (type.type == TypeType::Int) {
memory.update(identifier, int_cast(value));

View File

@ -118,9 +118,12 @@ int main(int argc, char* argv[]) {
print_error_position(input, e.pos);
cout << BOLD RED "Type Error: " RESET << e.get_message() << endl;
} catch (const RuntimeError& e) {
// print_error_position(input, e.pos);
// cout << BOLD RED "Runtime Error: " RESET << e.get_message() << endl;
} catch (RuntimeError& e) {
print_error_position(input, e.pos);
cout << BOLD RED "Runtime Error: " RESET << e.get_message() << endl;
for (auto e : e.get_trace()) {
cout << get<0>(e) << " " << (get<1>(e).line + 1) << endl;
}
}
cout << endl;
}

View File

@ -22,12 +22,11 @@ bool Memory::contains_top(string identifier) {
return top.vars.contains(identifier);
}
void Memory::add_scope(ScopeType type, CodePosition entry_pos, MemoryVar* fn) {
void Memory::add_scope(ScopeType type, MemoryVar* fn) {
Scope& top = scopes.back();
scopes.emplace_back();
scopes.back().depth = top.depth + 1;
scopes.back().type = type;
scopes.back().entry_pos = entry_pos;
scopes.back().fn = fn;
}
@ -54,10 +53,9 @@ Scope& Memory::get_function_scope(void) {
throw InternalError();
}
void Memory::declare(string identifier, Type type, CodePosition pos) {
void Memory::declare(string identifier, Type type) {
Scope& top = scopes.back();
top.vars[identifier].type = type;
top.vars[identifier].declarationPos = pos;
}
void Memory::update(string identifier, EvalResult value) {