error.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #pragma once
  2. #include "namedict.h"
  3. #include "tuplelist.h"
  4. struct NeedMoreLines {
  5. NeedMoreLines(bool is_compiling_class) : is_compiling_class(is_compiling_class) {}
  6. bool is_compiling_class;
  7. };
  8. struct HandledException {};
  9. struct UnhandledException {};
  10. struct ToBeRaisedException {};
  11. enum CompileMode {
  12. EXEC_MODE,
  13. EVAL_MODE,
  14. REPL_MODE,
  15. JSON_MODE,
  16. };
  17. struct SourceData {
  18. const char* source;
  19. Str filename;
  20. std::vector<const char*> line_starts;
  21. CompileMode mode;
  22. std::pair<const char*,const char*> get_line(int lineno) const {
  23. if(lineno == -1) return {nullptr, nullptr};
  24. lineno -= 1;
  25. if(lineno < 0) lineno = 0;
  26. const char* _start = line_starts.at(lineno);
  27. const char* i = _start;
  28. while(*i != '\n' && *i != '\0') i++;
  29. return {_start, i};
  30. }
  31. SourceData(const char* source, Str filename, CompileMode mode) {
  32. source = strdup(source);
  33. // Skip utf8 BOM if there is any.
  34. if (strncmp(source, "\xEF\xBB\xBF", 3) == 0) source += 3;
  35. this->filename = filename;
  36. this->source = source;
  37. line_starts.push_back(source);
  38. this->mode = mode;
  39. }
  40. Str snapshot(int lineno, const char* cursor=nullptr){
  41. StrStream ss;
  42. ss << " " << "File \"" << filename << "\", line " << lineno << '\n';
  43. std::pair<const char*,const char*> pair = get_line(lineno);
  44. Str line = "<?>";
  45. int removed_spaces = 0;
  46. if(pair.first && pair.second){
  47. line = Str(pair.first, pair.second-pair.first).lstrip();
  48. removed_spaces = pair.second - pair.first - line.size();
  49. if(line.empty()) line = "<?>";
  50. }
  51. ss << " " << line;
  52. if(cursor && line != "<?>" && cursor >= pair.first && cursor <= pair.second){
  53. auto column = cursor - pair.first - removed_spaces;
  54. if(column >= 0) ss << "\n " << std::string(column, ' ') << "^";
  55. }
  56. return ss.str();
  57. }
  58. ~SourceData() { free((void*)source); }
  59. };
  60. namespace pkpy{
  61. class Exception {
  62. StrName type;
  63. Str msg;
  64. std::stack<Str> stacktrace;
  65. public:
  66. Exception(StrName type, Str msg): type(type), msg(msg) {}
  67. bool match_type(StrName type) const { return this->type == type;}
  68. bool is_re = true;
  69. void st_push(Str snapshot){
  70. if(stacktrace.size() >= 8) return;
  71. stacktrace.push(snapshot);
  72. }
  73. Str summary() const {
  74. std::stack<Str> st(stacktrace);
  75. StrStream ss;
  76. if(is_re) ss << "Traceback (most recent call last):\n";
  77. while(!st.empty()) { ss << st.top() << '\n'; st.pop(); }
  78. if (!msg.empty()) ss << type.str() << ": " << msg;
  79. else ss << type.str();
  80. return ss.str();
  81. }
  82. };
  83. }