diff --git a/README.md b/README.md index 8ff5f015bc..273bc16f7c 100644 --- a/README.md +++ b/README.md @@ -80,11 +80,11 @@ ParamDecl : token(Symbol) token(Colon) Type Type : token(Symbol) | PointerType | token(Unreachable) -PointerType : token(Star) token(Const) Type | token(Star) token(Mut) Type +PointerType : token(Star) token(Const) Type | token(Star) token(Mut) Type Block : token(LBrace) many(Statement) token(RBrace) -Statement : ExpressionStatement | ReturnStatement +Statement : ExpressionStatement | ReturnStatement ExpressionStatement : Expression token(Semicolon) diff --git a/src/codegen.cpp b/src/codegen.cpp index e9269ced64..79213c27b4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -292,15 +292,11 @@ static void analyze_node(CodeGen *g, AstNode *node) { analyze_node(g, child); } break; - case NodeTypeStatement: - switch (node->data.statement.type) { - case AstNodeStatementTypeExpression: - analyze_node(g, node->data.statement.data.expr.expression); - break; - case AstNodeStatementTypeReturn: - analyze_node(g, node->data.statement.data.retrn.expression); - break; - } + case NodeTypeStatementExpression: + analyze_node(g, node->data.statement_expression.expression); + break; + case NodeTypeStatementReturn: + analyze_node(g, node->data.statement_return.expression); break; case NodeTypeExpression: switch (node->data.expression.type) { @@ -514,23 +510,34 @@ static void gen_block(CodeGen *g, AstNode *block_node) { for (int i = 0; i < block_node->data.block.statements.length; i += 1) { AstNode *statement_node = block_node->data.block.statements.at(i); - assert(statement_node->type == NodeTypeStatement); - switch (statement_node->data.statement.type) { - case AstNodeStatementTypeReturn: + switch (statement_node->type) { + case NodeTypeStatementReturn: { - AstNode *expr_node = statement_node->data.statement.data.retrn.expression; + AstNode *expr_node = statement_node->data.statement_return.expression; LLVMValueRef value = gen_expr(g, expr_node); add_debug_source_node(g, statement_node); LLVMBuildRet(g->builder, value); break; } - case AstNodeStatementTypeExpression: + case NodeTypeStatementExpression: { - AstNode *expr_node = statement_node->data.statement.data.expr.expression; + AstNode *expr_node = statement_node->data.statement_expression.expression; gen_expr(g, expr_node); break; } + case NodeTypeRoot: + case NodeTypeFnProto: + case NodeTypeFnDef: + case NodeTypeFnDecl: + case NodeTypeParamDecl: + case NodeTypeType: + case NodeTypeBlock: + case NodeTypeExpression: + case NodeTypeFnCall: + case NodeTypeExternBlock: + case NodeTypeDirective: + assert(false); } } diff --git a/src/parser.cpp b/src/parser.cpp index c2ea75f381..e24041538e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -10,6 +10,7 @@ #include #include +static void ast_error(Token *token, const char *format, ...) __attribute__ ((noreturn)); __attribute__ ((format (printf, 2, 3))) static void ast_error(Token *token, const char *format, ...) { int line = token->start_line + 1; @@ -40,8 +41,10 @@ const char *node_type_str(NodeType node_type) { return "Type"; case NodeTypeBlock: return "Block"; - case NodeTypeStatement: - return "Statement"; + case NodeTypeStatementExpression: + return "StatementExpression"; + case NodeTypeStatementReturn: + return "StatementReturn"; case NodeTypeExpression: return "Expression"; case NodeTypeFnCall: @@ -125,17 +128,13 @@ void ast_print(AstNode *node, int indent) { } } break; - case NodeTypeStatement: - switch (node->data.statement.type) { - case AstNodeStatementTypeReturn: - fprintf(stderr, "ReturnStatement\n"); - ast_print(node->data.statement.data.retrn.expression, indent + 2); - break; - case AstNodeStatementTypeExpression: - fprintf(stderr, "ExpressionStatement\n"); - ast_print(node->data.statement.data.expr.expression, indent + 2); - break; - } + case NodeTypeStatementReturn: + fprintf(stderr, "ReturnStatement\n"); + ast_print(node->data.statement_return.expression, indent + 2); + break; + case NodeTypeStatementExpression: + fprintf(stderr, "ExpressionStatement\n"); + ast_print(node->data.statement_expression.expression, indent + 2); break; case NodeTypeExternBlock: { @@ -258,7 +257,8 @@ static void parse_string_literal(ParseContext *pc, Token *token, Buf *buf) { assert(!escape); } -static void ast_invalid_token_error(ParseContext *pc, Token *token) { +void ast_invalid_token_error(ParseContext *pc, Token *token) __attribute__ ((noreturn)); +void ast_invalid_token_error(ParseContext *pc, Token *token) { Buf token_value = BUF_INIT; ast_buf_from_token(pc, token, &token_value); ast_error(token, "invalid token: '%s'", buf_ptr(&token_value)); @@ -448,40 +448,35 @@ Statement : ExpressionStatement | ReturnStatement ; ExpressionStatement : Expression token(Semicolon) ; ReturnStatement : token(Return) Expression token(Semicolon) ; - -Expression : token(Number) | token(String) | token(Unreachable) | FnCall - -FnCall : token(Symbol) token(LParen) list(Expression, token(Comma)) token(RParen) ; */ static AstNode *ast_parse_statement(ParseContext *pc, int token_index, int *new_token_index) { Token *token = &pc->tokens->at(token_index); - AstNode *node = ast_create_node(NodeTypeStatement, token); - if (token->id == TokenIdKeywordReturn) { + AstNode *node = ast_create_node(NodeTypeStatementReturn, token); token_index += 1; - node->data.statement.type = AstNodeStatementTypeReturn; - node->data.statement.data.retrn.expression = ast_parse_expression(pc, token_index, &token_index); + node->data.statement_return.expression = ast_parse_expression(pc, token_index, &token_index); Token *semicolon = &pc->tokens->at(token_index); token_index += 1; ast_expect_token(pc, semicolon, TokenIdSemicolon); + *new_token_index = token_index; + return node; } else if (token->id == TokenIdSymbol || token->id == TokenIdStringLiteral || token->id == TokenIdKeywordUnreachable || token->id == TokenIdNumberLiteral) { - node->data.statement.type = AstNodeStatementTypeExpression; - node->data.statement.data.expr.expression = ast_parse_expression(pc, token_index, &token_index); + AstNode *node = ast_create_node(NodeTypeStatementExpression, token); + node->data.statement_expression.expression = ast_parse_expression(pc, token_index, &token_index); Token *semicolon = &pc->tokens->at(token_index); token_index += 1; ast_expect_token(pc, semicolon, TokenIdSemicolon); + *new_token_index = token_index; + return node; } else { ast_invalid_token_error(pc, token); } - - *new_token_index = token_index; - return node; } /* diff --git a/src/parser.hpp b/src/parser.hpp index 74627306a8..daa9251209 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -23,11 +23,12 @@ enum NodeType { NodeTypeParamDecl, NodeTypeType, NodeTypeBlock, - NodeTypeStatement, NodeTypeExpression, NodeTypeFnCall, NodeTypeExternBlock, NodeTypeDirective, + NodeTypeStatementExpression, + NodeTypeStatementReturn, }; struct AstNodeRoot { @@ -70,11 +71,6 @@ struct AstNodeBlock { ZigList statements; }; -enum AstNodeStatementType { - AstNodeStatementTypeExpression, - AstNodeStatementTypeReturn, -}; - struct AstNodeStatementExpression { AstNode *expression; }; @@ -83,14 +79,6 @@ struct AstNodeStatementReturn { AstNode *expression; }; -struct AstNodeStatement { - AstNodeStatementType type; - union { - AstNodeStatementExpression expr; - AstNodeStatementReturn retrn; - } data; -}; - enum AstNodeExpressionType { AstNodeExpressionTypeNumber, AstNodeExpressionTypeString, @@ -136,7 +124,8 @@ struct AstNode { AstNodeType type; AstNodeParamDecl param_decl; AstNodeBlock block; - AstNodeStatement statement; + AstNodeStatementExpression statement_expression; + AstNodeStatementReturn statement_return; AstNodeExpression expression; AstNodeFnCall fn_call; AstNodeExternBlock extern_block; @@ -146,7 +135,6 @@ struct AstNode { __attribute__ ((format (printf, 2, 3))) void ast_token_error(Token *token, const char *format, ...); -void ast_invalid_token_error(Buf *buf, Token *token); // This function is provided by generated code, generated by parsergen.cpp