compiler.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  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)(bool canAssign);
  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 uint8_t parseVariable(const char *);
  45. static void defineVariable(uint8_t);
  46. static uint8_t identifierConstant(Token *name);
  47. static ParseRule *getRule(TokenType);
  48. static void statement();
  49. static void declaration();
  50. static Chunk *currentChunk() {
  51. return compilingChunk;
  52. }
  53. static void errorAt(Token *token, const char *message) {
  54. if (parser.panicMode) return;
  55. parser.panicMode = true;
  56. fprintf(stderr, "[line %d] Error", token->line);
  57. if (token->type == TOKEN_EOF) {
  58. fprintf(stderr, " at end");
  59. } else if (token->type == TOKEN_ERROR) {
  60. ///! Nothing.
  61. } else {
  62. fprintf(stderr, " at '%.*s'", token->length, token->start);
  63. }
  64. fprintf(stderr, ": %s\n", message);
  65. parser.hadError = true;
  66. }
  67. static void error(const char *message) {
  68. errorAt(&parser.previous, message);
  69. }
  70. static void errorAtCurrent(const char *message) {
  71. errorAt(&parser.current, message);
  72. }
  73. static void advance() {
  74. parser.previous = parser.current;
  75. for (;;) {
  76. parser.current = scanToken();
  77. if (parser.current.type != TOKEN_ERROR) break;
  78. errorAtCurrent(parser.current.start);
  79. }
  80. }
  81. void consume(TokenType type, const char *message) {
  82. if (parser.current.type == type) {
  83. advance();
  84. return;
  85. }
  86. errorAtCurrent(message);
  87. }
  88. static bool check(TokenType type) {
  89. return parser.current.type == type;
  90. }
  91. static bool match(TokenType type) {
  92. if (!check(type)) return false;
  93. advance();
  94. return true;
  95. }
  96. static void emitByte(uint8_t byte) {
  97. writeChunk(currentChunk(), byte, parser.previous.line);
  98. }
  99. static void emitBytes(uint8_t byte1, uint8_t byte2) {
  100. emitByte(byte1);
  101. emitByte(byte2);
  102. }
  103. static void emitReturn() {
  104. emitByte(OP_RETURN);
  105. }
  106. static uint8_t makeConstant(Value value) {
  107. int constant = addConstant(currentChunk(), value);
  108. if (constant > UINT8_MAX) {
  109. error("Too many constants in one chunk.");
  110. return 0;
  111. }
  112. return (uint8_t) constant;
  113. }
  114. static void expression() {
  115. parsePrecedence(PREC_ASSIGNMENT);
  116. }
  117. /// for example: var a; var b = 10;
  118. static void varDeclaration() {
  119. uint8_t global = parseVariable("Expect variable name.");
  120. if (match(TOKEN_EQUAL)) {
  121. expression();
  122. } else {
  123. emitByte(OP_NIL);
  124. }
  125. consume(TOKEN_SEMICOLON, "Expect ';' after variable declaration.");
  126. defineVariable(global);
  127. }
  128. static void expressionStatement() {
  129. expression();
  130. consume(TOKEN_SEMICOLON, "Expect ';' after expression.");
  131. emitByte(OP_POP);
  132. }
  133. static void printStatement() {
  134. expression();
  135. consume(TOKEN_SEMICOLON, "Expect ';' after value.");
  136. emitByte(OP_PRINT);
  137. }
  138. static void synchronize() {
  139. parser.panicMode = false;
  140. while (parser.current.type != TOKEN_EOF) {
  141. if (parser.previous.type == TOKEN_SEMICOLON) return;
  142. switch (parser.current.type) {
  143. case TOKEN_CLASS:
  144. case TOKEN_FUN:
  145. case TOKEN_VAR:
  146. case TOKEN_FOR:
  147. case TOKEN_IF:
  148. case TOKEN_WHILE:
  149. case TOKEN_PRINT:
  150. case TOKEN_RETURN:
  151. return;
  152. default:;// Do nothing.
  153. }
  154. advance();
  155. }
  156. }
  157. ///declaration → classDecl
  158. /// | funDecl
  159. /// | varDecl
  160. /// | statement ;
  161. static void declaration() {
  162. if (match(TOKEN_VAR)) {
  163. varDeclaration();
  164. } else {
  165. statement();
  166. }
  167. if (parser.panicMode) synchronize();
  168. }
  169. ///statement → exprStmt
  170. /// | forStmt
  171. /// | ifStmt
  172. /// | printStmt
  173. /// | returnStmt
  174. /// | whileStmt
  175. /// | block ;
  176. static void statement() {
  177. if (match(TOKEN_PRINT)) {
  178. printStatement();
  179. } else {
  180. expressionStatement();
  181. }
  182. }
  183. static void emitConstant(Value value) {
  184. emitBytes(OP_CONSTANT, makeConstant(value));
  185. }
  186. static void endCompiler() {
  187. emitReturn();
  188. #ifdef DEBUG_PRINT_CODE
  189. if (!parser.hadError) {
  190. disassembleChunk(currentChunk(), "code");
  191. }
  192. #endif
  193. }
  194. static void grouping(__attribute__((unused)) bool canAssign) {
  195. expression();
  196. consume(TOKEN_RIGHT_PAREN, "Expect ')' after expression.");
  197. }
  198. /// \brief parse number token
  199. /// Number literals: 123
  200. static void number(__attribute__((unused)) bool canAssign) {
  201. double value = strtod(parser.previous.start, NULL);
  202. emitConstant(NUMBER_VAL(value));
  203. }
  204. static void string(__attribute__((unused)) bool canAssign) {
  205. emitConstant(OBJ_VAL(copyString(parser.previous.start + 1,
  206. parser.previous.length - 2)));
  207. }
  208. static void namedVariable(Token name, bool canAssign) {
  209. uint8_t arg = identifierConstant(&name);
  210. if (canAssign && match(TOKEN_EQUAL)) {
  211. // 如 menu.brunch(sunday).beverage = "mimosa";
  212. expression();
  213. emitBytes(OP_SET_GLOBAL, arg);
  214. } else {
  215. emitBytes(OP_GET_GLOBAL, arg);
  216. }
  217. }
  218. static void variable(bool canAssign) {
  219. namedVariable(parser.previous, canAssign);
  220. }
  221. /// Unary negation: -123
  222. static void unary(__attribute__((unused)) bool canAssign) {
  223. TokenType operatorType = parser.previous.type;
  224. // Compile the operand.
  225. parsePrecedence(PREC_UNARY);
  226. // Emit the operator instruction.
  227. switch (operatorType) {
  228. case TOKEN_BANG:
  229. emitByte(OP_NOT);
  230. break;
  231. case TOKEN_MINUS:
  232. emitByte(OP_NEGATE);
  233. break;
  234. default: return;// Unreachable.
  235. }
  236. }
  237. /// \brief infix parser
  238. static void binary(__attribute__((unused)) bool canAssign) {
  239. TokenType operatorType = parser.previous.type;
  240. ParseRule *rule = getRule(operatorType);
  241. parsePrecedence((Precedence) rule->precedence + 1);
  242. switch (operatorType) {
  243. case TOKEN_BANG_EQUAL:
  244. emitBytes(OP_EQUAL, OP_NOT);
  245. break;
  246. case TOKEN_EQUAL_EQUAL:
  247. emitByte(OP_EQUAL);
  248. break;
  249. case TOKEN_GREATER:
  250. emitByte(OP_GREATER);
  251. break;
  252. case TOKEN_GREATER_EQUAL:
  253. emitBytes(OP_LESS, OP_NOT);
  254. break;
  255. case TOKEN_LESS:
  256. emitByte(OP_LESS);
  257. break;
  258. case TOKEN_LESS_EQUAL:
  259. emitBytes(OP_GREATER, OP_NOT);
  260. break;
  261. case TOKEN_PLUS:
  262. emitByte(OP_ADD);
  263. break;
  264. case TOKEN_MINUS:
  265. emitByte(OP_SUBTRACT);
  266. break;
  267. case TOKEN_STAR:
  268. emitByte(OP_MULTIPLY);
  269. break;
  270. case TOKEN_SLASH:
  271. emitByte(OP_DIVIDE);
  272. break;
  273. default: return;// Unreachable.
  274. }
  275. }
  276. static void literal(__attribute__((unused)) bool canAssign) {
  277. switch (parser.previous.type) {
  278. case TOKEN_FALSE:
  279. emitByte(OP_FALSE);
  280. break;
  281. case TOKEN_NIL:
  282. emitByte(OP_NIL);
  283. break;
  284. case TOKEN_TRUE:
  285. emitByte(OP_TRUE);
  286. break;
  287. default: return;// Unreachable
  288. }
  289. }
  290. ParseRule rules[] = {
  291. [TOKEN_LEFT_PAREN] = {grouping, NULL, PREC_NONE},
  292. [TOKEN_RIGHT_PAREN] = {NULL, NULL, PREC_NONE},
  293. [TOKEN_LEFT_BRACE] = {NULL, NULL, PREC_NONE},
  294. [TOKEN_RIGHT_BRACE] = {NULL, NULL, PREC_NONE},
  295. [TOKEN_COMMA] = {NULL, NULL, PREC_NONE},
  296. [TOKEN_DOT] = {NULL, NULL, PREC_NONE},
  297. [TOKEN_MINUS] = {unary, binary, PREC_TERM},
  298. [TOKEN_PLUS] = {NULL, binary, PREC_TERM},
  299. [TOKEN_SEMICOLON] = {NULL, NULL, PREC_NONE},
  300. [TOKEN_SLASH] = {NULL, binary, PREC_FACTOR},
  301. [TOKEN_STAR] = {NULL, binary, PREC_FACTOR},
  302. [TOKEN_BANG] = {unary, NULL, PREC_NONE},
  303. [TOKEN_BANG_EQUAL] = {NULL, binary, PREC_EQUALITY},
  304. [TOKEN_EQUAL] = {NULL, NULL, PREC_NONE},
  305. [TOKEN_EQUAL_EQUAL] = {NULL, binary, PREC_EQUALITY},
  306. [TOKEN_GREATER] = {NULL, binary, PREC_COMPARISON},
  307. [TOKEN_GREATER_EQUAL] = {NULL, binary, PREC_COMPARISON},
  308. [TOKEN_LESS] = {NULL, binary, PREC_COMPARISON},
  309. [TOKEN_LESS_EQUAL] = {NULL, binary, PREC_COMPARISON},
  310. [TOKEN_IDENTIFIER] = {variable, NULL, PREC_NONE},
  311. [TOKEN_STRING] = {string, NULL, PREC_NONE},
  312. [TOKEN_NUMBER] = {number, NULL, PREC_NONE},
  313. [TOKEN_AND] = {NULL, NULL, PREC_NONE},
  314. [TOKEN_CLASS] = {NULL, NULL, PREC_NONE},
  315. [TOKEN_ELSE] = {NULL, NULL, PREC_NONE},
  316. [TOKEN_FALSE] = {literal, NULL, PREC_NONE},
  317. [TOKEN_FOR] = {NULL, NULL, PREC_NONE},
  318. [TOKEN_FUN] = {NULL, NULL, PREC_NONE},
  319. [TOKEN_IF] = {NULL, NULL, PREC_NONE},
  320. [TOKEN_NIL] = {literal, NULL, PREC_NONE},
  321. [TOKEN_OR] = {NULL, NULL, PREC_NONE},
  322. [TOKEN_PRINT] = {NULL, NULL, PREC_NONE},
  323. [TOKEN_RETURN] = {NULL, NULL, PREC_NONE},
  324. [TOKEN_SUPER] = {NULL, NULL, PREC_NONE},
  325. [TOKEN_THIS] = {NULL, NULL, PREC_NONE},
  326. [TOKEN_TRUE] = {literal, NULL, PREC_NONE},
  327. [TOKEN_VAR] = {NULL, NULL, PREC_NONE},
  328. [TOKEN_WHILE] = {NULL, NULL, PREC_NONE},
  329. [TOKEN_ERROR] = {NULL, NULL, PREC_NONE},
  330. [TOKEN_EOF] = {NULL, NULL, PREC_NONE},
  331. };
  332. /// \brief 优先级处理
  333. /// \param precedence
  334. static void parsePrecedence(Precedence precedence) {
  335. advance();
  336. ParseFn prefixRule = getRule(parser.previous.type)->prefix;
  337. if (prefixRule == NULL) {
  338. error("Expect expression.");
  339. return;
  340. }
  341. bool canAssign = precedence <= PREC_ASSIGNMENT;
  342. prefixRule(canAssign);///! 执行具体函数
  343. while (precedence <= getRule(parser.current.type)->precedence) {
  344. advance();
  345. ParseFn infixRule = getRule(parser.previous.type)->infix;
  346. infixRule(canAssign);///! 执行具体函数
  347. }
  348. if (canAssign && match(TOKEN_EQUAL)) {
  349. error("Invalid assignment target.");
  350. }
  351. }
  352. static uint8_t identifierConstant(Token *name) {
  353. return makeConstant(OBJ_VAL(copyString(name->start, name->length)));
  354. }
  355. static uint8_t parseVariable(const char *errorMessage) {
  356. consume(TOKEN_IDENTIFIER, errorMessage);
  357. return identifierConstant(&parser.previous);
  358. }
  359. static void defineVariable(uint8_t global) {
  360. emitBytes(OP_DEFINE_GLOBAL, global);
  361. }
  362. static ParseRule *getRule(TokenType type) {
  363. return &rules[type];
  364. }
  365. /**
  366. ******************************************************************************
  367. * statement → exprStmt
  368. | forStmt
  369. | ifStmt
  370. | printStmt
  371. | returnStmt
  372. | whileStmt
  373. | block ;
  374. declaration → classDecl
  375. | funDecl
  376. | varDecl
  377. | statement ;
  378. ******************************************************************************
  379. */
  380. bool compile(const char *source, Chunk *chunk) {
  381. initScanner(source);
  382. compilingChunk = chunk;
  383. parser.hadError = false;
  384. parser.panicMode = false;
  385. advance();
  386. while (!match(TOKEN_EOF)) {
  387. declaration();
  388. }
  389. endCompiler();//! return opcode
  390. return !parser.hadError;
  391. }