| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- #pragma once
- #include "safestl.h"
- struct NeedMoreLines {
- NeedMoreLines(bool is_compiling_class) : is_compiling_class(is_compiling_class) {}
- bool is_compiling_class;
- };
- struct HandledException {};
- struct UnhandledException {};
- struct ToBeRaisedException {};
- enum CompileMode {
- EXEC_MODE,
- EVAL_MODE,
- REPL_MODE,
- JSON_MODE,
- };
- struct SourceData {
- const char* source;
- _Str filename;
- std::vector<const char*> line_starts;
- CompileMode mode;
- std::pair<const char*,const char*> get_line(int lineno) const {
- if(lineno == -1) return {nullptr, nullptr};
- lineno -= 1;
- if(lineno < 0) lineno = 0;
- const char* _start = line_starts.at(lineno);
- const char* i = _start;
- while(*i != '\n' && *i != '\0') i++;
- return {_start, i};
- }
- SourceData(const char* source, _Str filename, CompileMode mode) {
- source = strdup(source);
- // Skip utf8 BOM if there is any.
- if (strncmp(source, "\xEF\xBB\xBF", 3) == 0) source += 3;
- this->filename = filename;
- this->source = source;
- line_starts.push_back(source);
- this->mode = mode;
- }
- _Str snapshot(int lineno, const char* cursor=nullptr){
- _StrStream ss;
- ss << " " << "File \"" << filename << "\", line " << lineno << '\n';
- std::pair<const char*,const char*> pair = get_line(lineno);
- _Str line = "<?>";
- int removed_spaces = 0;
- if(pair.first && pair.second){
- line = _Str(pair.first, pair.second-pair.first).lstrip();
- removed_spaces = pair.second - pair.first - line.size();
- if(line.empty()) line = "<?>";
- }
- ss << " " << line;
- if(cursor && line != "<?>" && cursor >= pair.first && cursor <= pair.second){
- auto column = cursor - pair.first - removed_spaces;
- if(column >= 0) ss << "\n " << std::string(column, ' ') << "^";
- }
- return ss.str();
- }
- ~SourceData() { free((void*)source); }
- };
- class _Exception {
- _Str type;
- _Str msg;
- std::stack<_Str> stacktrace;
- public:
- _Exception(_Str type, _Str msg): type(type), msg(msg) {}
- bool match_type(const _Str& type) const { return this->type == type;}
- bool is_re = true;
- void st_push(_Str snapshot){
- if(stacktrace.size() >= 8) return;
- stacktrace.push(snapshot);
- }
- _Str summary() const {
- std::stack<_Str> st(stacktrace);
- _StrStream ss;
- if(is_re) ss << "Traceback (most recent call last):\n";
- while(!st.empty()) { ss << st.top() << '\n'; st.pop(); }
- ss << type << ": " << msg;
- return ss.str();
- }
- };
|