compiler.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #pragma once
  2. #include "codeobject.h"
  3. #include "common.h"
  4. #include "expr.h"
  5. #include "obj.h"
  6. namespace pkpy{
  7. class Compiler;
  8. typedef void (Compiler::*PrattCallback)();
  9. struct PrattRule{
  10. PrattCallback prefix;
  11. PrattCallback infix;
  12. Precedence precedence;
  13. };
  14. class Compiler {
  15. inline static PrattRule rules[kTokenCount];
  16. std::unique_ptr<Lexer> lexer;
  17. stack<CodeEmitContext> contexts;
  18. VM* vm;
  19. bool unknown_global_scope; // for eval/exec() call
  20. bool used;
  21. // for parsing token stream
  22. int i = 0;
  23. std::vector<Token> tokens;
  24. const Token& prev() const{ return tokens.at(i-1); }
  25. const Token& curr() const{ return tokens.at(i); }
  26. const Token& next() const{ return tokens.at(i+1); }
  27. const Token& err() const{
  28. if(i >= tokens.size()) return prev();
  29. return curr();
  30. }
  31. void advance(int delta=1) { i += delta; }
  32. CodeEmitContext* ctx() { return &contexts.top(); }
  33. CompileMode mode() const{ return lexer->src->mode; }
  34. NameScope name_scope() const;
  35. CodeObject_ push_global_context();
  36. FuncDecl_ push_f_context(Str name);
  37. void pop_context();
  38. static void init_pratt_rules();
  39. bool match(TokenIndex expected);
  40. void consume(TokenIndex expected);
  41. bool match_newlines_repl();
  42. bool match_newlines(bool repl_throw=false);
  43. bool match_end_stmt();
  44. void consume_end_stmt();
  45. /*************************************************/
  46. void EXPR(bool push_stack=true);
  47. void EXPR_TUPLE(bool push_stack=true);
  48. Expr_ EXPR_VARS(); // special case for `for loop` and `comp`
  49. template <typename T, typename... Args>
  50. std::unique_ptr<T> make_expr(Args&&... args) {
  51. std::unique_ptr<T> expr = std::make_unique<T>(std::forward<Args>(args)...);
  52. expr->line = prev().line;
  53. return expr;
  54. }
  55. template<typename T>
  56. void _consume_comp(Expr_ expr){
  57. static_assert(std::is_base_of<CompExpr, T>::value);
  58. std::unique_ptr<CompExpr> ce = make_expr<T>();
  59. ce->expr = std::move(expr);
  60. ce->vars = EXPR_VARS();
  61. consume(TK("in"));
  62. parse_expression(PREC_TERNARY + 1);
  63. ce->iter = ctx()->s_expr.popx();
  64. match_newlines_repl();
  65. if(match(TK("if"))){
  66. parse_expression(PREC_TERNARY + 1);
  67. ce->cond = ctx()->s_expr.popx();
  68. }
  69. ctx()->s_expr.push(std::move(ce));
  70. match_newlines_repl();
  71. }
  72. void exprLiteral();
  73. void exprLong();
  74. void exprBytes();
  75. void exprFString();
  76. void exprLambda();
  77. void exprTuple();
  78. void exprOr();
  79. void exprAnd();
  80. void exprTernary();
  81. void exprBinaryOp();
  82. void exprNot();
  83. void exprUnaryOp();
  84. void exprGroup();
  85. void exprList();
  86. void exprMap();
  87. void exprCall();
  88. void exprName();
  89. void exprAttrib();
  90. void exprSubscr();
  91. void exprLiteral0();
  92. void compile_block_body();
  93. void compile_normal_import();
  94. void compile_from_import();
  95. bool is_expression();
  96. void parse_expression(int precedence, bool push_stack=true);
  97. void compile_if_stmt();
  98. void compile_while_loop();
  99. void compile_for_loop();
  100. void compile_try_except();
  101. void compile_decorated();
  102. bool try_compile_assignment();
  103. void compile_stmt();
  104. void consume_type_hints();
  105. void compile_class();
  106. void _compile_f_args(FuncDecl_ decl, bool enable_type_hints);
  107. void compile_function(const std::vector<Expr_>& decorators={});
  108. PyObject* to_object(const TokenValue& value);
  109. PyObject* read_literal();
  110. void SyntaxError(Str msg){ lexer->throw_err("SyntaxError", msg, err().line, err().start); }
  111. void SyntaxError(){ lexer->throw_err("SyntaxError", "invalid syntax", err().line, err().start); }
  112. void IndentationError(Str msg){ lexer->throw_err("IndentationError", msg, err().line, err().start); }
  113. public:
  114. Compiler(VM* vm, const Str& source, const Str& filename, CompileMode mode, bool unknown_global_scope=false);
  115. CodeObject_ compile();
  116. Compiler(const Compiler&) = delete;
  117. Compiler& operator=(const Compiler&) = delete;
  118. };
  119. } // namespace pkpy