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