error.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #pragma once
  2. #include "safestl.h"
  3. struct NeedMoreLines {
  4. NeedMoreLines(bool isClassDef) : isClassDef(isClassDef) {}
  5. bool isClassDef;
  6. };
  7. struct HandledException {};
  8. struct UnhandledException {};
  9. struct ToBeRaisedException {};
  10. enum CompileMode {
  11. EXEC_MODE,
  12. EVAL_MODE,
  13. SINGLE_MODE, // for REPL
  14. JSON_MODE,
  15. };
  16. struct SourceData {
  17. const char* source;
  18. _Str filename;
  19. std::vector<const char*> lineStarts;
  20. CompileMode mode;
  21. std::pair<const char*,const char*> getLine(int lineno) const {
  22. if(lineno == -1) return {nullptr, nullptr};
  23. lineno -= 1;
  24. if(lineno < 0) lineno = 0;
  25. const char* _start = lineStarts.at(lineno);
  26. const char* i = _start;
  27. while(*i != '\n' && *i != '\0') i++;
  28. return {_start, i};
  29. }
  30. SourceData(const char* source, _Str filename, CompileMode mode) {
  31. source = strdup(source);
  32. // Skip utf8 BOM if there is any.
  33. if (strncmp(source, "\xEF\xBB\xBF", 3) == 0) source += 3;
  34. this->filename = filename;
  35. this->source = source;
  36. lineStarts.push_back(source);
  37. this->mode = mode;
  38. }
  39. _Str snapshot(int lineno, const char* cursor=nullptr){
  40. _StrStream ss;
  41. ss << " " << "File \"" << filename << "\", line " << lineno << '\n';
  42. std::pair<const char*,const char*> pair = getLine(lineno);
  43. _Str line = "<?>";
  44. int removedSpaces = 0;
  45. if(pair.first && pair.second){
  46. line = _Str(pair.first, pair.second-pair.first).__lstrip();
  47. removedSpaces = pair.second - pair.first - line.size();
  48. if(line.empty()) line = "<?>";
  49. }
  50. ss << " " << line;
  51. if(cursor && line != "<?>" && cursor >= pair.first && cursor <= pair.second){
  52. auto column = cursor - pair.first - removedSpaces;
  53. if(column >= 0) ss << "\n " << std::string(column, ' ') << "^";
  54. }
  55. return ss.str();
  56. }
  57. ~SourceData(){
  58. free((void*)source);
  59. }
  60. };
  61. class _Exception {
  62. _Str type;
  63. _Str msg;
  64. std::stack<_Str> stacktrace;
  65. public:
  66. _Exception(_Str type, _Str msg): type(type), msg(msg) {}
  67. bool match_type(const _Str& 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. ss << type << ": " << msg;
  79. return ss.str();
  80. }
  81. };