codeobject.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #pragma once
  2. #include "obj.h"
  3. #include "pointer.h"
  4. #include "error.h"
  5. enum Opcode {
  6. #define OPCODE(name) OP_##name,
  7. #include "opcodes.h"
  8. #undef OPCODE
  9. };
  10. static const char* OP_NAMES[] = {
  11. #define OPCODE(name) #name,
  12. #include "opcodes.h"
  13. #undef OPCODE
  14. };
  15. struct ByteCode{
  16. uint8_t op;
  17. int arg;
  18. uint16_t line;
  19. };
  20. _Str pad(const _Str& s, const int n){
  21. return s + _Str(n - s.size(), ' ');
  22. }
  23. struct CodeObject {
  24. _Source src;
  25. _Str co_name;
  26. CodeObject(_Source src, _Str co_name, CompileMode mode=EXEC_MODE) {
  27. this->src = src;
  28. this->co_name = co_name;
  29. }
  30. std::vector<ByteCode> co_code;
  31. PyVarList co_consts;
  32. std::vector<std::shared_ptr<NamePointer>> co_names;
  33. int addName(const _Str& name, NameScope scope){
  34. auto p = std::make_shared<NamePointer>(name, scope);
  35. for(int i=0; i<co_names.size(); i++){
  36. if(*co_names[i] == *p) return i;
  37. }
  38. co_names.push_back(p);
  39. return co_names.size() - 1;
  40. }
  41. int addConst(PyVar v){
  42. co_consts.push_back(v);
  43. return co_consts.size() - 1;
  44. }
  45. void __moveToEnd(int start, int end){
  46. auto _start = co_code.begin() + start;
  47. auto _end = co_code.begin() + end;
  48. co_code.insert(co_code.end(), _start, _end);
  49. for(int i=start; i<end; i++) co_code[i].op = OP_NO_OP;
  50. }
  51. _Str toString(){
  52. _StrStream ss;
  53. int prev_line = -1;
  54. for(int i=0; i<co_code.size(); i++){
  55. const ByteCode& byte = co_code[i];
  56. if(byte.op == OP_NO_OP) continue;
  57. _Str line = std::to_string(byte.line);
  58. if(byte.line == prev_line) line = "";
  59. else{
  60. if(prev_line != -1) ss << "\n";
  61. prev_line = byte.line;
  62. }
  63. ss << pad(line, 12) << " " << pad(std::to_string(i), 3);
  64. ss << " " << pad(OP_NAMES[byte.op], 20) << " ";
  65. ss << (byte.arg == -1 ? "" : std::to_string(byte.arg));
  66. if(i != co_code.size() - 1) ss << '\n';
  67. }
  68. _StrStream consts;
  69. consts << "co_consts: ";
  70. for(int i=0; i<co_consts.size(); i++){
  71. consts << co_consts[i]->getTypeName();
  72. if(i != co_consts.size() - 1) consts << ", ";
  73. }
  74. _StrStream names;
  75. names << "co_names: ";
  76. for(int i=0; i<co_names.size(); i++){
  77. names << co_names[i]->name;
  78. if(i != co_names.size() - 1) names << ", ";
  79. }
  80. ss << '\n' << consts.str() << '\n' << names.str() << '\n';
  81. for(int i=0; i<co_consts.size(); i++){
  82. auto fn = std::get_if<_Func>(&co_consts[i]->_native);
  83. if(fn) ss << '\n' << fn->code->co_name << ":\n" << fn->code->toString();
  84. }
  85. return _Str(ss);
  86. }
  87. };
  88. class Frame {
  89. private:
  90. std::vector<PyVar> s_data;
  91. int ip = 0;
  92. public:
  93. PyVarDict* f_globals;
  94. PyVarDict f_locals;
  95. const CodeObject* code;
  96. Frame(const CodeObject* code, PyVarDict locals, PyVarDict* globals)
  97. : code(code), f_locals(locals), f_globals(globals) {}
  98. inline const ByteCode& readCode() {
  99. return code->co_code[ip++];
  100. }
  101. _Str errorSnapshot(){
  102. int line = -1;
  103. if(!isEnd()) line = code->co_code[ip-1].line;
  104. return code->src->snapshot(line);
  105. }
  106. int stackSize() const {
  107. return s_data.size();
  108. }
  109. inline bool isEnd() const {
  110. return ip >= code->co_code.size();
  111. }
  112. inline PyVar __pop(){
  113. PyVar v = s_data.back();
  114. s_data.pop_back();
  115. return v;
  116. }
  117. inline PyVar __deref_pointer(VM*, PyVar);
  118. inline PyVar popValue(VM* vm){
  119. return __deref_pointer(vm, __pop());
  120. }
  121. inline PyVar topValue(VM* vm){
  122. return __deref_pointer(vm, s_data.back());
  123. }
  124. inline PyVar topNValue(VM* vm, int n=-1){
  125. return __deref_pointer(vm, s_data[s_data.size() + n]);
  126. }
  127. inline void push(PyVar v){
  128. s_data.push_back(v);
  129. }
  130. inline void jumpTo(int i){
  131. this->ip = i;
  132. }
  133. PyVarList popNValuesReversed(VM* vm, int n){
  134. PyVarList v(n);
  135. for(int i=n-1; i>=0; i--) v[i] = popValue(vm);
  136. return v;
  137. }
  138. PyVarList __popNReversed(int n){
  139. PyVarList v(n);
  140. for(int i=n-1; i>=0; i--) v[i] = __pop();
  141. return v;
  142. }
  143. };