| author | |
| committer | |
| log | e579011a6e6311be9b854e17c3a6583b72126b1b |
| tree | caaf3903dfbd34ab02665cb07c92d751ee61abc8 |
| parent | 079ed9e3569b60f45f5a0362a67c1d3a8b2d3665 |
4 files changed, 50 insertions(+), 60 deletions(-)
README.md+2-2| ... | ... | @@ -80,11 +80,11 @@ ParamDecl : token(Symbol) token(Colon) Type |
| 80 | 80 | |
| 81 | 81 | Type : token(Symbol) | PointerType | token(Unreachable) |
| 82 | 82 | |
| 83 | PointerType : token(Star) token(Const) Type | token(Star) token(Mut) Type | |
| 83 | PointerType : token(Star) token(Const) Type | token(Star) token(Mut) Type | |
| 84 | 84 | |
| 85 | 85 | Block : token(LBrace) many(Statement) token(RBrace) |
| 86 | 86 | |
| 87 | Statement : ExpressionStatement | ReturnStatement | |
| 87 | Statement : ExpressionStatement | ReturnStatement | |
| 88 | 88 | |
| 89 | 89 | ExpressionStatement : Expression token(Semicolon) |
| 90 | 90 |
src/codegen.cpp+22-15| ... | ... | @@ -292,15 +292,11 @@ static void analyze_node(CodeGen *g, AstNode *node) { |
| 292 | 292 | analyze_node(g, child); |
| 293 | 293 | } |
| 294 | 294 | break; |
| 295 | case NodeTypeStatement: | |
| 296 | switch (node->data.statement.type) { | |
| 297 | case AstNodeStatementTypeExpression: | |
| 298 | analyze_node(g, node->data.statement.data.expr.expression); | |
| 299 | break; | |
| 300 | case AstNodeStatementTypeReturn: | |
| 301 | analyze_node(g, node->data.statement.data.retrn.expression); | |
| 302 | break; | |
| 303 | } | |
| 295 | case NodeTypeStatementExpression: | |
| 296 | analyze_node(g, node->data.statement_expression.expression); | |
| 297 | break; | |
| 298 | case NodeTypeStatementReturn: | |
| 299 | analyze_node(g, node->data.statement_return.expression); | |
| 304 | 300 | break; |
| 305 | 301 | case NodeTypeExpression: |
| 306 | 302 | switch (node->data.expression.type) { |
| ... | ... | @@ -514,23 +510,34 @@ static void gen_block(CodeGen *g, AstNode *block_node) { |
| 514 | 510 | |
| 515 | 511 | for (int i = 0; i < block_node->data.block.statements.length; i += 1) { |
| 516 | 512 | AstNode *statement_node = block_node->data.block.statements.at(i); |
| 517 | assert(statement_node->type == NodeTypeStatement); | |
| 518 | switch (statement_node->data.statement.type) { | |
| 519 | case AstNodeStatementTypeReturn: | |
| 513 | switch (statement_node->type) { | |
| 514 | case NodeTypeStatementReturn: | |
| 520 | 515 | { |
| 521 | AstNode *expr_node = statement_node->data.statement.data.retrn.expression; | |
| 516 | AstNode *expr_node = statement_node->data.statement_return.expression; | |
| 522 | 517 | LLVMValueRef value = gen_expr(g, expr_node); |
| 523 | 518 | |
| 524 | 519 | add_debug_source_node(g, statement_node); |
| 525 | 520 | LLVMBuildRet(g->builder, value); |
| 526 | 521 | break; |
| 527 | 522 | } |
| 528 | case AstNodeStatementTypeExpression: | |
| 523 | case NodeTypeStatementExpression: | |
| 529 | 524 | { |
| 530 | AstNode *expr_node = statement_node->data.statement.data.expr.expression; | |
| 525 | AstNode *expr_node = statement_node->data.statement_expression.expression; | |
| 531 | 526 | gen_expr(g, expr_node); |
| 532 | 527 | break; |
| 533 | 528 | } |
| 529 | case NodeTypeRoot: | |
| 530 | case NodeTypeFnProto: | |
| 531 | case NodeTypeFnDef: | |
| 532 | case NodeTypeFnDecl: | |
| 533 | case NodeTypeParamDecl: | |
| 534 | case NodeTypeType: | |
| 535 | case NodeTypeBlock: | |
| 536 | case NodeTypeExpression: | |
| 537 | case NodeTypeFnCall: | |
| 538 | case NodeTypeExternBlock: | |
| 539 | case NodeTypeDirective: | |
| 540 | assert(false); | |
| 534 | 541 | } |
| 535 | 542 | } |
| 536 | 543 |
src/parser.cpp+22-27| ... | ... | @@ -10,6 +10,7 @@ |
| 10 | 10 | #include <stdarg.h> |
| 11 | 11 | #include <stdio.h> |
| 12 | 12 | |
| 13 | static void ast_error(Token *token, const char *format, ...) __attribute__ ((noreturn)); | |
| 13 | 14 | __attribute__ ((format (printf, 2, 3))) |
| 14 | 15 | static void ast_error(Token *token, const char *format, ...) { |
| 15 | 16 | int line = token->start_line + 1; |
| ... | ... | @@ -40,8 +41,10 @@ const char *node_type_str(NodeType node_type) { |
| 40 | 41 | return "Type"; |
| 41 | 42 | case NodeTypeBlock: |
| 42 | 43 | return "Block"; |
| 43 | case NodeTypeStatement: | |
| 44 | return "Statement"; | |
| 44 | case NodeTypeStatementExpression: | |
| 45 | return "StatementExpression"; | |
| 46 | case NodeTypeStatementReturn: | |
| 47 | return "StatementReturn"; | |
| 45 | 48 | case NodeTypeExpression: |
| 46 | 49 | return "Expression"; |
| 47 | 50 | case NodeTypeFnCall: |
| ... | ... | @@ -125,17 +128,13 @@ void ast_print(AstNode *node, int indent) { |
| 125 | 128 | } |
| 126 | 129 | } |
| 127 | 130 | break; |
| 128 | case NodeTypeStatement: | |
| 129 | switch (node->data.statement.type) { | |
| 130 | case AstNodeStatementTypeReturn: | |
| 131 | fprintf(stderr, "ReturnStatement\n"); | |
| 132 | ast_print(node->data.statement.data.retrn.expression, indent + 2); | |
| 133 | break; | |
| 134 | case AstNodeStatementTypeExpression: | |
| 135 | fprintf(stderr, "ExpressionStatement\n"); | |
| 136 | ast_print(node->data.statement.data.expr.expression, indent + 2); | |
| 137 | break; | |
| 138 | } | |
| 131 | case NodeTypeStatementReturn: | |
| 132 | fprintf(stderr, "ReturnStatement\n"); | |
| 133 | ast_print(node->data.statement_return.expression, indent + 2); | |
| 134 | break; | |
| 135 | case NodeTypeStatementExpression: | |
| 136 | fprintf(stderr, "ExpressionStatement\n"); | |
| 137 | ast_print(node->data.statement_expression.expression, indent + 2); | |
| 139 | 138 | break; |
| 140 | 139 | case NodeTypeExternBlock: |
| 141 | 140 | { |
| ... | ... | @@ -258,7 +257,8 @@ static void parse_string_literal(ParseContext *pc, Token *token, Buf *buf) { |
| 258 | 257 | assert(!escape); |
| 259 | 258 | } |
| 260 | 259 | |
| 261 | static void ast_invalid_token_error(ParseContext *pc, Token *token) { | |
| 260 | void ast_invalid_token_error(ParseContext *pc, Token *token) __attribute__ ((noreturn)); | |
| 261 | void ast_invalid_token_error(ParseContext *pc, Token *token) { | |
| 262 | 262 | Buf token_value = BUF_INIT; |
| 263 | 263 | ast_buf_from_token(pc, token, &token_value); |
| 264 | 264 | ast_error(token, "invalid token: '%s'", buf_ptr(&token_value)); |
| ... | ... | @@ -448,40 +448,35 @@ Statement : ExpressionStatement | ReturnStatement ; |
| 448 | 448 | ExpressionStatement : Expression token(Semicolon) ; |
| 449 | 449 | |
| 450 | 450 | ReturnStatement : token(Return) Expression token(Semicolon) ; |
| 451 | ||
| 452 | Expression : token(Number) | token(String) | token(Unreachable) | FnCall | |
| 453 | ||
| 454 | FnCall : token(Symbol) token(LParen) list(Expression, token(Comma)) token(RParen) ; | |
| 455 | 451 | */ |
| 456 | 452 | static AstNode *ast_parse_statement(ParseContext *pc, int token_index, int *new_token_index) { |
| 457 | 453 | Token *token = &pc->tokens->at(token_index); |
| 458 | AstNode *node = ast_create_node(NodeTypeStatement, token); | |
| 459 | ||
| 460 | 454 | if (token->id == TokenIdKeywordReturn) { |
| 455 | AstNode *node = ast_create_node(NodeTypeStatementReturn, token); | |
| 461 | 456 | token_index += 1; |
| 462 | node->data.statement.type = AstNodeStatementTypeReturn; | |
| 463 | node->data.statement.data.retrn.expression = ast_parse_expression(pc, token_index, &token_index); | |
| 457 | node->data.statement_return.expression = ast_parse_expression(pc, token_index, &token_index); | |
| 464 | 458 | |
| 465 | 459 | Token *semicolon = &pc->tokens->at(token_index); |
| 466 | 460 | token_index += 1; |
| 467 | 461 | ast_expect_token(pc, semicolon, TokenIdSemicolon); |
| 462 | *new_token_index = token_index; | |
| 463 | return node; | |
| 468 | 464 | } else if (token->id == TokenIdSymbol || |
| 469 | 465 | token->id == TokenIdStringLiteral || |
| 470 | 466 | token->id == TokenIdKeywordUnreachable || |
| 471 | 467 | token->id == TokenIdNumberLiteral) |
| 472 | 468 | { |
| 473 | node->data.statement.type = AstNodeStatementTypeExpression; | |
| 474 | node->data.statement.data.expr.expression = ast_parse_expression(pc, token_index, &token_index); | |
| 469 | AstNode *node = ast_create_node(NodeTypeStatementExpression, token); | |
| 470 | node->data.statement_expression.expression = ast_parse_expression(pc, token_index, &token_index); | |
| 475 | 471 | |
| 476 | 472 | Token *semicolon = &pc->tokens->at(token_index); |
| 477 | 473 | token_index += 1; |
| 478 | 474 | ast_expect_token(pc, semicolon, TokenIdSemicolon); |
| 475 | *new_token_index = token_index; | |
| 476 | return node; | |
| 479 | 477 | } else { |
| 480 | 478 | ast_invalid_token_error(pc, token); |
| 481 | 479 | } |
| 482 | ||
| 483 | *new_token_index = token_index; | |
| 484 | return node; | |
| 485 | 480 | } |
| 486 | 481 | |
| 487 | 482 | /* |
src/parser.hpp+4-16| ... | ... | @@ -23,11 +23,12 @@ enum NodeType { |
| 23 | 23 | NodeTypeParamDecl, |
| 24 | 24 | NodeTypeType, |
| 25 | 25 | NodeTypeBlock, |
| 26 | NodeTypeStatement, | |
| 27 | 26 | NodeTypeExpression, |
| 28 | 27 | NodeTypeFnCall, |
| 29 | 28 | NodeTypeExternBlock, |
| 30 | 29 | NodeTypeDirective, |
| 30 | NodeTypeStatementExpression, | |
| 31 | NodeTypeStatementReturn, | |
| 31 | 32 | }; |
| 32 | 33 | |
| 33 | 34 | struct AstNodeRoot { |
| ... | ... | @@ -70,11 +71,6 @@ struct AstNodeBlock { |
| 70 | 71 | ZigList<AstNode *> statements; |
| 71 | 72 | }; |
| 72 | 73 | |
| 73 | enum AstNodeStatementType { | |
| 74 | AstNodeStatementTypeExpression, | |
| 75 | AstNodeStatementTypeReturn, | |
| 76 | }; | |
| 77 | ||
| 78 | 74 | struct AstNodeStatementExpression { |
| 79 | 75 | AstNode *expression; |
| 80 | 76 | }; |
| ... | ... | @@ -83,14 +79,6 @@ struct AstNodeStatementReturn { |
| 83 | 79 | AstNode *expression; |
| 84 | 80 | }; |
| 85 | 81 | |
| 86 | struct AstNodeStatement { | |
| 87 | AstNodeStatementType type; | |
| 88 | union { | |
| 89 | AstNodeStatementExpression expr; | |
| 90 | AstNodeStatementReturn retrn; | |
| 91 | } data; | |
| 92 | }; | |
| 93 | ||
| 94 | 82 | enum AstNodeExpressionType { |
| 95 | 83 | AstNodeExpressionTypeNumber, |
| 96 | 84 | AstNodeExpressionTypeString, |
| ... | ... | @@ -136,7 +124,8 @@ struct AstNode { |
| 136 | 124 | AstNodeType type; |
| 137 | 125 | AstNodeParamDecl param_decl; |
| 138 | 126 | AstNodeBlock block; |
| 139 | AstNodeStatement statement; | |
| 127 | AstNodeStatementExpression statement_expression; | |
| 128 | AstNodeStatementReturn statement_return; | |
| 140 | 129 | AstNodeExpression expression; |
| 141 | 130 | AstNodeFnCall fn_call; |
| 142 | 131 | AstNodeExternBlock extern_block; |
| ... | ... | @@ -146,7 +135,6 @@ struct AstNode { |
| 146 | 135 | |
| 147 | 136 | __attribute__ ((format (printf, 2, 3))) |
| 148 | 137 | void ast_token_error(Token *token, const char *format, ...); |
| 149 | void ast_invalid_token_error(Buf *buf, Token *token); | |
| 150 | 138 | |
| 151 | 139 | |
| 152 | 140 | // This function is provided by generated code, generated by parsergen.cpp |