compiler.h 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
  1. #pragma once
  2. #include "parser.h"
  3. #include "error.h"
  4. #include "ceval.h"
  5. class Compiler;
  6. typedef void (Compiler::*GrammarFn)();
  7. typedef void (Compiler::*CompilerAction)();
  8. struct GrammarRule{
  9. GrammarFn prefix;
  10. GrammarFn infix;
  11. Precedence precedence;
  12. };
  13. enum StringType { NORMAL_STRING, RAW_STRING, F_STRING };
  14. class Compiler {
  15. std::unique_ptr<Parser> parser;
  16. std::stack<CodeObject_> codes;
  17. bool is_compiling_class = false;
  18. int lexing_count = 0;
  19. bool used = false;
  20. VM* vm;
  21. std::map<TokenIndex, GrammarRule> rules;
  22. CodeObject_ co() const{ return codes.top(); }
  23. CompileMode mode() const{ return parser->src->mode; }
  24. NameScope name_scope() const { return codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL; }
  25. public:
  26. Compiler(VM* vm, const char* source, Str filename, CompileMode mode){
  27. this->vm = vm;
  28. this->parser = std::make_unique<Parser>(
  29. pkpy::make_shared<SourceData>(source, filename, mode)
  30. );
  31. // http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
  32. #define METHOD(name) &Compiler::name
  33. #define NO_INFIX nullptr, PREC_NONE
  34. for(TokenIndex i=0; i<kTokenCount; i++) rules[i] = { nullptr, NO_INFIX };
  35. rules[TK(".")] = { nullptr, METHOD(exprAttrib), PREC_ATTRIB };
  36. rules[TK("(")] = { METHOD(exprGrouping), METHOD(exprCall), PREC_CALL };
  37. rules[TK("[")] = { METHOD(exprList), METHOD(exprSubscript), PREC_SUBSCRIPT };
  38. rules[TK("{")] = { METHOD(exprMap), NO_INFIX };
  39. rules[TK("%")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
  40. rules[TK("+")] = { nullptr, METHOD(exprBinaryOp), PREC_TERM };
  41. rules[TK("-")] = { METHOD(exprUnaryOp), METHOD(exprBinaryOp), PREC_TERM };
  42. rules[TK("*")] = { METHOD(exprUnaryOp), METHOD(exprBinaryOp), PREC_FACTOR };
  43. rules[TK("/")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
  44. rules[TK("//")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
  45. rules[TK("**")] = { nullptr, METHOD(exprBinaryOp), PREC_EXPONENT };
  46. rules[TK(">")] = { nullptr, METHOD(exprBinaryOp), PREC_COMPARISION };
  47. rules[TK("<")] = { nullptr, METHOD(exprBinaryOp), PREC_COMPARISION };
  48. rules[TK("==")] = { nullptr, METHOD(exprBinaryOp), PREC_EQUALITY };
  49. rules[TK("!=")] = { nullptr, METHOD(exprBinaryOp), PREC_EQUALITY };
  50. rules[TK(">=")] = { nullptr, METHOD(exprBinaryOp), PREC_COMPARISION };
  51. rules[TK("<=")] = { nullptr, METHOD(exprBinaryOp), PREC_COMPARISION };
  52. rules[TK("in")] = { nullptr, METHOD(exprBinaryOp), PREC_TEST };
  53. rules[TK("is")] = { nullptr, METHOD(exprBinaryOp), PREC_TEST };
  54. rules[TK("not in")] = { nullptr, METHOD(exprBinaryOp), PREC_TEST };
  55. rules[TK("is not")] = { nullptr, METHOD(exprBinaryOp), PREC_TEST };
  56. rules[TK("and") ] = { nullptr, METHOD(exprAnd), PREC_LOGICAL_AND };
  57. rules[TK("or")] = { nullptr, METHOD(exprOr), PREC_LOGICAL_OR };
  58. rules[TK("not")] = { METHOD(exprUnaryOp), nullptr, PREC_UNARY };
  59. rules[TK("True")] = { METHOD(exprValue), NO_INFIX };
  60. rules[TK("False")] = { METHOD(exprValue), NO_INFIX };
  61. rules[TK("lambda")] = { METHOD(exprLambda), NO_INFIX };
  62. rules[TK("None")] = { METHOD(exprValue), NO_INFIX };
  63. rules[TK("...")] = { METHOD(exprValue), NO_INFIX };
  64. rules[TK("@id")] = { METHOD(exprName), NO_INFIX };
  65. rules[TK("@num")] = { METHOD(exprLiteral), NO_INFIX };
  66. rules[TK("@str")] = { METHOD(exprLiteral), NO_INFIX };
  67. rules[TK("@fstr")] = { METHOD(exprFString), NO_INFIX };
  68. rules[TK("?")] = { nullptr, METHOD(exprTernary), PREC_TERNARY };
  69. rules[TK("=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
  70. rules[TK("+=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
  71. rules[TK("-=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
  72. rules[TK("*=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
  73. rules[TK("/=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
  74. rules[TK("//=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
  75. rules[TK("%=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
  76. rules[TK("&=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
  77. rules[TK("|=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
  78. rules[TK("^=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
  79. rules[TK(",")] = { nullptr, METHOD(exprComma), PREC_COMMA };
  80. rules[TK("<<")] = { nullptr, METHOD(exprBinaryOp), PREC_BITWISE_SHIFT };
  81. rules[TK(">>")] = { nullptr, METHOD(exprBinaryOp), PREC_BITWISE_SHIFT };
  82. rules[TK("&")] = { nullptr, METHOD(exprBinaryOp), PREC_BITWISE_AND };
  83. rules[TK("|")] = { nullptr, METHOD(exprBinaryOp), PREC_BITWISE_OR };
  84. rules[TK("^")] = { nullptr, METHOD(exprBinaryOp), PREC_BITWISE_XOR };
  85. #undef METHOD
  86. #undef NO_INFIX
  87. #define EXPR() parse_expression(PREC_TERNARY) // no '=' and ',' just a simple expression
  88. #define EXPR_TUPLE() parse_expression(PREC_COMMA) // no '=', but ',' is allowed
  89. #define EXPR_ANY() parse_expression(PREC_ASSIGNMENT)
  90. }
  91. private:
  92. Str eat_string_until(char quote, bool raw) {
  93. bool quote3 = parser->match_n_chars(2, quote);
  94. std::vector<char> buff;
  95. while (true) {
  96. char c = parser->eatchar_include_newline();
  97. if (c == quote){
  98. if(quote3 && !parser->match_n_chars(2, quote)){
  99. buff.push_back(c);
  100. continue;
  101. }
  102. break;
  103. }
  104. if (c == '\0'){
  105. if(quote3 && parser->src->mode == REPL_MODE){
  106. throw NeedMoreLines(false);
  107. }
  108. SyntaxError("EOL while scanning string literal");
  109. }
  110. if (c == '\n'){
  111. if(!quote3) SyntaxError("EOL while scanning string literal");
  112. else{
  113. buff.push_back(c);
  114. continue;
  115. }
  116. }
  117. if (!raw && c == '\\') {
  118. switch (parser->eatchar_include_newline()) {
  119. case '"': buff.push_back('"'); break;
  120. case '\'': buff.push_back('\''); break;
  121. case '\\': buff.push_back('\\'); break;
  122. case 'n': buff.push_back('\n'); break;
  123. case 'r': buff.push_back('\r'); break;
  124. case 't': buff.push_back('\t'); break;
  125. default: SyntaxError("invalid escape char");
  126. }
  127. } else {
  128. buff.push_back(c);
  129. }
  130. }
  131. return Str(buff.data(), buff.size());
  132. }
  133. void eat_string(char quote, StringType type) {
  134. Str s = eat_string_until(quote, type == RAW_STRING);
  135. if(type == F_STRING){
  136. parser->set_next_token(TK("@fstr"), vm->PyStr(s));
  137. }else{
  138. parser->set_next_token(TK("@str"), vm->PyStr(s));
  139. }
  140. }
  141. void eat_number() {
  142. static const std::regex pattern("^(0x)?[0-9a-fA-F]+(\\.[0-9]+)?");
  143. std::smatch m;
  144. const char* i = parser->token_start;
  145. while(*i != '\n' && *i != '\0') i++;
  146. std::string s = std::string(parser->token_start, i);
  147. try{
  148. if (std::regex_search(s, m, pattern)) {
  149. // here is m.length()-1, since the first char was eaten by lex_token()
  150. for(int j=0; j<m.length()-1; j++) parser->eatchar();
  151. int base = 10;
  152. size_t size;
  153. if (m[1].matched) base = 16;
  154. if (m[2].matched) {
  155. if(base == 16) SyntaxError("hex literal should not contain a dot");
  156. parser->set_next_token(TK("@num"), vm->PyFloat(std::stod(m[0], &size)));
  157. } else {
  158. parser->set_next_token(TK("@num"), vm->PyInt(std::stoll(m[0], &size, base)));
  159. }
  160. if (size != m.length()) UNREACHABLE();
  161. }
  162. }catch(std::exception& _){
  163. SyntaxError("invalid number literal");
  164. }
  165. }
  166. void lex_token(){
  167. lexing_count++;
  168. _lex_token();
  169. lexing_count--;
  170. }
  171. // Lex the next token and set it as the next token.
  172. void _lex_token() {
  173. parser->prev = parser->curr;
  174. parser->curr = parser->next_token();
  175. //std::cout << parser->curr.info() << std::endl;
  176. while (parser->peekchar() != '\0') {
  177. parser->token_start = parser->curr_char;
  178. char c = parser->eatchar_include_newline();
  179. switch (c) {
  180. case '\'': case '"': eat_string(c, NORMAL_STRING); return;
  181. case '#': parser->skip_line_comment(); break;
  182. case '{': parser->set_next_token(TK("{")); return;
  183. case '}': parser->set_next_token(TK("}")); return;
  184. case ',': parser->set_next_token(TK(",")); return;
  185. case ':': parser->set_next_token(TK(":")); return;
  186. case ';': parser->set_next_token(TK(";")); return;
  187. case '(': parser->set_next_token(TK("(")); return;
  188. case ')': parser->set_next_token(TK(")")); return;
  189. case '[': parser->set_next_token(TK("[")); return;
  190. case ']': parser->set_next_token(TK("]")); return;
  191. case '%': parser->set_next_token_2('=', TK("%"), TK("%=")); return;
  192. case '&': parser->set_next_token_2('=', TK("&"), TK("&=")); return;
  193. case '|': parser->set_next_token_2('=', TK("|"), TK("|=")); return;
  194. case '^': parser->set_next_token_2('=', TK("^"), TK("^=")); return;
  195. case '?': parser->set_next_token(TK("?")); return;
  196. case '.': {
  197. if(parser->matchchar('.')) {
  198. if(parser->matchchar('.')) {
  199. parser->set_next_token(TK("..."));
  200. } else {
  201. SyntaxError("invalid token '..'");
  202. }
  203. } else {
  204. parser->set_next_token(TK("."));
  205. }
  206. return;
  207. }
  208. case '=': parser->set_next_token_2('=', TK("="), TK("==")); return;
  209. case '+': parser->set_next_token_2('=', TK("+"), TK("+=")); return;
  210. case '>': {
  211. if(parser->matchchar('=')) parser->set_next_token(TK(">="));
  212. else if(parser->matchchar('>')) parser->set_next_token(TK(">>"));
  213. else parser->set_next_token(TK(">"));
  214. return;
  215. }
  216. case '<': {
  217. if(parser->matchchar('=')) parser->set_next_token(TK("<="));
  218. else if(parser->matchchar('<')) parser->set_next_token(TK("<<"));
  219. else parser->set_next_token(TK("<"));
  220. return;
  221. }
  222. case '-': {
  223. if(parser->matchchar('=')) parser->set_next_token(TK("-="));
  224. else if(parser->matchchar('>')) parser->set_next_token(TK("->"));
  225. else parser->set_next_token(TK("-"));
  226. return;
  227. }
  228. case '!':
  229. if(parser->matchchar('=')) parser->set_next_token(TK("!="));
  230. else SyntaxError("expected '=' after '!'");
  231. break;
  232. case '*':
  233. if (parser->matchchar('*')) {
  234. parser->set_next_token(TK("**")); // '**'
  235. } else {
  236. parser->set_next_token_2('=', TK("*"), TK("*="));
  237. }
  238. return;
  239. case '/':
  240. if(parser->matchchar('/')) {
  241. parser->set_next_token_2('=', TK("//"), TK("//="));
  242. } else {
  243. parser->set_next_token_2('=', TK("/"), TK("/="));
  244. }
  245. return;
  246. case '\r': break; // just ignore '\r'
  247. case ' ': case '\t': parser->eat_spaces(); break;
  248. case '\n': {
  249. parser->set_next_token(TK("@eol"));
  250. if(!parser->eat_indentation()) IndentationError("unindent does not match any outer indentation level");
  251. return;
  252. }
  253. default: {
  254. if(c == 'f'){
  255. if(parser->matchchar('\'')) {eat_string('\'', F_STRING); return;}
  256. if(parser->matchchar('"')) {eat_string('"', F_STRING); return;}
  257. }else if(c == 'r'){
  258. if(parser->matchchar('\'')) {eat_string('\'', RAW_STRING); return;}
  259. if(parser->matchchar('"')) {eat_string('"', RAW_STRING); return;}
  260. }
  261. if (c >= '0' && c <= '9') {
  262. eat_number();
  263. return;
  264. }
  265. switch (parser->eat_name())
  266. {
  267. case 0: break;
  268. case 1: SyntaxError("invalid char: " + std::string(1, c));
  269. case 2: SyntaxError("invalid utf8 sequence: " + std::string(1, c));
  270. case 3: SyntaxError("@id contains invalid char"); break;
  271. case 4: SyntaxError("invalid JSON token"); break;
  272. default: UNREACHABLE();
  273. }
  274. return;
  275. }
  276. }
  277. }
  278. parser->token_start = parser->curr_char;
  279. parser->set_next_token(TK("@eof"));
  280. }
  281. inline TokenIndex peek() {
  282. return parser->curr.type;
  283. }
  284. // not sure this will work
  285. TokenIndex peek_next() {
  286. if(parser->nexts.empty()) return TK("@eof");
  287. return parser->nexts.front().type;
  288. }
  289. bool match(TokenIndex expected) {
  290. if (peek() != expected) return false;
  291. lex_token();
  292. return true;
  293. }
  294. void consume(TokenIndex expected) {
  295. if (!match(expected)){
  296. StrStream ss;
  297. ss << "expected '" << TK_STR(expected) << "', but got '" << TK_STR(peek()) << "'";
  298. SyntaxError(ss.str());
  299. }
  300. }
  301. bool match_newlines(bool repl_throw=false) {
  302. bool consumed = false;
  303. if (peek() == TK("@eol")) {
  304. while (peek() == TK("@eol")) lex_token();
  305. consumed = true;
  306. }
  307. if (repl_throw && peek() == TK("@eof")){
  308. throw NeedMoreLines(is_compiling_class);
  309. }
  310. return consumed;
  311. }
  312. bool match_end_stmt() {
  313. if (match(TK(";"))) { match_newlines(); return true; }
  314. if (match_newlines() || peek()==TK("@eof")) return true;
  315. if (peek() == TK("@dedent")) return true;
  316. return false;
  317. }
  318. void consume_end_stmt() {
  319. if (!match_end_stmt()) SyntaxError("expected statement end");
  320. }
  321. void exprLiteral() {
  322. PyVar value = parser->prev.value;
  323. int index = co()->add_const(value);
  324. emit(OP_LOAD_CONST, index);
  325. }
  326. void exprFString() {
  327. static const std::regex pattern(R"(\{(.*?)\})");
  328. PyVar value = parser->prev.value;
  329. Str s = vm->PyStr_AS_C(value);
  330. std::sregex_iterator begin(s.begin(), s.end(), pattern);
  331. std::sregex_iterator end;
  332. int size = 0;
  333. int i = 0;
  334. for(auto it = begin; it != end; it++) {
  335. std::smatch m = *it;
  336. if (i < m.position()) {
  337. std::string literal = s.substr(i, m.position() - i);
  338. emit(OP_LOAD_CONST, co()->add_const(vm->PyStr(literal)));
  339. size++;
  340. }
  341. emit(OP_LOAD_EVAL_FN);
  342. emit(OP_LOAD_CONST, co()->add_const(vm->PyStr(m[1].str())));
  343. emit(OP_CALL, 1);
  344. size++;
  345. i = (int)(m.position() + m.length());
  346. }
  347. if (i < s.size()) {
  348. std::string literal = s.substr(i, s.size() - i);
  349. emit(OP_LOAD_CONST, co()->add_const(vm->PyStr(literal)));
  350. size++;
  351. }
  352. emit(OP_BUILD_STRING, size);
  353. }
  354. void exprLambda() {
  355. pkpy::Function func;
  356. func.name = "<lambda>";
  357. if(!match(TK(":"))){
  358. _compile_f_args(func, false);
  359. consume(TK(":"));
  360. }
  361. func.code = pkpy::make_shared<CodeObject>(parser->src, func.name);
  362. this->codes.push(func.code);
  363. co()->_rvalue += 1; EXPR_TUPLE(); co()->_rvalue -= 1;
  364. emit(OP_RETURN_VALUE);
  365. func.code->optimize(vm);
  366. this->codes.pop();
  367. emit(OP_LOAD_FUNCTION, co()->add_const(vm->PyFunction(func)));
  368. if(name_scope() == NAME_LOCAL) emit(OP_SETUP_CLOSURE);
  369. }
  370. void exprAssign() {
  371. int lhs = co()->codes.empty() ? -1 : co()->codes.size() - 1;
  372. co()->_rvalue += 1;
  373. TokenIndex op = parser->prev.type;
  374. if(op == TK("=")) { // a = (expr)
  375. EXPR_TUPLE();
  376. if(lhs!=-1 && co()->codes[lhs].op == OP_LOAD_NAME_REF){
  377. emit(OP_STORE_NAME, co()->codes[lhs].arg);
  378. co()->codes[lhs].op = OP_NO_OP;
  379. co()->codes[lhs].arg = -1;
  380. }else{
  381. emit(OP_STORE_REF);
  382. }
  383. }else{ // a += (expr) -> a = a + (expr)
  384. EXPR();
  385. switch (op) {
  386. case TK("+="): emit(OP_INPLACE_BINARY_OP, 0); break;
  387. case TK("-="): emit(OP_INPLACE_BINARY_OP, 1); break;
  388. case TK("*="): emit(OP_INPLACE_BINARY_OP, 2); break;
  389. case TK("/="): emit(OP_INPLACE_BINARY_OP, 3); break;
  390. case TK("//="): emit(OP_INPLACE_BINARY_OP, 4); break;
  391. case TK("%="): emit(OP_INPLACE_BINARY_OP, 5); break;
  392. case TK("&="): emit(OP_INPLACE_BITWISE_OP, 2); break;
  393. case TK("|="): emit(OP_INPLACE_BITWISE_OP, 3); break;
  394. case TK("^="): emit(OP_INPLACE_BITWISE_OP, 4); break;
  395. default: UNREACHABLE();
  396. }
  397. }
  398. co()->_rvalue -= 1;
  399. }
  400. void exprComma() {
  401. int size = 1; // an expr is in the stack now
  402. do {
  403. EXPR(); // NOTE: "1," will fail, "1,2" will be ok
  404. size++;
  405. } while(match(TK(",")));
  406. emit(OP_BUILD_SMART_TUPLE, size);
  407. }
  408. void exprOr() {
  409. int patch = emit(OP_JUMP_IF_TRUE_OR_POP);
  410. parse_expression(PREC_LOGICAL_OR);
  411. patch_jump(patch);
  412. }
  413. void exprAnd() {
  414. int patch = emit(OP_JUMP_IF_FALSE_OR_POP);
  415. parse_expression(PREC_LOGICAL_AND);
  416. patch_jump(patch);
  417. }
  418. void exprTernary() {
  419. int patch = emit(OP_POP_JUMP_IF_FALSE);
  420. EXPR(); // if true
  421. int patch2 = emit(OP_JUMP_ABSOLUTE);
  422. consume(TK(":"));
  423. patch_jump(patch);
  424. EXPR(); // if false
  425. patch_jump(patch2);
  426. }
  427. void exprBinaryOp() {
  428. TokenIndex op = parser->prev.type;
  429. parse_expression((Precedence)(rules[op].precedence + 1));
  430. switch (op) {
  431. case TK("+"): emit(OP_BINARY_OP, 0); break;
  432. case TK("-"): emit(OP_BINARY_OP, 1); break;
  433. case TK("*"): emit(OP_BINARY_OP, 2); break;
  434. case TK("/"): emit(OP_BINARY_OP, 3); break;
  435. case TK("//"): emit(OP_BINARY_OP, 4); break;
  436. case TK("%"): emit(OP_BINARY_OP, 5); break;
  437. case TK("**"): emit(OP_BINARY_OP, 6); break;
  438. case TK("<"): emit(OP_COMPARE_OP, 0); break;
  439. case TK("<="): emit(OP_COMPARE_OP, 1); break;
  440. case TK("=="): emit(OP_COMPARE_OP, 2); break;
  441. case TK("!="): emit(OP_COMPARE_OP, 3); break;
  442. case TK(">"): emit(OP_COMPARE_OP, 4); break;
  443. case TK(">="): emit(OP_COMPARE_OP, 5); break;
  444. case TK("in"): emit(OP_CONTAINS_OP, 0); break;
  445. case TK("not in"): emit(OP_CONTAINS_OP, 1); break;
  446. case TK("is"): emit(OP_IS_OP, 0); break;
  447. case TK("is not"): emit(OP_IS_OP, 1); break;
  448. case TK("<<"): emit(OP_BITWISE_OP, 0); break;
  449. case TK(">>"): emit(OP_BITWISE_OP, 1); break;
  450. case TK("&"): emit(OP_BITWISE_OP, 2); break;
  451. case TK("|"): emit(OP_BITWISE_OP, 3); break;
  452. case TK("^"): emit(OP_BITWISE_OP, 4); break;
  453. default: UNREACHABLE();
  454. }
  455. }
  456. void exprUnaryOp() {
  457. TokenIndex op = parser->prev.type;
  458. parse_expression((Precedence)(PREC_UNARY + 1));
  459. switch (op) {
  460. case TK("-"): emit(OP_UNARY_NEGATIVE); break;
  461. case TK("not"): emit(OP_UNARY_NOT); break;
  462. case TK("*"): SyntaxError("cannot use '*' as unary operator"); break;
  463. default: UNREACHABLE();
  464. }
  465. }
  466. void exprGrouping() {
  467. match_newlines(mode()==REPL_MODE);
  468. EXPR_TUPLE();
  469. match_newlines(mode()==REPL_MODE);
  470. consume(TK(")"));
  471. }
  472. void exprList() {
  473. int _patch = emit(OP_NO_OP);
  474. int _body_start = co()->codes.size();
  475. int ARGC = 0;
  476. do {
  477. match_newlines(mode()==REPL_MODE);
  478. if (peek() == TK("]")) break;
  479. EXPR(); ARGC++;
  480. match_newlines(mode()==REPL_MODE);
  481. if(ARGC == 1 && match(TK("for"))) goto __LISTCOMP;
  482. } while (match(TK(",")));
  483. match_newlines(mode()==REPL_MODE);
  484. consume(TK("]"));
  485. emit(OP_BUILD_LIST, ARGC);
  486. return;
  487. __LISTCOMP:
  488. int _body_end_return = emit(OP_JUMP_ABSOLUTE, -1);
  489. int _body_end = co()->codes.size();
  490. co()->codes[_patch].op = OP_JUMP_ABSOLUTE;
  491. co()->codes[_patch].arg = _body_end;
  492. emit(OP_BUILD_LIST, 0);
  493. EXPR_FOR_VARS();consume(TK("in"));EXPR_TUPLE();
  494. match_newlines(mode()==REPL_MODE);
  495. int _skipPatch = emit(OP_JUMP_ABSOLUTE);
  496. int _cond_start = co()->codes.size();
  497. int _cond_end_return = -1;
  498. if(match(TK("if"))) {
  499. EXPR_TUPLE();
  500. _cond_end_return = emit(OP_JUMP_ABSOLUTE, -1);
  501. }
  502. patch_jump(_skipPatch);
  503. emit(OP_GET_ITER);
  504. co()->_enter_block(FOR_LOOP);
  505. emit(OP_FOR_ITER);
  506. if(_cond_end_return != -1) { // there is an if condition
  507. emit(OP_JUMP_ABSOLUTE, _cond_start);
  508. patch_jump(_cond_end_return);
  509. int ifpatch = emit(OP_POP_JUMP_IF_FALSE);
  510. emit(OP_JUMP_ABSOLUTE, _body_start);
  511. patch_jump(_body_end_return);
  512. emit(OP_LIST_APPEND);
  513. patch_jump(ifpatch);
  514. }else{
  515. emit(OP_JUMP_ABSOLUTE, _body_start);
  516. patch_jump(_body_end_return);
  517. emit(OP_LIST_APPEND);
  518. }
  519. emit(OP_LOOP_CONTINUE, -1, true);
  520. co()->_exit_block();
  521. match_newlines(mode()==REPL_MODE);
  522. consume(TK("]"));
  523. }
  524. void exprMap() {
  525. bool parsing_dict = false;
  526. int size = 0;
  527. do {
  528. match_newlines(mode()==REPL_MODE);
  529. if (peek() == TK("}")) break;
  530. EXPR();
  531. if(peek() == TK(":")) parsing_dict = true;
  532. if(parsing_dict){
  533. consume(TK(":"));
  534. EXPR();
  535. }
  536. size++;
  537. match_newlines(mode()==REPL_MODE);
  538. } while (match(TK(",")));
  539. consume(TK("}"));
  540. if(size == 0 || parsing_dict) emit(OP_BUILD_MAP, size);
  541. else emit(OP_BUILD_SET, size);
  542. }
  543. void exprCall() {
  544. int ARGC = 0;
  545. int KWARGC = 0;
  546. do {
  547. match_newlines(mode()==REPL_MODE);
  548. if (peek() == TK(")")) break;
  549. if(peek() == TK("@id") && peek_next() == TK("=")) {
  550. consume(TK("@id"));
  551. const Str& key = parser->prev.str();
  552. emit(OP_LOAD_CONST, co()->add_const(vm->PyStr(key)));
  553. consume(TK("="));
  554. co()->_rvalue += 1; EXPR(); co()->_rvalue -= 1;
  555. KWARGC++;
  556. } else{
  557. if(KWARGC > 0) SyntaxError("positional argument follows keyword argument");
  558. co()->_rvalue += 1; EXPR(); co()->_rvalue -= 1;
  559. ARGC++;
  560. }
  561. match_newlines(mode()==REPL_MODE);
  562. } while (match(TK(",")));
  563. consume(TK(")"));
  564. emit(OP_CALL, (KWARGC << 16) | ARGC);
  565. }
  566. void exprName(){ _exprName(false); }
  567. void _exprName(bool force_lvalue) {
  568. Token tkname = parser->prev;
  569. int index = co()->add_name(tkname.str(), name_scope());
  570. bool fast_load = !force_lvalue && co()->_rvalue>0;
  571. emit(fast_load ? OP_LOAD_NAME : OP_LOAD_NAME_REF, index);
  572. }
  573. void exprAttrib() {
  574. consume(TK("@id"));
  575. const Str& name = parser->prev.str();
  576. int index = co()->add_name(name, NAME_ATTR);
  577. index = (index<<1) + (int)(co()->_rvalue>0);
  578. emit(OP_BUILD_ATTR, index);
  579. }
  580. // [:], [:b]
  581. // [a], [a:], [a:b]
  582. void exprSubscript() {
  583. if(match(TK(":"))){
  584. emit(OP_LOAD_NONE);
  585. if(match(TK("]"))){
  586. emit(OP_LOAD_NONE);
  587. }else{
  588. EXPR_TUPLE();
  589. consume(TK("]"));
  590. }
  591. emit(OP_BUILD_SLICE);
  592. }else{
  593. EXPR_TUPLE();
  594. if(match(TK(":"))){
  595. if(match(TK("]"))){
  596. emit(OP_LOAD_NONE);
  597. }else{
  598. EXPR_TUPLE();
  599. consume(TK("]"));
  600. }
  601. emit(OP_BUILD_SLICE);
  602. }else{
  603. consume(TK("]"));
  604. }
  605. }
  606. emit(OP_BUILD_INDEX, (int)(co()->_rvalue>0));
  607. }
  608. void exprValue() {
  609. TokenIndex op = parser->prev.type;
  610. switch (op) {
  611. case TK("None"): emit(OP_LOAD_NONE); break;
  612. case TK("True"): emit(OP_LOAD_TRUE); break;
  613. case TK("False"): emit(OP_LOAD_FALSE); break;
  614. case TK("..."): emit(OP_LOAD_ELLIPSIS); break;
  615. default: UNREACHABLE();
  616. }
  617. }
  618. int emit(Opcode opcode, int arg=-1, bool keepline=false) {
  619. int line = parser->prev.line;
  620. co()->codes.push_back(
  621. Bytecode{(uint8_t)opcode, arg, line, (uint16_t)co()->_curr_block_i}
  622. );
  623. int i = co()->codes.size() - 1;
  624. if(keepline && i>=1) co()->codes[i].line = co()->codes[i-1].line;
  625. return i;
  626. }
  627. inline void patch_jump(int addr_index) {
  628. int target = co()->codes.size();
  629. co()->codes[addr_index].arg = target;
  630. }
  631. void compile_block_body(CompilerAction action=nullptr) {
  632. if(action == nullptr) action = &Compiler::compile_stmt;
  633. consume(TK(":"));
  634. if(peek()!=TK("@eol") && peek()!=TK("@eof")){
  635. (this->*action)(); // inline block
  636. return;
  637. }
  638. if(!match_newlines(mode()==REPL_MODE)){
  639. SyntaxError("expected a new line after ':'");
  640. }
  641. consume(TK("@indent"));
  642. while (peek() != TK("@dedent")) {
  643. match_newlines();
  644. (this->*action)();
  645. match_newlines();
  646. }
  647. consume(TK("@dedent"));
  648. }
  649. Token _compile_import() {
  650. consume(TK("@id"));
  651. Token tkmodule = parser->prev;
  652. int index = co()->add_name(tkmodule.str(), NAME_SPECIAL);
  653. emit(OP_IMPORT_NAME, index);
  654. return tkmodule;
  655. }
  656. // import a as b
  657. void compile_normal_import() {
  658. do {
  659. Token tkmodule = _compile_import();
  660. if (match(TK("as"))) {
  661. consume(TK("@id"));
  662. tkmodule = parser->prev;
  663. }
  664. int index = co()->add_name(tkmodule.str(), name_scope());
  665. emit(OP_STORE_NAME, index);
  666. } while (match(TK(",")));
  667. consume_end_stmt();
  668. }
  669. // from a import b as c, d as e
  670. void compile_from_import() {
  671. Token tkmodule = _compile_import();
  672. consume(TK("import"));
  673. do {
  674. emit(OP_DUP_TOP_VALUE);
  675. consume(TK("@id"));
  676. Token tkname = parser->prev;
  677. int index = co()->add_name(tkname.str(), NAME_ATTR);
  678. emit(OP_BUILD_ATTR, (index<<1)+1);
  679. if (match(TK("as"))) {
  680. consume(TK("@id"));
  681. tkname = parser->prev;
  682. }
  683. index = co()->add_name(tkname.str(), name_scope());
  684. emit(OP_STORE_NAME, index);
  685. } while (match(TK(",")));
  686. emit(OP_POP_TOP);
  687. consume_end_stmt();
  688. }
  689. void parse_expression(Precedence precedence) {
  690. lex_token();
  691. GrammarFn prefix = rules[parser->prev.type].prefix;
  692. if (prefix == nullptr) SyntaxError(Str("expected an expression, but got ") + TK_STR(parser->prev.type));
  693. (this->*prefix)();
  694. while (rules[peek()].precedence >= precedence) {
  695. lex_token();
  696. TokenIndex op = parser->prev.type;
  697. GrammarFn infix = rules[op].infix;
  698. if(infix == nullptr) throw std::runtime_error("(infix == nullptr) is true");
  699. (this->*infix)();
  700. }
  701. }
  702. void compile_if_stmt() {
  703. match_newlines();
  704. co()->_rvalue += 1;
  705. EXPR_TUPLE(); // condition
  706. co()->_rvalue -= 1;
  707. int ifpatch = emit(OP_POP_JUMP_IF_FALSE);
  708. compile_block_body();
  709. if (match(TK("elif"))) {
  710. int exit_jump = emit(OP_JUMP_ABSOLUTE);
  711. patch_jump(ifpatch);
  712. compile_if_stmt();
  713. patch_jump(exit_jump);
  714. } else if (match(TK("else"))) {
  715. int exit_jump = emit(OP_JUMP_ABSOLUTE);
  716. patch_jump(ifpatch);
  717. compile_block_body();
  718. patch_jump(exit_jump);
  719. } else {
  720. patch_jump(ifpatch);
  721. }
  722. }
  723. void compile_while_loop() {
  724. co()->_enter_block(WHILE_LOOP);
  725. co()->_rvalue += 1;
  726. EXPR_TUPLE(); // condition
  727. co()->_rvalue -= 1;
  728. int patch = emit(OP_POP_JUMP_IF_FALSE);
  729. compile_block_body();
  730. emit(OP_LOOP_CONTINUE, -1, true);
  731. patch_jump(patch);
  732. co()->_exit_block();
  733. }
  734. void EXPR_FOR_VARS(){
  735. int size = 0;
  736. do {
  737. consume(TK("@id"));
  738. _exprName(true); size++;
  739. } while (match(TK(",")));
  740. if(size > 1) emit(OP_BUILD_SMART_TUPLE, size);
  741. }
  742. void compile_for_loop() {
  743. EXPR_FOR_VARS();consume(TK("in"));
  744. co()->_rvalue += 1; EXPR_TUPLE(); co()->_rvalue -= 1;
  745. emit(OP_GET_ITER);
  746. co()->_enter_block(FOR_LOOP);
  747. emit(OP_FOR_ITER);
  748. compile_block_body();
  749. emit(OP_LOOP_CONTINUE, -1, true);
  750. co()->_exit_block();
  751. }
  752. void compile_try_except() {
  753. co()->_enter_block(TRY_EXCEPT);
  754. emit(OP_TRY_BLOCK_ENTER);
  755. compile_block_body();
  756. emit(OP_TRY_BLOCK_EXIT);
  757. std::vector<int> patches = { emit(OP_JUMP_ABSOLUTE) };
  758. co()->_exit_block();
  759. do {
  760. consume(TK("except"));
  761. if(match(TK("@id"))){
  762. int name_idx = co()->add_name(parser->prev.str(), NAME_SPECIAL);
  763. emit(OP_EXCEPTION_MATCH, name_idx);
  764. }else{
  765. emit(OP_LOAD_TRUE);
  766. }
  767. int patch = emit(OP_POP_JUMP_IF_FALSE);
  768. emit(OP_POP_TOP); // pop the exception on match
  769. compile_block_body();
  770. patches.push_back(emit(OP_JUMP_ABSOLUTE));
  771. patch_jump(patch);
  772. }while(peek() == TK("except"));
  773. emit(OP_RE_RAISE); // no match, re-raise
  774. for (int patch : patches) patch_jump(patch);
  775. }
  776. void compile_stmt() {
  777. if (match(TK("break"))) {
  778. if (!co()->_is_curr_block_loop()) SyntaxError("'break' outside loop");
  779. consume_end_stmt();
  780. emit(OP_LOOP_BREAK);
  781. } else if (match(TK("continue"))) {
  782. if (!co()->_is_curr_block_loop()) SyntaxError("'continue' not properly in loop");
  783. consume_end_stmt();
  784. emit(OP_LOOP_CONTINUE);
  785. } else if (match(TK("yield"))) {
  786. if (codes.size() == 1) SyntaxError("'yield' outside function");
  787. co()->_rvalue += 1;
  788. EXPR_TUPLE();
  789. co()->_rvalue -= 1;
  790. consume_end_stmt();
  791. co()->is_generator = true;
  792. emit(OP_YIELD_VALUE, -1, true);
  793. } else if (match(TK("return"))) {
  794. if (codes.size() == 1) SyntaxError("'return' outside function");
  795. if(match_end_stmt()){
  796. emit(OP_LOAD_NONE);
  797. }else{
  798. co()->_rvalue += 1;
  799. EXPR_TUPLE(); // return value
  800. co()->_rvalue -= 1;
  801. consume_end_stmt();
  802. }
  803. emit(OP_RETURN_VALUE, -1, true);
  804. } else if (match(TK("if"))) {
  805. compile_if_stmt();
  806. } else if (match(TK("while"))) {
  807. compile_while_loop();
  808. } else if (match(TK("for"))) {
  809. compile_for_loop();
  810. } else if (match(TK("import"))){
  811. compile_normal_import();
  812. } else if (match(TK("from"))){
  813. compile_from_import();
  814. } else if (match(TK("def"))){
  815. compile_function();
  816. } else if (match(TK("try"))) {
  817. compile_try_except();
  818. } else if(match(TK("assert"))) {
  819. co()->_rvalue += 1;
  820. EXPR();
  821. if (match(TK(","))) EXPR();
  822. else emit(OP_LOAD_CONST, co()->add_const(vm->PyStr("")));
  823. co()->_rvalue -= 1;
  824. emit(OP_ASSERT);
  825. consume_end_stmt();
  826. } else if(match(TK("with"))){
  827. EXPR();
  828. consume(TK("as"));
  829. consume(TK("@id"));
  830. Token tkname = parser->prev;
  831. int index = co()->add_name(tkname.str(), name_scope());
  832. emit(OP_STORE_NAME, index);
  833. emit(OP_LOAD_NAME_REF, index);
  834. emit(OP_WITH_ENTER);
  835. compile_block_body();
  836. emit(OP_LOAD_NAME_REF, index);
  837. emit(OP_WITH_EXIT);
  838. } else if(match(TK("label"))){
  839. if(mode() != EXEC_MODE) SyntaxError("'label' is only available in EXEC_MODE");
  840. consume(TK(".")); consume(TK("@id"));
  841. Str label = parser->prev.str();
  842. bool ok = co()->add_label(label);
  843. if(!ok) SyntaxError("label '" + label + "' already exists");
  844. consume_end_stmt();
  845. } else if(match(TK("goto"))){ // https://entrian.com/goto/
  846. if(mode() != EXEC_MODE) SyntaxError("'goto' is only available in EXEC_MODE");
  847. consume(TK(".")); consume(TK("@id"));
  848. emit(OP_GOTO, co()->add_name(parser->prev.str(), NAME_SPECIAL));
  849. consume_end_stmt();
  850. } else if(match(TK("raise"))){
  851. consume(TK("@id"));
  852. int dummy_t = co()->add_name(parser->prev.str(), NAME_SPECIAL);
  853. if(match(TK("(")) && !match(TK(")"))){
  854. EXPR(); consume(TK(")"));
  855. }else{
  856. emit(OP_LOAD_NONE);
  857. }
  858. emit(OP_RAISE, dummy_t);
  859. consume_end_stmt();
  860. } else if(match(TK("del"))){
  861. EXPR();
  862. emit(OP_DELETE_REF);
  863. consume_end_stmt();
  864. } else if(match(TK("global"))){
  865. do {
  866. consume(TK("@id"));
  867. co()->global_names[parser->prev.str()] = 1;
  868. } while (match(TK(",")));
  869. consume_end_stmt();
  870. } else if(match(TK("pass"))){
  871. consume_end_stmt();
  872. } else {
  873. EXPR_ANY();
  874. consume_end_stmt();
  875. // If last op is not an assignment, pop the result.
  876. uint8_t last_op = co()->codes.back().op;
  877. if( last_op!=OP_STORE_NAME && last_op!=OP_STORE_REF && last_op!=OP_INPLACE_BINARY_OP && last_op!=OP_INPLACE_BITWISE_OP){
  878. if(mode()==REPL_MODE && name_scope() == NAME_GLOBAL) emit(OP_PRINT_EXPR, -1, true);
  879. emit(OP_POP_TOP, -1, true);
  880. }
  881. }
  882. }
  883. void compile_class(){
  884. consume(TK("@id"));
  885. int cls_name_idx = co()->add_name(parser->prev.str(), NAME_GLOBAL);
  886. int super_cls_name_idx = -1;
  887. if(match(TK("(")) && match(TK("@id"))){
  888. super_cls_name_idx = co()->add_name(parser->prev.str(), NAME_GLOBAL);
  889. consume(TK(")"));
  890. }
  891. emit(OP_LOAD_NONE);
  892. is_compiling_class = true;
  893. compile_block_body(&Compiler::compile_function);
  894. is_compiling_class = false;
  895. if(super_cls_name_idx == -1) emit(OP_LOAD_NONE);
  896. else emit(OP_LOAD_NAME_REF, super_cls_name_idx);
  897. emit(OP_BUILD_CLASS, cls_name_idx);
  898. }
  899. void _compile_f_args(pkpy::Function& func, bool enable_type_hints){
  900. int state = 0; // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
  901. do {
  902. if(state == 3) SyntaxError("**kwargs should be the last argument");
  903. match_newlines();
  904. if(match(TK("*"))){
  905. if(state < 1) state = 1;
  906. else SyntaxError("*args should be placed before **kwargs");
  907. }
  908. else if(match(TK("**"))){
  909. state = 3;
  910. }
  911. consume(TK("@id"));
  912. const Str& name = parser->prev.str();
  913. if(func.has_name(name)) SyntaxError("duplicate argument name");
  914. // eat type hints
  915. if(enable_type_hints && match(TK(":"))) consume(TK("@id"));
  916. if(state == 0 && peek() == TK("=")) state = 2;
  917. switch (state)
  918. {
  919. case 0: func.args.push_back(name); break;
  920. case 1: func.starred_arg = name; state+=1; break;
  921. case 2: {
  922. consume(TK("="));
  923. PyVarOrNull value = read_literal();
  924. if(value == nullptr){
  925. SyntaxError(Str("expect a literal, not ") + TK_STR(parser->curr.type));
  926. }
  927. func.kwargs[name] = value;
  928. func.kwargs_order.push_back(name);
  929. } break;
  930. case 3: SyntaxError("**kwargs is not supported yet"); break;
  931. }
  932. } while (match(TK(",")));
  933. }
  934. void compile_function(){
  935. if(is_compiling_class){
  936. if(match(TK("pass"))) return;
  937. consume(TK("def"));
  938. }
  939. pkpy::Function func;
  940. consume(TK("@id"));
  941. func.name = parser->prev.str();
  942. consume(TK("("));
  943. if (!match(TK(")"))) {
  944. _compile_f_args(func, true);
  945. consume(TK(")"));
  946. }
  947. if(match(TK("->"))) consume(TK("@id")); // eat type hints
  948. func.code = pkpy::make_shared<CodeObject>(parser->src, func.name);
  949. this->codes.push(func.code);
  950. compile_block_body();
  951. func.code->optimize(vm);
  952. this->codes.pop();
  953. emit(OP_LOAD_FUNCTION, co()->add_const(vm->PyFunction(func)));
  954. if(name_scope() == NAME_LOCAL) emit(OP_SETUP_CLOSURE);
  955. if(!is_compiling_class) emit(OP_STORE_NAME, co()->add_name(func.name, name_scope()));
  956. }
  957. PyVarOrNull read_literal(){
  958. if(match(TK("-"))){
  959. consume(TK("@num"));
  960. PyVar val = parser->prev.value;
  961. return vm->num_negated(val);
  962. }
  963. if(match(TK("@num"))) return parser->prev.value;
  964. if(match(TK("@str"))) return parser->prev.value;
  965. if(match(TK("True"))) return vm->PyBool(true);
  966. if(match(TK("False"))) return vm->PyBool(false);
  967. if(match(TK("None"))) return vm->None;
  968. if(match(TK("..."))) return vm->Ellipsis;
  969. return nullptr;
  970. }
  971. /***** Error Reporter *****/
  972. void throw_err(Str type, Str msg){
  973. int lineno = parser->curr.line;
  974. const char* cursor = parser->curr.start;
  975. // if error occurs in lexing, lineno should be `parser->current_line`
  976. if(lexing_count > 0){
  977. lineno = parser->current_line;
  978. cursor = parser->curr_char;
  979. }
  980. if(parser->peekchar() == '\n') lineno--;
  981. auto e = pkpy::Exception("SyntaxError", msg);
  982. e.st_push(parser->src->snapshot(lineno, cursor));
  983. throw e;
  984. }
  985. void SyntaxError(Str msg){ throw_err("SyntaxError", msg); }
  986. void IndentationError(Str msg){ throw_err("IndentationError", msg); }
  987. public:
  988. CodeObject_ compile(){
  989. // can only be called once
  990. if(used) UNREACHABLE();
  991. used = true;
  992. CodeObject_ code = pkpy::make_shared<CodeObject>(parser->src, Str("<module>"));
  993. codes.push(code);
  994. lex_token(); lex_token();
  995. match_newlines();
  996. if(mode()==EVAL_MODE) {
  997. EXPR_TUPLE();
  998. consume(TK("@eof"));
  999. code->optimize(vm);
  1000. return code;
  1001. }else if(mode()==JSON_MODE){
  1002. PyVarOrNull value = read_literal();
  1003. if(value != nullptr) emit(OP_LOAD_CONST, code->add_const(value));
  1004. else if(match(TK("{"))) exprMap();
  1005. else if(match(TK("["))) exprList();
  1006. else SyntaxError("expect a JSON object or array");
  1007. consume(TK("@eof"));
  1008. return code; // no need to optimize for JSON decoding
  1009. }
  1010. while (!match(TK("@eof"))) {
  1011. if (match(TK("class"))) {
  1012. compile_class();
  1013. } else {
  1014. compile_stmt();
  1015. }
  1016. match_newlines();
  1017. }
  1018. code->optimize(vm);
  1019. return code;
  1020. }
  1021. };