diff --git a/scripts/loc.py b/scripts/loc.py index d121863d..97e0ac5c 100644 --- a/scripts/loc.py +++ b/scripts/loc.py @@ -8,12 +8,16 @@ def get_loc(path): def get_loc_for_dir(path): loc = 0 + loc_ex = 0 for root, dirs, files in os.walk(path): for file in files: if file.endswith('.h'): _i = get_loc(os.path.join(root, file)) print(f"{file}: {_i}") - loc += _i - return loc + if file.startswith('_'): + loc_ex += _i + else: + loc += _i + return f'{loc} (+{loc_ex})' print(get_loc_for_dir('src')) \ No newline at end of file diff --git a/src/compiler.h b/src/compiler.h index b0ad3782..8ff028cd 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -884,8 +884,7 @@ __LISTCOMP: consume(TK("@id")); int dummy_t = co()->add_name(parser->prev.str(), NAME_SPECIAL); if(match(TK("("))){ - EXPR(); - consume(TK(")")); + EXPR(); consume(TK(")")); }else{ emit(OP_LOAD_NONE); } @@ -1077,7 +1076,11 @@ __LISTCOMP: return parser->src->snapshot(lineno, cursor); } - void syntaxError(_Str msg){ throw CompileError("SyntaxError", msg, getLineSnapshot()); } - void indentationError(_Str msg){ throw CompileError("IndentationError", msg, getLineSnapshot()); } - void unexpectedError(_Str msg){ throw CompileError("UnexpectedError", msg, getLineSnapshot()); } + void __throw_e(_Str type, _Str msg){ + auto e = _Error0("SyntaxError", msg, false); + e.st_push(getLineSnapshot()); + throw e; + } + void syntaxError(_Str msg){ __throw_e("SyntaxError", msg); } + void indentationError(_Str msg){ __throw_e("IndentationError", msg); } }; \ No newline at end of file diff --git a/src/error.h b/src/error.h index 9c0ce0bc..a4b85d92 100644 --- a/src/error.h +++ b/src/error.h @@ -52,12 +52,10 @@ struct SourceMetadata { removedSpaces = pair.second - pair.first - line.size(); if(line.empty()) line = ""; } - ss << " " << line << '\n'; + ss << " " << line; if(cursor && line != "" && cursor >= pair.first && cursor <= pair.second){ auto column = cursor - pair.first - removedSpaces; - if(column >= 0){ - ss << " " << std::string(column, ' ') << "^\n"; - } + if(column >= 0) ss << "\n " << std::string(column, ' ') << "^"; } return ss.str(); } @@ -69,37 +67,24 @@ struct SourceMetadata { typedef pkpy::shared_ptr _Source; -class _Error : public std::exception { -private: - _Str _what; +class _Error0 : public std::exception { + _Str type; + _Str msg; + bool is_runtime_error; + std::stack<_Str> stacktrace; + + mutable _Str _what_cached; public: - _Error(_Str type, _Str msg, _Str desc){ - _what = desc + type + ": " + msg; - } + _Error0(_Str type, _Str msg, bool is_runtime_error): type(type), msg(msg), is_runtime_error(is_runtime_error) {} + void st_push(_Str snapshot){ stacktrace.push(snapshot); } const char* what() const noexcept override { - return _what.c_str(); - } -}; - -class CompileError : public _Error { -public: - CompileError(_Str type, _Str msg, _Str snapshot) - : _Error(type, msg, snapshot) {} -}; - -class RuntimeError : public _Error { -private: - static _Str __concat(std::stack<_Str> snapshots){ + std::stack<_Str> st(stacktrace); _StrStream ss; - ss << "Traceback (most recent call last):" << '\n'; - while(!snapshots.empty()){ - ss << snapshots.top(); - snapshots.pop(); - } - return ss.str(); + if(is_runtime_error) ss << "Traceback (most recent call last):\n"; + while(!st.empty()) { ss << st.top() << '\n'; st.pop(); } + ss << type << ": " << msg; + _what_cached = ss.str(); + return _what_cached.c_str(); } -public: - RuntimeError(_Str type, _Str msg, const std::stack<_Str>& snapshots) - : _Error(type, msg, __concat(snapshots)) {} }; \ No newline at end of file diff --git a/src/pocketpy.h b/src/pocketpy.h index 115d54b9..0dd7514b 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -8,10 +8,11 @@ _Code VM::compile(_Str source, _Str filename, CompileMode mode) { Compiler compiler(this, source.c_str(), filename, mode); try{ return compiler.__fillCode(); - }catch(_Error& e){ + }catch(_Error0& e){ throw e; }catch(std::exception& e){ - throw CompileError("UnexpectedError", e.what(), compiler.getLineSnapshot()); + compiler.__throw_e("UnexpectedError", e.what()); + return nullptr; } } diff --git a/src/vm.h b/src/vm.h index 50812dea..6dcf484e 100644 --- a/src/vm.h +++ b/src/vm.h @@ -520,13 +520,17 @@ public: if(_module == nullptr) _module = _main; try { _Code code = compile(source, filename, mode); - //if(filename != "") std::cout << disassemble(code) << std::endl; return _exec(code, _module, pkpy::make_shared()); - }catch (const _Error& e){ + }catch (const _Error0& e){ *_stderr << e.what() << '\n'; } catch (const std::exception& e) { - auto re = RuntimeError("UnexpectedError", e.what(), _cleanErrorAndGetSnapshots()); + auto re = _Error0("UnexpectedError", e.what(), false); + auto snapshots = _cleanErrorAndGetSnapshots(); + while(!snapshots.empty()){ + re.st_push(snapshots.top()); + snapshots.pop(); + } *_stderr << re.what() << '\n'; } return nullptr; @@ -535,7 +539,7 @@ public: template Frame* __push_new_frame(Args&&... args){ if(callstack.size() > maxRecursionDepth){ - throw RuntimeError("RecursionError", "maximum recursion depth exceeded", _cleanErrorAndGetSnapshots()); + _error("RecursionError", "maximum recursion depth exceeded"); } callstack.emplace_back(std::make_unique(std::forward(args)...)); return callstack.back().get(); @@ -888,7 +892,13 @@ public: /***** Error Reporter *****/ private: void _error(const _Str& name, const _Str& msg){ - throw RuntimeError(name, msg, _cleanErrorAndGetSnapshots()); + auto e = _Error0(name, msg, true); + std::stack<_Str> snapshots = _cleanErrorAndGetSnapshots(); + while (!snapshots.empty()){ + e.st_push(snapshots.top()); + snapshots.pop(); + } + throw e; } std::stack<_Str> _cleanErrorAndGetSnapshots(){