compiler.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /**
  2. ******************************************************************************
  3. * @file : compiler.c
  4. * @author : simon
  5. * @brief : None
  6. * @attention : None
  7. * @date : 2023/8/17
  8. ******************************************************************************
  9. */
  10. #include "compiler.h"
  11. #include "common.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(Value 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(Value 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(NUMBER_VAL(value));
  124. }
  125. static void string() {
  126. emitConstant(OBJ_VAL(copyString(parser.previous.start + 1,
  127. parser.previous.length - 2)));
  128. }
  129. /// Unary negation: -123
  130. static void unary() {
  131. TokenType operatorType = parser.previous.type;
  132. // Compile the operand.
  133. parsePrecedence(PREC_UNARY);
  134. // Emit the operator instruction.
  135. switch (operatorType) {
  136. case TOKEN_BANG:
  137. emitByte(OP_NOT);
  138. break;
  139. case TOKEN_MINUS:
  140. emitByte(OP_NEGATE);
  141. break;
  142. default: return;// Unreachable.
  143. }
  144. }
  145. /// \brief infix parser
  146. static void binary() {
  147. TokenType operatorType = parser.previous.type;
  148. ParseRule *rule = getRule(operatorType);
  149. parsePrecedence((Precedence) rule->precedence + 1);
  150. switch (operatorType) {
  151. case TOKEN_BANG_EQUAL:
  152. emitBytes(OP_EQUAL, OP_NOT);
  153. break;
  154. case TOKEN_EQUAL_EQUAL:
  155. emitByte(OP_EQUAL);
  156. break;
  157. case TOKEN_GREATER:
  158. emitByte(OP_GREATER);
  159. break;
  160. case TOKEN_GREATER_EQUAL:
  161. emitBytes(OP_LESS, OP_NOT);
  162. break;
  163. case TOKEN_LESS:
  164. emitByte(OP_LESS);
  165. break;
  166. case TOKEN_LESS_EQUAL:
  167. emitBytes(OP_GREATER, OP_NOT);
  168. break;
  169. case TOKEN_PLUS:
  170. emitByte(OP_ADD);
  171. break;
  172. case TOKEN_MINUS:
  173. emitByte(OP_SUBTRACT);
  174. break;
  175. case TOKEN_STAR:
  176. emitByte(OP_MULTIPLY);
  177. break;
  178. case TOKEN_SLASH:
  179. emitByte(OP_DIVIDE);
  180. break;
  181. default: return;// Unreachable.
  182. }
  183. }
  184. static void literal() {
  185. switch (parser.previous.type) {
  186. case TOKEN_FALSE:
  187. emitByte(OP_FALSE);
  188. break;
  189. case TOKEN_NIL:
  190. emitByte(OP_NIL);
  191. break;
  192. case TOKEN_TRUE:
  193. emitByte(OP_TRUE);
  194. break;
  195. default: return;// Unreachable
  196. }
  197. }
  198. ParseRule rules[] = {
  199. [TOKEN_LEFT_PAREN] = {grouping, NULL, PREC_NONE},
  200. [TOKEN_RIGHT_PAREN] = {NULL, NULL, PREC_NONE},
  201. [TOKEN_LEFT_BRACE] = {NULL, NULL, PREC_NONE},
  202. [TOKEN_RIGHT_BRACE] = {NULL, NULL, PREC_NONE},
  203. [TOKEN_COMMA] = {NULL, NULL, PREC_NONE},
  204. [TOKEN_DOT] = {NULL, NULL, PREC_NONE},
  205. [TOKEN_MINUS] = {unary, binary, PREC_TERM},
  206. [TOKEN_PLUS] = {NULL, binary, PREC_TERM},
  207. [TOKEN_SEMICOLON] = {NULL, NULL, PREC_NONE},
  208. [TOKEN_SLASH] = {NULL, binary, PREC_FACTOR},
  209. [TOKEN_STAR] = {NULL, binary, PREC_FACTOR},
  210. [TOKEN_BANG] = {unary, NULL, PREC_NONE},
  211. [TOKEN_BANG_EQUAL] = {NULL, binary, PREC_EQUALITY},
  212. [TOKEN_EQUAL] = {NULL, NULL, PREC_NONE},
  213. [TOKEN_EQUAL_EQUAL] = {NULL, binary, PREC_EQUALITY},
  214. [TOKEN_GREATER] = {NULL, binary, PREC_COMPARISON},
  215. [TOKEN_GREATER_EQUAL] = {NULL, binary, PREC_COMPARISON},
  216. [TOKEN_LESS] = {NULL, binary, PREC_COMPARISON},
  217. [TOKEN_LESS_EQUAL] = {NULL, binary, PREC_COMPARISON},
  218. [TOKEN_IDENTIFIER] = {NULL, NULL, PREC_NONE},
  219. [TOKEN_STRING] = {string, NULL, PREC_NONE},
  220. [TOKEN_NUMBER] = {number, NULL, PREC_NONE},
  221. [TOKEN_AND] = {NULL, NULL, PREC_NONE},
  222. [TOKEN_CLASS] = {NULL, NULL, PREC_NONE},
  223. [TOKEN_ELSE] = {NULL, NULL, PREC_NONE},
  224. [TOKEN_FALSE] = {literal, NULL, PREC_NONE},
  225. [TOKEN_FOR] = {NULL, NULL, PREC_NONE},
  226. [TOKEN_FUN] = {NULL, NULL, PREC_NONE},
  227. [TOKEN_IF] = {NULL, NULL, PREC_NONE},
  228. [TOKEN_NIL] = {literal, NULL, PREC_NONE},
  229. [TOKEN_OR] = {NULL, NULL, PREC_NONE},
  230. [TOKEN_PRINT] = {NULL, NULL, PREC_NONE},
  231. [TOKEN_RETURN] = {NULL, NULL, PREC_NONE},
  232. [TOKEN_SUPER] = {NULL, NULL, PREC_NONE},
  233. [TOKEN_THIS] = {NULL, NULL, PREC_NONE},
  234. [TOKEN_TRUE] = {literal, NULL, PREC_NONE},
  235. [TOKEN_VAR] = {NULL, NULL, PREC_NONE},
  236. [TOKEN_WHILE] = {NULL, NULL, PREC_NONE},
  237. [TOKEN_ERROR] = {NULL, NULL, PREC_NONE},
  238. [TOKEN_EOF] = {NULL, NULL, PREC_NONE},
  239. };
  240. /// \brief 优先级处理
  241. /// \param precedence
  242. static void parsePrecedence(Precedence precedence) {
  243. advance();
  244. ParseFn prefixRule = getRule(parser.previous.type)->prefix;
  245. if (prefixRule == NULL) {
  246. error("Expect expression.");
  247. return;
  248. }
  249. prefixRule();///! 执行具体函数
  250. while (precedence <= getRule(parser.current.type)->precedence) {
  251. advance();
  252. ParseFn infixRule = getRule(parser.previous.type)->infix;
  253. infixRule();///! 执行具体函数
  254. }
  255. }
  256. static ParseRule *getRule(TokenType type) {
  257. return &rules[type];
  258. }
  259. bool compile(const char *source, Chunk *chunk) {
  260. initScanner(source);
  261. compilingChunk = chunk;
  262. parser.hadError = false;
  263. parser.panicMode = false;
  264. advance();
  265. expression();
  266. consume(TOKEN_EOF, "Expect end of expression");
  267. endCompiler();//! return opcode
  268. return !parser.hadError;
  269. }