1
0

error.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #include "pocketpy/error.h"
  2. namespace pkpy{
  3. SourceData::SourceData(const Str& source, const Str& filename, CompileMode mode) {
  4. int index = 0;
  5. // Skip utf8 BOM if there is any.
  6. if (strncmp(source.begin(), "\xEF\xBB\xBF", 3) == 0) index += 3;
  7. // Replace all '\r' with ' '
  8. std::stringstream ss;
  9. while(index < source.length()){
  10. if(source[index] == '\r') ss << ' ';
  11. else ss << source[index];
  12. index++;
  13. }
  14. this->filename = filename;
  15. this->source = ss.str();
  16. line_starts.push_back(this->source.c_str());
  17. this->mode = mode;
  18. }
  19. std::pair<const char*,const char*> SourceData::get_line(int lineno) const {
  20. if(lineno == -1) return {nullptr, nullptr};
  21. lineno -= 1;
  22. if(lineno < 0) lineno = 0;
  23. const char* _start = line_starts.at(lineno);
  24. const char* i = _start;
  25. while(*i != '\n' && *i != '\0') i++;
  26. return {_start, i};
  27. }
  28. Str SourceData::snapshot(int lineno, const char* cursor){
  29. std::stringstream ss;
  30. ss << " " << "File \"" << filename << "\", line " << lineno << '\n';
  31. std::pair<const char*,const char*> pair = get_line(lineno);
  32. Str line = "<?>";
  33. int removed_spaces = 0;
  34. if(pair.first && pair.second){
  35. line = Str(pair.first, pair.second-pair.first).lstrip();
  36. removed_spaces = pair.second - pair.first - line.length();
  37. if(line.empty()) line = "<?>";
  38. }
  39. ss << " " << line;
  40. if(cursor && line != "<?>" && cursor >= pair.first && cursor <= pair.second){
  41. auto column = cursor - pair.first - removed_spaces;
  42. if(column >= 0) ss << "\n " << std::string(column, ' ') << "^";
  43. }
  44. return ss.str();
  45. }
  46. void Exception::st_push(Str snapshot){
  47. if(stacktrace.size() >= 8) return;
  48. stacktrace.push(snapshot);
  49. }
  50. Str Exception::summary() const {
  51. stack<Str> st(stacktrace);
  52. std::stringstream ss;
  53. if(is_re) ss << "Traceback (most recent call last):\n";
  54. while(!st.empty()) { ss << st.top() << '\n'; st.pop(); }
  55. if (!msg.empty()) ss << type.sv() << ": " << msg;
  56. else ss << type.sv();
  57. return ss.str();
  58. }
  59. } // namespace pkpy