compiler.cpp 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245
  1. #include "pocketpy/compiler.h"
  2. namespace pkpy{
  3. NameScope Compiler::name_scope() const {
  4. auto s = contexts.size()>1 ? NAME_LOCAL : NAME_GLOBAL;
  5. if(unknown_global_scope && s == NAME_GLOBAL) s = NAME_GLOBAL_UNKNOWN;
  6. return s;
  7. }
  8. CodeObject_ Compiler::push_global_context(){
  9. CodeObject_ co = std::make_shared<CodeObject>(lexer.src, lexer.src->filename);
  10. co->start_line = i==0 ? 1 : prev().line;
  11. contexts.push(CodeEmitContext(vm, co, contexts.size()));
  12. return co;
  13. }
  14. FuncDecl_ Compiler::push_f_context(Str name){
  15. FuncDecl_ decl = std::make_shared<FuncDecl>();
  16. decl->code = std::make_shared<CodeObject>(lexer.src, name);
  17. decl->code->start_line = i==0 ? 1 : prev().line;
  18. decl->nested = name_scope() == NAME_LOCAL;
  19. contexts.push(CodeEmitContext(vm, decl->code, contexts.size()));
  20. contexts.top().func = decl;
  21. return decl;
  22. }
  23. void Compiler::pop_context(){
  24. if(!ctx()->s_expr.empty()){
  25. throw std::runtime_error("!ctx()->s_expr.empty()");
  26. }
  27. // add a `return None` in the end as a guard
  28. // previously, we only do this if the last opcode is not a return
  29. // however, this is buggy...since there may be a jump to the end (out of bound) even if the last opcode is a return
  30. ctx()->emit_(OP_RETURN_VALUE, 1, BC_KEEPLINE, true);
  31. // find the last valid token
  32. int j = i-1;
  33. while(tokens[j].type == TK("@eol") || tokens[j].type == TK("@dedent") || tokens[j].type == TK("@eof")) j--;
  34. ctx()->co->end_line = tokens[j].line;
  35. // some check here
  36. auto& codes = ctx()->co->codes;
  37. if(ctx()->co->varnames.size() > PK_MAX_CO_VARNAMES){
  38. SyntaxError("maximum number of local variables exceeded");
  39. }
  40. if(ctx()->co->consts.size() > 65530){
  41. SyntaxError("maximum number of constants exceeded");
  42. }
  43. if(codes.size() > 65530 && ctx()->co->src->mode != JSON_MODE){
  44. // json mode does not contain jump instructions, so it is safe to ignore this check
  45. SyntaxError("maximum number of opcodes exceeded");
  46. }
  47. // pre-compute LOOP_BREAK and LOOP_CONTINUE
  48. for(int i=0; i<codes.size(); i++){
  49. Bytecode& bc = codes[i];
  50. if(bc.op == OP_LOOP_CONTINUE){
  51. bc.arg = ctx()->co->blocks[bc.arg].start;
  52. }else if(bc.op == OP_LOOP_BREAK){
  53. bc.arg = ctx()->co->blocks[bc.arg].get_break_end();
  54. }
  55. }
  56. // pre-compute func->is_simple
  57. FuncDecl_ func = contexts.top().func;
  58. if(func){
  59. func->is_simple = true;
  60. if(func->code->is_generator) func->is_simple = false;
  61. if(func->kwargs.size() > 0) func->is_simple = false;
  62. if(func->starred_arg >= 0) func->is_simple = false;
  63. if(func->starred_kwarg >= 0) func->is_simple = false;
  64. }
  65. contexts.pop();
  66. }
  67. void Compiler::init_pratt_rules(){
  68. PK_LOCAL_STATIC unsigned int count = 0;
  69. if(count > 0) return;
  70. count += 1;
  71. // http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
  72. #define PK_METHOD(name) &Compiler::name
  73. #define PK_NO_INFIX nullptr, PREC_LOWEST
  74. for(TokenIndex i=0; i<kTokenCount; i++) rules[i] = { nullptr, PK_NO_INFIX };
  75. rules[TK(".")] = { nullptr, PK_METHOD(exprAttrib), PREC_PRIMARY };
  76. rules[TK("(")] = { PK_METHOD(exprGroup), PK_METHOD(exprCall), PREC_PRIMARY };
  77. rules[TK("[")] = { PK_METHOD(exprList), PK_METHOD(exprSubscr), PREC_PRIMARY };
  78. rules[TK("{")] = { PK_METHOD(exprMap), PK_NO_INFIX };
  79. rules[TK("%")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_FACTOR };
  80. rules[TK("+")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_TERM };
  81. rules[TK("-")] = { PK_METHOD(exprUnaryOp), PK_METHOD(exprBinaryOp), PREC_TERM };
  82. rules[TK("*")] = { PK_METHOD(exprUnaryOp), PK_METHOD(exprBinaryOp), PREC_FACTOR };
  83. rules[TK("~")] = { PK_METHOD(exprUnaryOp), nullptr, PREC_UNARY };
  84. rules[TK("/")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_FACTOR };
  85. rules[TK("//")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_FACTOR };
  86. rules[TK("**")] = { PK_METHOD(exprUnaryOp), PK_METHOD(exprBinaryOp), PREC_EXPONENT };
  87. rules[TK(">")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_COMPARISION };
  88. rules[TK("<")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_COMPARISION };
  89. rules[TK("==")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_COMPARISION };
  90. rules[TK("!=")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_COMPARISION };
  91. rules[TK(">=")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_COMPARISION };
  92. rules[TK("<=")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_COMPARISION };
  93. rules[TK("in")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_COMPARISION };
  94. rules[TK("is")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_COMPARISION };
  95. rules[TK("<<")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_BITWISE_SHIFT };
  96. rules[TK(">>")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_BITWISE_SHIFT };
  97. rules[TK("&")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_BITWISE_AND };
  98. rules[TK("|")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_BITWISE_OR };
  99. rules[TK("^")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_BITWISE_XOR };
  100. rules[TK("@")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_FACTOR };
  101. rules[TK("if")] = { nullptr, PK_METHOD(exprTernary), PREC_TERNARY };
  102. rules[TK("not in")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_COMPARISION };
  103. rules[TK("is not")] = { nullptr, PK_METHOD(exprBinaryOp), PREC_COMPARISION };
  104. rules[TK("and") ] = { nullptr, PK_METHOD(exprAnd), PREC_LOGICAL_AND };
  105. rules[TK("or")] = { nullptr, PK_METHOD(exprOr), PREC_LOGICAL_OR };
  106. rules[TK("not")] = { PK_METHOD(exprNot), nullptr, PREC_LOGICAL_NOT };
  107. rules[TK("True")] = { PK_METHOD(exprLiteral0), PK_NO_INFIX };
  108. rules[TK("False")] = { PK_METHOD(exprLiteral0), PK_NO_INFIX };
  109. rules[TK("None")] = { PK_METHOD(exprLiteral0), PK_NO_INFIX };
  110. rules[TK("...")] = { PK_METHOD(exprLiteral0), PK_NO_INFIX };
  111. rules[TK("lambda")] = { PK_METHOD(exprLambda), PK_NO_INFIX };
  112. rules[TK("@id")] = { PK_METHOD(exprName), PK_NO_INFIX };
  113. rules[TK("@num")] = { PK_METHOD(exprLiteral), PK_NO_INFIX };
  114. rules[TK("@str")] = { PK_METHOD(exprLiteral), PK_NO_INFIX };
  115. rules[TK("@fstr")] = { PK_METHOD(exprFString), PK_NO_INFIX };
  116. rules[TK("@long")] = { PK_METHOD(exprLong), PK_NO_INFIX };
  117. rules[TK("@imag")] = { PK_METHOD(exprImag), PK_NO_INFIX };
  118. rules[TK("@bytes")] = { PK_METHOD(exprBytes), PK_NO_INFIX };
  119. rules[TK(":")] = { PK_METHOD(exprSlice0), PK_METHOD(exprSlice1), PREC_PRIMARY };
  120. #undef PK_METHOD
  121. #undef PK_NO_INFIX
  122. }
  123. bool Compiler::match(TokenIndex expected) {
  124. if (curr().type != expected) return false;
  125. advance();
  126. return true;
  127. }
  128. void Compiler::consume(TokenIndex expected) {
  129. if (!match(expected)){
  130. SyntaxError(
  131. _S("expected '", TK_STR(expected), "', got '", TK_STR(curr().type), "'")
  132. );
  133. }
  134. }
  135. bool Compiler::match_newlines_repl(){
  136. return match_newlines(mode()==REPL_MODE);
  137. }
  138. bool Compiler::match_newlines(bool repl_throw) {
  139. bool consumed = false;
  140. if (curr().type == TK("@eol")) {
  141. while (curr().type == TK("@eol")) advance();
  142. consumed = true;
  143. }
  144. if (repl_throw && curr().type == TK("@eof")){
  145. throw NeedMoreLines(ctx()->is_compiling_class);
  146. }
  147. return consumed;
  148. }
  149. bool Compiler::match_end_stmt() {
  150. if (match(TK(";"))) { match_newlines(); return true; }
  151. if (match_newlines() || curr().type == TK("@eof")) return true;
  152. if (curr().type == TK("@dedent")) return true;
  153. return false;
  154. }
  155. void Compiler::consume_end_stmt() {
  156. if (!match_end_stmt()) SyntaxError("expected statement end");
  157. }
  158. void Compiler::EXPR() {
  159. parse_expression(PREC_LOWEST+1);
  160. }
  161. void Compiler::EXPR_TUPLE(bool allow_slice) {
  162. parse_expression(PREC_LOWEST+1, allow_slice);
  163. if(!match(TK(","))) return;
  164. // tuple expression
  165. Expr_vector items;
  166. items.push_back(ctx()->s_expr.popx());
  167. do {
  168. if(curr().brackets_level) match_newlines_repl();
  169. if(!is_expression(allow_slice)) break;
  170. parse_expression(PREC_LOWEST+1, allow_slice);
  171. items.push_back(ctx()->s_expr.popx());
  172. if(curr().brackets_level) match_newlines_repl();
  173. } while(match(TK(",")));
  174. ctx()->s_expr.push(make_expr<TupleExpr>(std::move(items)));
  175. }
  176. // special case for `for loop` and `comp`
  177. Expr_ Compiler::EXPR_VARS(){
  178. Expr_vector items;
  179. do {
  180. consume(TK("@id"));
  181. items.push_back(make_expr<NameExpr>(prev().str(), name_scope()));
  182. } while(match(TK(",")));
  183. if(items.size()==1) return std::move(items[0]);
  184. return make_expr<TupleExpr>(std::move(items));
  185. }
  186. void Compiler::exprLiteral(){
  187. ctx()->s_expr.push(make_expr<LiteralExpr>(prev().value));
  188. }
  189. void Compiler::exprLong(){
  190. ctx()->s_expr.push(make_expr<LongExpr>(prev().str()));
  191. }
  192. void Compiler::exprImag(){
  193. ctx()->s_expr.push(make_expr<ImagExpr>(std::get<f64>(prev().value)));
  194. }
  195. void Compiler::exprBytes(){
  196. ctx()->s_expr.push(make_expr<BytesExpr>(std::get<Str>(prev().value)));
  197. }
  198. void Compiler::exprFString(){
  199. ctx()->s_expr.push(make_expr<FStringExpr>(std::get<Str>(prev().value)));
  200. }
  201. void Compiler::exprLambda(){
  202. FuncDecl_ decl = push_f_context("<lambda>");
  203. auto e = make_expr<LambdaExpr>(decl);
  204. if(!match(TK(":"))){
  205. _compile_f_args(e->decl, false);
  206. consume(TK(":"));
  207. }
  208. // https://github.com/pocketpy/pocketpy/issues/37
  209. parse_expression(PREC_LAMBDA + 1);
  210. ctx()->emit_expr();
  211. ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
  212. pop_context();
  213. ctx()->s_expr.push(std::move(e));
  214. }
  215. void Compiler::exprOr(){
  216. auto e = make_expr<OrExpr>();
  217. e->lhs = ctx()->s_expr.popx();
  218. parse_expression(PREC_LOGICAL_OR + 1);
  219. e->rhs = ctx()->s_expr.popx();
  220. ctx()->s_expr.push(std::move(e));
  221. }
  222. void Compiler::exprAnd(){
  223. auto e = make_expr<AndExpr>();
  224. e->lhs = ctx()->s_expr.popx();
  225. parse_expression(PREC_LOGICAL_AND + 1);
  226. e->rhs = ctx()->s_expr.popx();
  227. ctx()->s_expr.push(std::move(e));
  228. }
  229. void Compiler::exprTernary(){
  230. auto e = make_expr<TernaryExpr>();
  231. e->true_expr = ctx()->s_expr.popx();
  232. // cond
  233. parse_expression(PREC_TERNARY + 1);
  234. e->cond = ctx()->s_expr.popx();
  235. consume(TK("else"));
  236. // if false
  237. parse_expression(PREC_TERNARY + 1);
  238. e->false_expr = ctx()->s_expr.popx();
  239. ctx()->s_expr.push(std::move(e));
  240. }
  241. void Compiler::exprBinaryOp(){
  242. auto e = make_expr<BinaryExpr>();
  243. e->op = prev().type;
  244. e->lhs = ctx()->s_expr.popx();
  245. parse_expression(rules[e->op].precedence + 1);
  246. e->rhs = ctx()->s_expr.popx();
  247. ctx()->s_expr.push(std::move(e));
  248. }
  249. void Compiler::exprNot() {
  250. parse_expression(PREC_LOGICAL_NOT + 1);
  251. ctx()->s_expr.push(make_expr<NotExpr>(ctx()->s_expr.popx()));
  252. }
  253. void Compiler::exprUnaryOp(){
  254. TokenIndex op = prev().type;
  255. parse_expression(PREC_UNARY + 1);
  256. switch(op){
  257. case TK("-"):
  258. ctx()->s_expr.push(make_expr<NegatedExpr>(ctx()->s_expr.popx()));
  259. break;
  260. case TK("~"):
  261. ctx()->s_expr.push(make_expr<InvertExpr>(ctx()->s_expr.popx()));
  262. break;
  263. case TK("*"):
  264. ctx()->s_expr.push(make_expr<StarredExpr>(1, ctx()->s_expr.popx()));
  265. break;
  266. case TK("**"):
  267. ctx()->s_expr.push(make_expr<StarredExpr>(2, ctx()->s_expr.popx()));
  268. break;
  269. default: PK_FATAL_ERROR();
  270. }
  271. }
  272. void Compiler::exprGroup(){
  273. match_newlines_repl();
  274. EXPR_TUPLE(); // () is just for change precedence
  275. match_newlines_repl();
  276. consume(TK(")"));
  277. if(ctx()->s_expr.top()->is_tuple()) return;
  278. Expr_ g = make_expr<GroupedExpr>(ctx()->s_expr.popx());
  279. ctx()->s_expr.push(std::move(g));
  280. }
  281. void Compiler::consume_comp(unique_ptr_128<CompExpr> ce, Expr_ expr){
  282. ce->expr = std::move(expr);
  283. ce->vars = EXPR_VARS();
  284. consume(TK("in"));
  285. parse_expression(PREC_TERNARY + 1);
  286. ce->iter = ctx()->s_expr.popx();
  287. match_newlines_repl();
  288. if(match(TK("if"))){
  289. parse_expression(PREC_TERNARY + 1);
  290. ce->cond = ctx()->s_expr.popx();
  291. }
  292. ctx()->s_expr.push(std::move(ce));
  293. match_newlines_repl();
  294. }
  295. void Compiler::exprList() {
  296. int line = prev().line;
  297. Expr_vector items;
  298. do {
  299. match_newlines_repl();
  300. if (curr().type == TK("]")) break;
  301. EXPR();
  302. items.push_back(ctx()->s_expr.popx());
  303. match_newlines_repl();
  304. if(items.size()==1 && match(TK("for"))){
  305. consume_comp(make_expr<ListCompExpr>(), std::move(items[0]));
  306. consume(TK("]"));
  307. return;
  308. }
  309. match_newlines_repl();
  310. } while (match(TK(",")));
  311. consume(TK("]"));
  312. auto e = make_expr<ListExpr>(std::move(items));
  313. e->line = line; // override line
  314. ctx()->s_expr.push(std::move(e));
  315. }
  316. void Compiler::exprMap() {
  317. bool parsing_dict = false; // {...} may be dict or set
  318. Expr_vector items;
  319. do {
  320. match_newlines_repl();
  321. if (curr().type == TK("}")) break;
  322. EXPR();
  323. int star_level = ctx()->s_expr.top()->star_level();
  324. if(star_level==2 || curr().type == TK(":")){
  325. parsing_dict = true;
  326. }
  327. if(parsing_dict){
  328. auto dict_item = make_expr<DictItemExpr>();
  329. if(star_level == 2){
  330. dict_item->key = nullptr;
  331. dict_item->value = ctx()->s_expr.popx();
  332. }else{
  333. consume(TK(":"));
  334. EXPR();
  335. dict_item->key = ctx()->s_expr.popx();
  336. dict_item->value = ctx()->s_expr.popx();
  337. }
  338. items.push_back(std::move(dict_item));
  339. }else{
  340. items.push_back(ctx()->s_expr.popx());
  341. }
  342. match_newlines_repl();
  343. if(items.size()==1 && match(TK("for"))){
  344. if(parsing_dict) consume_comp(make_expr<DictCompExpr>(), std::move(items[0]));
  345. else consume_comp(make_expr<SetCompExpr>(), std::move(items[0]));
  346. consume(TK("}"));
  347. return;
  348. }
  349. match_newlines_repl();
  350. } while (match(TK(",")));
  351. consume(TK("}"));
  352. if(items.size()==0 || parsing_dict){
  353. auto e = make_expr<DictExpr>(std::move(items));
  354. ctx()->s_expr.push(std::move(e));
  355. }else{
  356. auto e = make_expr<SetExpr>(std::move(items));
  357. ctx()->s_expr.push(std::move(e));
  358. }
  359. }
  360. void Compiler::exprCall() {
  361. auto e = make_expr<CallExpr>();
  362. e->callable = ctx()->s_expr.popx();
  363. do {
  364. match_newlines_repl();
  365. if (curr().type==TK(")")) break;
  366. if(curr().type==TK("@id") && next().type==TK("=")) {
  367. consume(TK("@id"));
  368. Str key = prev().str();
  369. consume(TK("="));
  370. EXPR();
  371. e->kwargs.push_back({key, ctx()->s_expr.popx()});
  372. } else{
  373. EXPR();
  374. if(ctx()->s_expr.top()->star_level() == 2){
  375. // **kwargs
  376. e->kwargs.push_back({"**", ctx()->s_expr.popx()});
  377. }else{
  378. // positional argument
  379. if(!e->kwargs.empty()) SyntaxError("positional argument follows keyword argument");
  380. e->args.push_back(ctx()->s_expr.popx());
  381. }
  382. }
  383. match_newlines_repl();
  384. } while (match(TK(",")));
  385. consume(TK(")"));
  386. if(e->args.size() > 32767) SyntaxError("too many positional arguments");
  387. if(e->kwargs.size() > 32767) SyntaxError("too many keyword arguments");
  388. ctx()->s_expr.push(std::move(e));
  389. }
  390. void Compiler::exprName(){
  391. Str name = prev().str();
  392. NameScope scope = name_scope();
  393. if(ctx()->global_names.count(name)){
  394. scope = NAME_GLOBAL;
  395. }
  396. ctx()->s_expr.push(make_expr<NameExpr>(name, scope));
  397. }
  398. void Compiler::exprAttrib() {
  399. consume(TK("@id"));
  400. ctx()->s_expr.push(
  401. make_expr<AttribExpr>(ctx()->s_expr.popx(), StrName::get(prev().sv()))
  402. );
  403. }
  404. void Compiler::exprSlice0() {
  405. auto slice = make_expr<SliceExpr>();
  406. if(is_expression()){ // :<stop>
  407. EXPR();
  408. slice->stop = ctx()->s_expr.popx();
  409. // try optional step
  410. if(match(TK(":"))){ // :<stop>:<step>
  411. EXPR();
  412. slice->step = ctx()->s_expr.popx();
  413. }
  414. }else if(match(TK(":"))){
  415. if(is_expression()){ // ::<step>
  416. EXPR();
  417. slice->step = ctx()->s_expr.popx();
  418. } // else ::
  419. } // else :
  420. ctx()->s_expr.push(std::move(slice));
  421. }
  422. void Compiler::exprSlice1() {
  423. auto slice = make_expr<SliceExpr>();
  424. slice->start = ctx()->s_expr.popx();
  425. if(is_expression()){ // <start>:<stop>
  426. EXPR();
  427. slice->stop = ctx()->s_expr.popx();
  428. // try optional step
  429. if(match(TK(":"))){ // <start>:<stop>:<step>
  430. EXPR();
  431. slice->step = ctx()->s_expr.popx();
  432. }
  433. }else if(match(TK(":"))){ // <start>::<step>
  434. EXPR();
  435. slice->step = ctx()->s_expr.popx();
  436. } // else <start>:
  437. ctx()->s_expr.push(std::move(slice));
  438. }
  439. void Compiler::exprSubscr() {
  440. auto e = make_expr<SubscrExpr>();
  441. match_newlines_repl();
  442. e->a = ctx()->s_expr.popx(); // a
  443. EXPR_TUPLE(true);
  444. e->b = ctx()->s_expr.popx(); // a[<expr>]
  445. match_newlines_repl();
  446. consume(TK("]"));
  447. ctx()->s_expr.push(std::move(e));
  448. }
  449. void Compiler::exprLiteral0() {
  450. ctx()->s_expr.push(make_expr<Literal0Expr>(prev().type));
  451. }
  452. void Compiler::compile_block_body(void (Compiler::*callback)()) {
  453. if(callback == nullptr) callback = &Compiler::compile_stmt;
  454. consume(TK(":"));
  455. if(curr().type!=TK("@eol") && curr().type!=TK("@eof")){
  456. compile_stmt(); // inline block
  457. return;
  458. }
  459. if(!match_newlines(mode()==REPL_MODE)){
  460. SyntaxError("expected a new line after ':'");
  461. }
  462. consume(TK("@indent"));
  463. while (curr().type != TK("@dedent")) {
  464. match_newlines();
  465. (this->*callback)();
  466. match_newlines();
  467. }
  468. consume(TK("@dedent"));
  469. }
  470. // import a [as b]
  471. // import a [as b], c [as d]
  472. void Compiler::compile_normal_import() {
  473. do {
  474. consume(TK("@id"));
  475. Str name = prev().str();
  476. ctx()->emit_(OP_IMPORT_PATH, ctx()->add_const_string(name.sv()), prev().line);
  477. if (match(TK("as"))) {
  478. consume(TK("@id"));
  479. name = prev().str();
  480. }
  481. ctx()->emit_store_name(name_scope(), StrName(name), prev().line);
  482. } while (match(TK(",")));
  483. consume_end_stmt();
  484. }
  485. // from a import b [as c], d [as e]
  486. // from a.b import c [as d]
  487. // from . import a [as b]
  488. // from .a import b [as c]
  489. // from ..a import b [as c]
  490. // from .a.b import c [as d]
  491. // from xxx import *
  492. void Compiler::compile_from_import() {
  493. int dots = 0;
  494. while(true){
  495. switch(curr().type){
  496. case TK("."): dots+=1; break;
  497. case TK(".."): dots+=2; break;
  498. case TK("..."): dots+=3; break;
  499. default: goto __EAT_DOTS_END;
  500. }
  501. advance();
  502. }
  503. __EAT_DOTS_END:
  504. SStream ss;
  505. for(int i=0; i<dots; i++) ss << '.';
  506. if(dots > 0){
  507. // @id is optional if dots > 0
  508. if(match(TK("@id"))){
  509. ss << prev().sv();
  510. while (match(TK("."))) {
  511. consume(TK("@id"));
  512. ss << "." << prev().sv();
  513. }
  514. }
  515. }else{
  516. // @id is required if dots == 0
  517. consume(TK("@id"));
  518. ss << prev().sv();
  519. while (match(TK("."))) {
  520. consume(TK("@id"));
  521. ss << "." << prev().sv();
  522. }
  523. }
  524. ctx()->emit_(OP_IMPORT_PATH, ctx()->add_const_string(ss.str().sv()), prev().line);
  525. consume(TK("import"));
  526. if (match(TK("*"))) {
  527. if(name_scope() != NAME_GLOBAL) SyntaxError("from <module> import * can only be used in global scope");
  528. // pop the module and import __all__
  529. ctx()->emit_(OP_POP_IMPORT_STAR, BC_NOARG, prev().line);
  530. consume_end_stmt();
  531. return;
  532. }
  533. do {
  534. ctx()->emit_(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
  535. consume(TK("@id"));
  536. Str name = prev().str();
  537. ctx()->emit_(OP_LOAD_ATTR, StrName(name).index, prev().line);
  538. if (match(TK("as"))) {
  539. consume(TK("@id"));
  540. name = prev().str();
  541. }
  542. ctx()->emit_store_name(name_scope(), StrName(name), prev().line);
  543. } while (match(TK(",")));
  544. ctx()->emit_(OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
  545. consume_end_stmt();
  546. }
  547. bool Compiler::is_expression(bool allow_slice){
  548. PrattCallback prefix = rules[curr().type].prefix;
  549. return prefix != nullptr && (allow_slice || curr().type!=TK(":"));
  550. }
  551. void Compiler::parse_expression(int precedence, bool allow_slice) {
  552. PrattCallback prefix = rules[curr().type].prefix;
  553. if (prefix==nullptr || (curr().type==TK(":") && !allow_slice)){
  554. SyntaxError(Str("expected an expression, got ") + TK_STR(curr().type));
  555. }
  556. advance();
  557. (this->*prefix)();
  558. while (rules[curr().type].precedence >= precedence && (allow_slice || curr().type!=TK(":"))) {
  559. TokenIndex op = curr().type;
  560. advance();
  561. PrattCallback infix = rules[op].infix;
  562. PK_ASSERT(infix != nullptr);
  563. (this->*infix)();
  564. }
  565. }
  566. void Compiler::compile_if_stmt() {
  567. EXPR(); // condition
  568. ctx()->emit_expr();
  569. int patch = ctx()->emit_(OP_POP_JUMP_IF_FALSE, BC_NOARG, prev().line);
  570. compile_block_body();
  571. if (match(TK("elif"))) {
  572. int exit_patch = ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, prev().line);
  573. ctx()->patch_jump(patch);
  574. compile_if_stmt();
  575. ctx()->patch_jump(exit_patch);
  576. } else if (match(TK("else"))) {
  577. int exit_patch = ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, prev().line);
  578. ctx()->patch_jump(patch);
  579. compile_block_body();
  580. ctx()->patch_jump(exit_patch);
  581. } else {
  582. ctx()->patch_jump(patch);
  583. }
  584. }
  585. void Compiler::compile_while_loop() {
  586. CodeBlock* block = ctx()->enter_block(CodeBlockType::WHILE_LOOP);
  587. EXPR(); // condition
  588. ctx()->emit_expr();
  589. int patch = ctx()->emit_(OP_POP_JUMP_IF_FALSE, BC_NOARG, prev().line);
  590. compile_block_body();
  591. ctx()->emit_(OP_LOOP_CONTINUE, ctx()->get_loop(), BC_KEEPLINE, true);
  592. ctx()->patch_jump(patch);
  593. ctx()->exit_block();
  594. // optional else clause
  595. if (match(TK("else"))) {
  596. compile_block_body();
  597. block->end2 = ctx()->co->codes.size();
  598. }
  599. }
  600. void Compiler::compile_for_loop() {
  601. Expr_ vars = EXPR_VARS();
  602. consume(TK("in"));
  603. EXPR_TUPLE(); ctx()->emit_expr();
  604. ctx()->emit_(OP_GET_ITER, BC_NOARG, BC_KEEPLINE);
  605. CodeBlock* block = ctx()->enter_block(CodeBlockType::FOR_LOOP);
  606. int for_codei = ctx()->emit_(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE);
  607. bool ok = vars->emit_store(ctx());
  608. if(!ok) SyntaxError(); // this error occurs in `vars` instead of this line, but...nevermind
  609. ctx()->try_merge_for_iter_store(for_codei);
  610. compile_block_body();
  611. ctx()->emit_(OP_LOOP_CONTINUE, ctx()->get_loop(), BC_KEEPLINE, true);
  612. ctx()->exit_block();
  613. // optional else clause
  614. if (match(TK("else"))) {
  615. compile_block_body();
  616. block->end2 = ctx()->co->codes.size();
  617. }
  618. }
  619. void Compiler::compile_try_except() {
  620. ctx()->enter_block(CodeBlockType::TRY_EXCEPT);
  621. compile_block_body();
  622. pod_vector<int> patches = {
  623. ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, BC_KEEPLINE)
  624. };
  625. ctx()->exit_block();
  626. int finally_entry = -1;
  627. if(curr().type != TK("finally")){
  628. do {
  629. StrName as_name;
  630. consume(TK("except"));
  631. if(is_expression()){
  632. EXPR(); // push assumed type on to the stack
  633. ctx()->emit_expr();
  634. ctx()->emit_(OP_EXCEPTION_MATCH, BC_NOARG, prev().line);
  635. if(match(TK("as"))){
  636. consume(TK("@id"));
  637. as_name = StrName(prev().sv());
  638. }
  639. }else{
  640. ctx()->emit_(OP_LOAD_TRUE, BC_NOARG, BC_KEEPLINE);
  641. }
  642. int patch = ctx()->emit_(OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE);
  643. // on match
  644. if(!as_name.empty()){
  645. ctx()->emit_(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
  646. ctx()->emit_store_name(name_scope(), as_name, BC_KEEPLINE);
  647. }
  648. // pop the exception
  649. ctx()->emit_(OP_POP_EXCEPTION, BC_NOARG, BC_KEEPLINE);
  650. compile_block_body();
  651. patches.push_back(ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, BC_KEEPLINE));
  652. ctx()->patch_jump(patch);
  653. }while(curr().type == TK("except"));
  654. }
  655. if(match(TK("finally"))){
  656. int patch = ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, BC_KEEPLINE);
  657. finally_entry = ctx()->co->codes.size();
  658. compile_block_body();
  659. ctx()->emit_(OP_JUMP_ABSOLUTE_TOP, BC_NOARG, BC_KEEPLINE);
  660. ctx()->patch_jump(patch);
  661. }
  662. // no match, re-raise
  663. if(finally_entry != -1){
  664. i64 target = ctx()->co->codes.size()+2;
  665. ctx()->emit_(OP_LOAD_CONST, ctx()->add_const(VAR(target)), BC_KEEPLINE);
  666. ctx()->emit_(OP_JUMP_ABSOLUTE, finally_entry, BC_KEEPLINE);
  667. }
  668. ctx()->emit_(OP_RE_RAISE, BC_NOARG, BC_KEEPLINE);
  669. // no exception or no match, jump to the end
  670. for (int patch : patches) ctx()->patch_jump(patch);
  671. if(finally_entry != -1){
  672. i64 target = ctx()->co->codes.size()+2;
  673. ctx()->emit_(OP_LOAD_CONST, ctx()->add_const(VAR(target)), BC_KEEPLINE);
  674. ctx()->emit_(OP_JUMP_ABSOLUTE, finally_entry, BC_KEEPLINE);
  675. }
  676. }
  677. void Compiler::compile_decorated(){
  678. Expr_vector decorators;
  679. do{
  680. EXPR();
  681. decorators.push_back(ctx()->s_expr.popx());
  682. if(!match_newlines_repl()) SyntaxError();
  683. }while(match(TK("@")));
  684. if(match(TK("class"))){
  685. compile_class(decorators);
  686. }else{
  687. consume(TK("def"));
  688. compile_function(decorators);
  689. }
  690. }
  691. bool Compiler::try_compile_assignment(){
  692. switch (curr().type) {
  693. case TK("+="): case TK("-="): case TK("*="): case TK("/="): case TK("//="): case TK("%="):
  694. case TK("<<="): case TK(">>="): case TK("&="): case TK("|="): case TK("^="): {
  695. Expr* lhs_p = ctx()->s_expr.top().get();
  696. if(lhs_p->is_starred()) SyntaxError();
  697. if(ctx()->is_compiling_class) SyntaxError("can't use inplace operator in class definition");
  698. advance();
  699. auto e = make_expr<BinaryExpr>();
  700. e->op = prev().type - 1; // -1 to remove =
  701. e->lhs = ctx()->s_expr.popx();
  702. EXPR_TUPLE();
  703. e->rhs = ctx()->s_expr.popx();
  704. if(e->is_starred()) SyntaxError();
  705. e->emit_(ctx());
  706. bool ok = lhs_p->emit_store(ctx());
  707. if(!ok) SyntaxError();
  708. } return true;
  709. case TK("="): {
  710. int n = 0;
  711. while(match(TK("="))){
  712. EXPR_TUPLE();
  713. n += 1;
  714. }
  715. // stack size is n+1
  716. Expr_ val = ctx()->s_expr.popx();
  717. val->emit_(ctx());
  718. for(int j=1; j<n; j++) ctx()->emit_(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
  719. for(int j=0; j<n; j++){
  720. auto e = ctx()->s_expr.popx();
  721. if(e->is_starred()) SyntaxError();
  722. bool ok = e->emit_store(ctx());
  723. if(!ok) SyntaxError();
  724. }
  725. } return true;
  726. default: return false;
  727. }
  728. }
  729. void Compiler::compile_stmt() {
  730. if(match(TK("class"))){
  731. compile_class();
  732. return;
  733. }
  734. advance();
  735. int kw_line = prev().line; // backup line number
  736. int curr_loop_block = ctx()->get_loop();
  737. switch(prev().type){
  738. case TK("break"):
  739. if (curr_loop_block < 0) SyntaxError("'break' outside loop");
  740. ctx()->emit_(OP_LOOP_BREAK, curr_loop_block, kw_line);
  741. consume_end_stmt();
  742. break;
  743. case TK("continue"):
  744. if (curr_loop_block < 0) SyntaxError("'continue' not properly in loop");
  745. ctx()->emit_(OP_LOOP_CONTINUE, curr_loop_block, kw_line);
  746. consume_end_stmt();
  747. break;
  748. case TK("yield"):
  749. if (contexts.size() <= 1) SyntaxError("'yield' outside function");
  750. EXPR_TUPLE(); ctx()->emit_expr();
  751. // if yield present, mark the function as generator
  752. ctx()->co->is_generator = true;
  753. ctx()->emit_(OP_YIELD_VALUE, BC_NOARG, kw_line);
  754. consume_end_stmt();
  755. break;
  756. case TK("yield from"):
  757. if (contexts.size() <= 1) SyntaxError("'yield from' outside function");
  758. EXPR_TUPLE(); ctx()->emit_expr();
  759. // if yield from present, mark the function as generator
  760. ctx()->co->is_generator = true;
  761. ctx()->emit_(OP_GET_ITER, BC_NOARG, kw_line);
  762. ctx()->enter_block(CodeBlockType::FOR_LOOP);
  763. ctx()->emit_(OP_FOR_ITER_YIELD_VALUE, BC_NOARG, kw_line);
  764. ctx()->emit_(OP_LOOP_CONTINUE, ctx()->get_loop(), kw_line);
  765. ctx()->exit_block();
  766. consume_end_stmt();
  767. break;
  768. case TK("return"):
  769. if (contexts.size() <= 1) SyntaxError("'return' outside function");
  770. if(match_end_stmt()){
  771. ctx()->emit_(OP_RETURN_VALUE, 1, kw_line);
  772. }else{
  773. EXPR_TUPLE(); ctx()->emit_expr();
  774. // check if it is a generator
  775. if(ctx()->co->is_generator) SyntaxError("'return' with argument inside generator function");
  776. consume_end_stmt();
  777. ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, kw_line);
  778. }
  779. break;
  780. /*************************************************/
  781. case TK("if"): compile_if_stmt(); break;
  782. case TK("while"): compile_while_loop(); break;
  783. case TK("for"): compile_for_loop(); break;
  784. case TK("import"): compile_normal_import(); break;
  785. case TK("from"): compile_from_import(); break;
  786. case TK("def"): compile_function(); break;
  787. case TK("@"): compile_decorated(); break;
  788. case TK("try"): compile_try_except(); break;
  789. case TK("pass"): consume_end_stmt(); break;
  790. /*************************************************/
  791. case TK("++"):{
  792. consume(TK("@id"));
  793. StrName name(prev().sv());
  794. NameScope scope = name_scope();
  795. bool is_global = ctx()->global_names.count(name.sv());
  796. if(is_global) scope = NAME_GLOBAL;
  797. switch(scope){
  798. case NAME_LOCAL:
  799. ctx()->emit_(OP_INC_FAST, ctx()->add_varname(name), prev().line);
  800. break;
  801. case NAME_GLOBAL:
  802. ctx()->emit_(OP_INC_GLOBAL, name.index, prev().line);
  803. break;
  804. default: SyntaxError(); break;
  805. }
  806. consume_end_stmt();
  807. break;
  808. }
  809. case TK("--"):{
  810. consume(TK("@id"));
  811. StrName name(prev().sv());
  812. switch(name_scope()){
  813. case NAME_LOCAL:
  814. ctx()->emit_(OP_DEC_FAST, ctx()->add_varname(name), prev().line);
  815. break;
  816. case NAME_GLOBAL:
  817. ctx()->emit_(OP_DEC_GLOBAL, name.index, prev().line);
  818. break;
  819. default: SyntaxError(); break;
  820. }
  821. consume_end_stmt();
  822. break;
  823. }
  824. case TK("assert"):{
  825. EXPR(); // condition
  826. ctx()->emit_expr();
  827. int index = ctx()->emit_(OP_POP_JUMP_IF_TRUE, BC_NOARG, kw_line);
  828. int has_msg = 0;
  829. if(match(TK(","))){
  830. EXPR(); // message
  831. ctx()->emit_expr();
  832. has_msg = 1;
  833. }
  834. ctx()->emit_(OP_RAISE_ASSERT, has_msg, kw_line);
  835. ctx()->patch_jump(index);
  836. consume_end_stmt();
  837. break;
  838. }
  839. case TK("global"):
  840. do {
  841. consume(TK("@id"));
  842. ctx()->global_names.insert(prev().str());
  843. } while (match(TK(",")));
  844. consume_end_stmt();
  845. break;
  846. case TK("raise"): {
  847. EXPR(); ctx()->emit_expr();
  848. ctx()->emit_(OP_RAISE, BC_NOARG, kw_line);
  849. consume_end_stmt();
  850. } break;
  851. case TK("del"): {
  852. EXPR_TUPLE();
  853. Expr_ e = ctx()->s_expr.popx();
  854. bool ok = e->emit_del(ctx());
  855. if(!ok) SyntaxError();
  856. consume_end_stmt();
  857. } break;
  858. case TK("with"): {
  859. EXPR(); // [ <expr> ]
  860. ctx()->emit_expr();
  861. ctx()->enter_block(CodeBlockType::CONTEXT_MANAGER);
  862. Expr_ as_name;
  863. if(match(TK("as"))){
  864. consume(TK("@id"));
  865. as_name = make_expr<NameExpr>(prev().str(), name_scope());
  866. }
  867. ctx()->emit_(OP_WITH_ENTER, BC_NOARG, prev().line);
  868. // [ <expr> <expr>.__enter__() ]
  869. if(as_name != nullptr){
  870. bool ok = as_name->emit_store(ctx());
  871. if(!ok) SyntaxError();
  872. }else{
  873. ctx()->emit_(OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
  874. }
  875. compile_block_body();
  876. ctx()->emit_(OP_WITH_EXIT, BC_NOARG, prev().line);
  877. ctx()->exit_block();
  878. } break;
  879. /*************************************************/
  880. case TK("=="): {
  881. consume(TK("@id"));
  882. if(mode()!=EXEC_MODE) SyntaxError("'label' is only available in EXEC_MODE");
  883. bool ok = ctx()->add_label(prev().str());
  884. consume(TK("=="));
  885. if(!ok) SyntaxError("label " + prev().str().escape() + " already exists");
  886. consume_end_stmt();
  887. } break;
  888. case TK("->"):
  889. consume(TK("@id"));
  890. if(mode()!=EXEC_MODE) SyntaxError("'goto' is only available in EXEC_MODE");
  891. ctx()->emit_(OP_GOTO, StrName(prev().sv()).index, prev().line);
  892. consume_end_stmt();
  893. break;
  894. /*************************************************/
  895. // handle dangling expression or assignment
  896. default: {
  897. advance(-1); // do revert since we have pre-called advance() at the beginning
  898. EXPR_TUPLE();
  899. bool is_typed_name = false; // e.g. x: int
  900. // eat variable's type hint if it is a single name
  901. if(ctx()->s_expr.top()->is_name()){
  902. if(match(TK(":"))){
  903. consume_type_hints();
  904. is_typed_name = true;
  905. if(ctx()->is_compiling_class){
  906. NameExpr* ne = static_cast<NameExpr*>(ctx()->s_expr.top().get());
  907. ctx()->emit_(OP_ADD_CLASS_ANNOTATION, ne->name.index, BC_KEEPLINE);
  908. }
  909. }
  910. }
  911. if(!try_compile_assignment()){
  912. if(!ctx()->s_expr.empty() && ctx()->s_expr.top()->is_starred()){
  913. SyntaxError();
  914. }
  915. if(!is_typed_name){
  916. ctx()->emit_expr();
  917. if((mode()==CELL_MODE || mode()==REPL_MODE) && name_scope()==NAME_GLOBAL){
  918. ctx()->emit_(OP_PRINT_EXPR, BC_NOARG, BC_KEEPLINE);
  919. }else{
  920. ctx()->emit_(OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
  921. }
  922. }else{
  923. PK_ASSERT(ctx()->s_expr.size() == 1)
  924. ctx()->s_expr.pop();
  925. }
  926. }
  927. consume_end_stmt();
  928. }
  929. }
  930. }
  931. void Compiler::consume_type_hints(){
  932. EXPR();
  933. ctx()->s_expr.pop();
  934. }
  935. void Compiler::_add_decorators(const Expr_vector& decorators){
  936. // [obj]
  937. for(auto it=decorators.rbegin(); it!=decorators.rend(); ++it){
  938. (*it)->emit_(ctx()); // [obj, f]
  939. ctx()->emit_(OP_ROT_TWO, BC_NOARG, (*it)->line); // [f, obj]
  940. ctx()->emit_(OP_LOAD_NULL, BC_NOARG, BC_KEEPLINE); // [f, obj, NULL]
  941. ctx()->emit_(OP_ROT_TWO, BC_NOARG, BC_KEEPLINE); // [obj, NULL, f]
  942. ctx()->emit_(OP_CALL, 1, (*it)->line); // [obj]
  943. }
  944. }
  945. void Compiler::compile_class(const Expr_vector& decorators){
  946. consume(TK("@id"));
  947. int namei = StrName(prev().sv()).index;
  948. Expr_ base = nullptr;
  949. if(match(TK("("))){
  950. if(is_expression()){
  951. EXPR();
  952. base = ctx()->s_expr.popx();
  953. }
  954. consume(TK(")"));
  955. }
  956. if(base == nullptr){
  957. ctx()->emit_(OP_LOAD_NONE, BC_NOARG, prev().line);
  958. }else {
  959. base->emit_(ctx());
  960. }
  961. ctx()->emit_(OP_BEGIN_CLASS, namei, BC_KEEPLINE);
  962. for(auto& c: this->contexts.container()){
  963. if(c.is_compiling_class){
  964. SyntaxError("nested class is not allowed");
  965. }
  966. }
  967. ctx()->is_compiling_class = true;
  968. compile_block_body();
  969. ctx()->is_compiling_class = false;
  970. if(!decorators.empty()){
  971. ctx()->emit_(OP_BEGIN_CLASS_DECORATION, BC_NOARG, BC_KEEPLINE);
  972. _add_decorators(decorators);
  973. ctx()->emit_(OP_END_CLASS_DECORATION, BC_NOARG, BC_KEEPLINE);
  974. }
  975. ctx()->emit_(OP_END_CLASS, namei, BC_KEEPLINE);
  976. }
  977. void Compiler::_compile_f_args(FuncDecl_ decl, bool enable_type_hints){
  978. int state = 0; // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
  979. do {
  980. if(state > 3) SyntaxError();
  981. if(state == 3) SyntaxError("**kwargs should be the last argument");
  982. match_newlines();
  983. if(match(TK("*"))){
  984. if(state < 1) state = 1;
  985. else SyntaxError("*args should be placed before **kwargs");
  986. }
  987. else if(match(TK("**"))){
  988. state = 3;
  989. }
  990. consume(TK("@id"));
  991. StrName name = prev().str();
  992. // check duplicate argument name
  993. for(int j: decl->args){
  994. if(decl->code->varnames[j] == name) {
  995. SyntaxError("duplicate argument name");
  996. }
  997. }
  998. for(auto& kv: decl->kwargs){
  999. if(decl->code->varnames[kv.index] == name){
  1000. SyntaxError("duplicate argument name");
  1001. }
  1002. }
  1003. if(decl->starred_arg!=-1 && decl->code->varnames[decl->starred_arg] == name){
  1004. SyntaxError("duplicate argument name");
  1005. }
  1006. if(decl->starred_kwarg!=-1 && decl->code->varnames[decl->starred_kwarg] == name){
  1007. SyntaxError("duplicate argument name");
  1008. }
  1009. // eat type hints
  1010. if(enable_type_hints && match(TK(":"))) consume_type_hints();
  1011. if(state == 0 && curr().type == TK("=")) state = 2;
  1012. int index = ctx()->add_varname(name);
  1013. switch (state)
  1014. {
  1015. case 0:
  1016. decl->args.push_back(index);
  1017. break;
  1018. case 1:
  1019. decl->starred_arg = index;
  1020. state+=1;
  1021. break;
  1022. case 2: {
  1023. consume(TK("="));
  1024. PyObject* value = read_literal();
  1025. if(value == nullptr){
  1026. SyntaxError(Str("default argument must be a literal"));
  1027. }
  1028. decl->add_kwarg(index, name, value);
  1029. } break;
  1030. case 3:
  1031. decl->starred_kwarg = index;
  1032. state+=1;
  1033. break;
  1034. }
  1035. } while (match(TK(",")));
  1036. }
  1037. void Compiler::compile_function(const Expr_vector& decorators){
  1038. const char* _start = curr().start;
  1039. consume(TK("@id"));
  1040. Str decl_name = prev().str();
  1041. FuncDecl_ decl = push_f_context(decl_name);
  1042. consume(TK("("));
  1043. if (!match(TK(")"))) {
  1044. _compile_f_args(decl, true);
  1045. consume(TK(")"));
  1046. }
  1047. if(match(TK("->"))) consume_type_hints();
  1048. const char* _end = curr().start;
  1049. decl->signature = Str(_start, _end-_start);
  1050. compile_block_body();
  1051. pop_context();
  1052. PyObject* docstring = nullptr;
  1053. if(decl->code->codes.size()>=2 && decl->code->codes[0].op == OP_LOAD_CONST && decl->code->codes[1].op == OP_POP_TOP){
  1054. PyObject* c = decl->code->consts[decl->code->codes[0].arg];
  1055. if(is_type(c, vm->tp_str)){
  1056. decl->code->codes[0].op = OP_NO_OP;
  1057. decl->code->codes[1].op = OP_NO_OP;
  1058. docstring = c;
  1059. }
  1060. }
  1061. if(docstring != nullptr){
  1062. decl->docstring = PK_OBJ_GET(Str, docstring);
  1063. }
  1064. ctx()->emit_(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line);
  1065. _add_decorators(decorators);
  1066. if(!ctx()->is_compiling_class){
  1067. auto e = make_expr<NameExpr>(decl_name, name_scope());
  1068. e->emit_store(ctx());
  1069. }else{
  1070. int index = StrName(decl_name).index;
  1071. ctx()->emit_(OP_STORE_CLASS_ATTR, index, prev().line);
  1072. }
  1073. }
  1074. PyObject* Compiler::to_object(const TokenValue& value){
  1075. PyObject* obj = nullptr;
  1076. if(std::holds_alternative<i64>(value)){
  1077. obj = VAR(std::get<i64>(value));
  1078. }
  1079. if(std::holds_alternative<f64>(value)){
  1080. obj = VAR(std::get<f64>(value));
  1081. }
  1082. if(std::holds_alternative<Str>(value)){
  1083. obj = VAR(std::get<Str>(value));
  1084. }
  1085. PK_ASSERT(obj != nullptr)
  1086. return obj;
  1087. }
  1088. PyObject* Compiler::read_literal(){
  1089. advance();
  1090. switch(prev().type){
  1091. case TK("-"): {
  1092. consume(TK("@num"));
  1093. PyObject* val = to_object(prev().value);
  1094. return vm->py_negate(val);
  1095. }
  1096. case TK("@num"): return to_object(prev().value);
  1097. case TK("@str"): return to_object(prev().value);
  1098. case TK("True"): return VAR(true);
  1099. case TK("False"): return VAR(false);
  1100. case TK("None"): return vm->None;
  1101. case TK("..."): return vm->Ellipsis;
  1102. case TK("("): {
  1103. List cpnts;
  1104. while(true) {
  1105. cpnts.push_back(read_literal());
  1106. if(curr().type == TK(")")) break;
  1107. consume(TK(","));
  1108. if(curr().type == TK(")")) break;
  1109. }
  1110. consume(TK(")"));
  1111. return VAR(Tuple(std::move(cpnts)));
  1112. }
  1113. default: break;
  1114. }
  1115. return nullptr;
  1116. }
  1117. Compiler::Compiler(VM* vm, std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope)
  1118. :lexer(vm, std::make_shared<SourceData>(source, filename, mode)){
  1119. this->vm = vm;
  1120. this->unknown_global_scope = unknown_global_scope;
  1121. init_pratt_rules();
  1122. }
  1123. CodeObject_ Compiler::compile(){
  1124. PK_ASSERT(i == 0) // make sure it is the first time to compile
  1125. tokens = lexer.run();
  1126. CodeObject_ code = push_global_context();
  1127. advance(); // skip @sof, so prev() is always valid
  1128. match_newlines(); // skip possible leading '\n'
  1129. if(mode()==EVAL_MODE) {
  1130. EXPR_TUPLE(); ctx()->emit_expr();
  1131. consume(TK("@eof"));
  1132. ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
  1133. pop_context();
  1134. return code;
  1135. }else if(mode()==JSON_MODE){
  1136. EXPR();
  1137. Expr_ e = ctx()->s_expr.popx();
  1138. if(!e->is_json_object()) SyntaxError("expect a JSON object, literal or array");
  1139. consume(TK("@eof"));
  1140. e->emit_(ctx());
  1141. ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
  1142. pop_context();
  1143. return code;
  1144. }
  1145. while (!match(TK("@eof"))) {
  1146. compile_stmt();
  1147. match_newlines();
  1148. }
  1149. pop_context();
  1150. return code;
  1151. }
  1152. // TODO: refactor this
  1153. void Lexer::throw_err(StrName type, Str msg, int lineno, const char* cursor){
  1154. PyObject* e_obj = vm->call(vm->builtins->attr(type), VAR(msg));
  1155. Exception& e = PK_OBJ_GET(Exception, e_obj);
  1156. e.st_push(src, lineno, cursor, "");
  1157. throw e;
  1158. }
  1159. } // namespace pkpy