compiler.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /**
  2. ******************************************************************************
  3. * @file : compiler.c
  4. * @author : simon
  5. * @brief : None
  6. * @attention : None
  7. * @date : 2023/8/17
  8. ******************************************************************************
  9. */
  10. #include "common.h"
  11. #include "compiler.h"
  12. #include "scanner.h"
  13. #ifdef DEBUG_PRINT_CODE
  14. #include "debug.h"
  15. #endif
  16. typedef struct {
  17. Token current;
  18. Token previous;
  19. bool hadError;
  20. bool panicMode;
  21. } Parser;
  22. typedef enum {
  23. PREC_NONE,
  24. PREC_ASSIGNMENT, // =
  25. PREC_OR, // or
  26. PREC_AND, // and
  27. PREC_EQUALITY, // == !=
  28. PREC_COMPARISON, // < > <= >=
  29. PREC_TERM, // + -
  30. PREC_FACTOR, // * /
  31. PREC_UNARY, // ! -
  32. PREC_CALL, // . ()
  33. PREC_PRIMARY
  34. } Precedence;
  35. typedef void (*ParseFn)();
  36. typedef struct {
  37. ParseFn prefix;
  38. ParseFn infix;
  39. Precedence precedence;
  40. } ParseRule;
  41. Parser parser;
  42. Chunk *compilingChunk;
  43. static void parsePrecedence(Precedence);
  44. static ParseRule *getRule(TokenType);
  45. static Chunk *currentChunk() {
  46. return compilingChunk;
  47. }
  48. static void errorAt(Token *token, const char *message) {
  49. if (parser.panicMode) return;
  50. parser.panicMode = true;
  51. fprintf(stderr, "[line %d] Error", token->line);
  52. if (token->type == TOKEN_EOF) {
  53. fprintf(stderr, " at end");
  54. } else if (token->type == TOKEN_ERROR) {
  55. ///! Nothing.
  56. } else {
  57. fprintf(stderr, " at '%.*s'", token->length, token->start);
  58. }
  59. fprintf(stderr, ": %s\n", message);
  60. parser.hadError = true;
  61. }
  62. static void error(const char *message) {
  63. errorAt(&parser.previous, message);
  64. }
  65. static void errorAtCurrent(const char *message) {
  66. errorAt(&parser.current, message);
  67. }
  68. static void advance() {
  69. parser.previous = parser.current;
  70. for (;;) {
  71. parser.current = scanToken();
  72. if (parser.current.type != TOKEN_ERROR) break;
  73. errorAtCurrent(parser.current.start);
  74. }
  75. }
  76. void consume(TokenType type, const char *message) {
  77. if (parser.current.type == type) {
  78. advance();
  79. return;
  80. }
  81. errorAtCurrent(message);
  82. }
  83. static void emitByte(uint8_t byte) {
  84. writeChunk(currentChunk(), byte, parser.previous.line);
  85. }
  86. static void emitBytes(uint8_t byte1, uint8_t byte2) {
  87. emitByte(byte1);
  88. emitByte(byte2);
  89. }
  90. static void emitReturn() {
  91. emitByte(OP_RETURN);
  92. }
  93. static uint8_t makeConstant(double value) {
  94. int constant = addConstant(currentChunk(), value);
  95. if (constant > UINT8_MAX) {
  96. error("Too many constants in one chunk.");
  97. return 0;
  98. }
  99. return (uint8_t) constant;
  100. }
  101. static void expression() {
  102. parsePrecedence(PREC_ASSIGNMENT);
  103. }
  104. static void emitConstant(double value) {
  105. emitBytes(OP_CONSTANT, makeConstant(value));
  106. }
  107. static void endCompiler() {
  108. emitReturn();
  109. #ifdef DEBUG_PRINT_CODE
  110. if (!parser.hadError) {
  111. disassembleChunk(currentChunk(), "code");
  112. }
  113. #endif
  114. }
  115. static void grouping() {
  116. expression();
  117. consume(TOKEN_RIGHT_PAREN, "Expect ')' after expression.");
  118. }
  119. /// \brief parse number token
  120. /// Number literals: 123
  121. static void number() {
  122. double value = strtod(parser.previous.start, NULL);
  123. emitConstant(value);
  124. }
  125. /// Unary negation: -123
  126. static void unary() {
  127. TokenType operatorType = parser.previous.type;
  128. // Compile the operand.
  129. parsePrecedence(PREC_UNARY);
  130. // Emit the operator instruction.
  131. switch (operatorType) {
  132. case TOKEN_MINUS: emitByte(OP_NEGATE);
  133. break;
  134. default: return; // Unreachable.
  135. }
  136. }
  137. /// \brief infix parser
  138. static void binary() {
  139. TokenType operatorType = parser.previous.type;
  140. ParseRule *rule = getRule(operatorType);
  141. parsePrecedence((Precedence) rule->precedence + 1);
  142. switch (operatorType) {
  143. case TOKEN_PLUS: emitByte(OP_ADD);
  144. break;
  145. case TOKEN_MINUS: emitByte(OP_SUBTRACT);
  146. break;
  147. case TOKEN_STAR: emitByte(OP_MULTIPLY);
  148. break;
  149. case TOKEN_SLASH: emitByte(OP_DIVIDE);
  150. break;
  151. default: return; // Unreachable.
  152. }
  153. }
  154. ParseRule rules[] = {
  155. [TOKEN_LEFT_PAREN] = {grouping, NULL, PREC_NONE},
  156. [TOKEN_RIGHT_PAREN] = {NULL, NULL, PREC_NONE},
  157. [TOKEN_LEFT_BRACE] = {NULL, NULL, PREC_NONE},
  158. [TOKEN_RIGHT_BRACE] = {NULL, NULL, PREC_NONE},
  159. [TOKEN_COMMA] = {NULL, NULL, PREC_NONE},
  160. [TOKEN_DOT] = {NULL, NULL, PREC_NONE},
  161. [TOKEN_MINUS] = {unary, binary, PREC_TERM},
  162. [TOKEN_PLUS] = {NULL, binary, PREC_TERM},
  163. [TOKEN_SEMICOLON] = {NULL, NULL, PREC_NONE},
  164. [TOKEN_SLASH] = {NULL, binary, PREC_FACTOR},
  165. [TOKEN_STAR] = {NULL, binary, PREC_FACTOR},
  166. [TOKEN_BANG] = {NULL, NULL, PREC_NONE},
  167. [TOKEN_BANG_EQUAL] = {NULL, NULL, PREC_NONE},
  168. [TOKEN_EQUAL] = {NULL, NULL, PREC_NONE},
  169. [TOKEN_EQUAL_EQUAL] = {NULL, NULL, PREC_NONE},
  170. [TOKEN_GREATER] = {NULL, NULL, PREC_NONE},
  171. [TOKEN_GREATER_EQUAL] = {NULL, NULL, PREC_NONE},
  172. [TOKEN_LESS] = {NULL, NULL, PREC_NONE},
  173. [TOKEN_LESS_EQUAL] = {NULL, NULL, PREC_NONE},
  174. [TOKEN_IDENTIFIER] = {NULL, NULL, PREC_NONE},
  175. [TOKEN_STRING] = {NULL, NULL, PREC_NONE},
  176. [TOKEN_NUMBER] = {number, NULL, PREC_NONE},
  177. [TOKEN_AND] = {NULL, NULL, PREC_NONE},
  178. [TOKEN_CLASS] = {NULL, NULL, PREC_NONE},
  179. [TOKEN_ELSE] = {NULL, NULL, PREC_NONE},
  180. [TOKEN_FALSE] = {NULL, NULL, PREC_NONE},
  181. [TOKEN_FOR] = {NULL, NULL, PREC_NONE},
  182. [TOKEN_FUN] = {NULL, NULL, PREC_NONE},
  183. [TOKEN_IF] = {NULL, NULL, PREC_NONE},
  184. [TOKEN_NIL] = {NULL, NULL, PREC_NONE},
  185. [TOKEN_OR] = {NULL, NULL, PREC_NONE},
  186. [TOKEN_PRINT] = {NULL, NULL, PREC_NONE},
  187. [TOKEN_RETURN] = {NULL, NULL, PREC_NONE},
  188. [TOKEN_SUPER] = {NULL, NULL, PREC_NONE},
  189. [TOKEN_THIS] = {NULL, NULL, PREC_NONE},
  190. [TOKEN_TRUE] = {NULL, NULL, PREC_NONE},
  191. [TOKEN_VAR] = {NULL, NULL, PREC_NONE},
  192. [TOKEN_WHILE] = {NULL, NULL, PREC_NONE},
  193. [TOKEN_ERROR] = {NULL, NULL, PREC_NONE},
  194. [TOKEN_EOF] = {NULL, NULL, PREC_NONE},
  195. };
  196. /// \brief 优先级处理
  197. /// \param precedence
  198. static void parsePrecedence(Precedence precedence) {
  199. advance();
  200. ParseFn prefixRule = getRule(parser.previous.type)->prefix;
  201. if (prefixRule == NULL) {
  202. error("Expect expression.");
  203. return;
  204. }
  205. prefixRule(); ///! 执行具体函数
  206. while (precedence <= getRule(parser.current.type)->precedence) {
  207. advance();
  208. ParseFn infixRule = getRule(parser.previous.type)->infix;
  209. infixRule(); ///! 执行具体函数
  210. }
  211. }
  212. static ParseRule *getRule(TokenType type) {
  213. return &rules[type];
  214. }
  215. bool compile(const char *source, Chunk *chunk) {
  216. initScanner(source);
  217. compilingChunk = chunk;
  218. parser.hadError = false;
  219. parser.panicMode = false;
  220. advance();
  221. expression();
  222. consume(TOKEN_EOF, "Expect end of expression");
  223. endCompiler(); //! return opcode
  224. return !parser.hadError;
  225. }