From dda04d885966abf1c771ca27c61216f08f495ecc Mon Sep 17 00:00:00 2001 From: ala89 Date: Wed, 3 Jan 2024 20:30:37 +0100 Subject: [PATCH] Add the stracktrace to RuntimeError --- src/analysis.cpp | 12 ++++++------ src/errors.cpp | 12 ++++++++++++ src/include/errors.h | 13 ++++++++++--- src/include/memory.h | 5 +++-- src/include/types.h | 2 -- src/interpreter.cpp | 15 ++++++++++----- src/main.cpp | 9 ++++++--- src/memory.cpp | 6 ++---- 8 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/analysis.cpp b/src/analysis.cpp index ec987bc..3fa6cc9 100644 --- a/src/analysis.cpp +++ b/src/analysis.cpp @@ -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 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(); diff --git a/src/errors.cpp b/src/errors.cpp index 0503704..7c0b51d 100644 --- a/src/errors.cpp +++ b/src/errors.cpp @@ -56,6 +56,18 @@ string UserError::get_message(void) const { } } +StackTrace& RuntimeError::get_trace(void) { + StackTraceEntry top = { "", 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 history, CodePosition pos) { if (pos.column == -1 || pos.line == -1) return; diff --git a/src/include/errors.h b/src/include/errors.h index 4135836..3dc8a1e 100644 --- a/src/include/errors.h +++ b/src/include/errors.h @@ -56,7 +56,8 @@ enum class ErrorType { using ErrorData = variant; -using StackTrace = vector>; +using StackTraceEntry = tuple; +using StackTrace = vector; 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 { diff --git a/src/include/memory.h b/src/include/memory.h index 5175fc5..c076484 100644 --- a/src/include/memory.h +++ b/src/include/memory.h @@ -4,6 +4,7 @@ #include #include #include +#include #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); diff --git a/src/include/types.h b/src/include/types.h index 8b94074..d639d38 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -206,14 +206,12 @@ struct MemoryVar { EvalResult value; Type type; bool initialized; - CodePosition declarationPos; }; struct Scope { unordered_map vars; int depth; ScopeType type; - CodePosition entry_pos; MemoryVar* fn; }; diff --git a/src/interpreter.cpp b/src/interpreter.cpp index 88ddf5f..fe96fc5 100644 --- a/src/interpreter.cpp +++ b/src/interpreter.cpp @@ -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(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)); diff --git a/src/main.cpp b/src/main.cpp index a71ed6a..cfdc764 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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; } diff --git a/src/memory.cpp b/src/memory.cpp index bb6c306..037879b 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -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) {