From b735764898412c5b9388fdf729c8ad8db43ddde5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 9 Jun 2019 19:24:24 -0400 Subject: different array literal syntax when inferring the size old syntax: []i32{1, 2, 3} new syntax: [_]i32{1, 2, 3} closes #1797 --- src/parser.cpp | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index 3d7bbf7801..89836f9bc8 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -288,6 +288,9 @@ static AstNode *ast_parse_prefix_op_expr( case NodeTypeArrayType: right = &prefix->data.array_type.child_type; break; + case NodeTypeInferredArrayType: + right = &prefix->data.inferred_array_type.child_type; + break; case NodeTypePointerType: { // We might get two pointers from *_ptr_type_start AstNode *child = prefix->data.pointer_type.op_expr; @@ -1852,11 +1855,15 @@ static AstNode *ast_parse_asm_output(ParseContext *pc) { // AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) { - if (eat_token_if(pc, TokenIdLBracket) == nullptr) - return nullptr; - - Token *sym_name = expect_token(pc, TokenIdSymbol); - expect_token(pc, TokenIdRBracket); + Token *sym_name = eat_token_if(pc, TokenIdBracketUnderscoreBracket); + if (sym_name == nullptr) { + if (eat_token_if(pc, TokenIdLBracket) == nullptr) { + return nullptr; + } else { + sym_name = expect_token(pc, TokenIdSymbol); + expect_token(pc, TokenIdRBracket); + } + } Token *str = expect_token(pc, TokenIdStringLiteral); expect_token(pc, TokenIdLParen); @@ -1871,7 +1878,7 @@ static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) { expect_token(pc, TokenIdRParen); AsmOutput *res = allocate(1); - res->asm_symbolic_name = token_buf(sym_name); + res->asm_symbolic_name = (sym_name->id == TokenIdBracketUnderscoreBracket) ? buf_create_from_str("_") : token_buf(sym_name); res->constraint = token_buf(str); res->variable_name = token_buf(var_name); res->return_type = return_type; @@ -1894,18 +1901,23 @@ static AstNode *ast_parse_asm_input(ParseContext *pc) { // AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN static AsmInput *ast_parse_asm_input_item(ParseContext *pc) { - if (eat_token_if(pc, TokenIdLBracket) == nullptr) - return nullptr; + Token *sym_name = eat_token_if(pc, TokenIdBracketUnderscoreBracket); + if (sym_name == nullptr) { + if (eat_token_if(pc, TokenIdLBracket) == nullptr) { + return nullptr; + } else { + sym_name = expect_token(pc, TokenIdSymbol); + expect_token(pc, TokenIdRBracket); + } + } - Token *sym_name = expect_token(pc, TokenIdSymbol); - expect_token(pc, TokenIdRBracket); Token *constraint = expect_token(pc, TokenIdStringLiteral); expect_token(pc, TokenIdLParen); AstNode *expr = ast_expect(pc, ast_parse_expr); expect_token(pc, TokenIdRParen); AsmInput *res = allocate(1); - res->asm_symbolic_name = token_buf(sym_name); + res->asm_symbolic_name = (sym_name->id == TokenIdBracketUnderscoreBracket) ? buf_create_from_str("_") : token_buf(sym_name); res->constraint = token_buf(constraint); res->expr = expr; return res; @@ -2597,6 +2609,12 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) { return ptr; } + Token *arr_init = eat_token_if(pc, TokenIdBracketUnderscoreBracket); + if (arr_init != nullptr) { + return ast_create_node(pc, NodeTypeInferredArrayType, arr_init); + } + + return nullptr; } @@ -3003,6 +3021,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont visit_field(&node->data.array_type.child_type, visit, context); visit_field(&node->data.array_type.align_expr, visit, context); break; + case NodeTypeInferredArrayType: + visit_field(&node->data.array_type.child_type, visit, context); + break; case NodeTypePromiseType: visit_field(&node->data.promise_type.payload_type, visit, context); break; -- cgit v1.2.3 From 6c160b8856921e5e1d0a437794b3b7ee7e1a4d0b Mon Sep 17 00:00:00 2001 From: SamTebbs33 Date: Sat, 8 Jun 2019 15:58:11 +0100 Subject: Add check for null body in if, for and while --- src/parser.cpp | 15 +++++++++++++++ test/compile_errors.zig | 27 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index 89836f9bc8..af98a4be93 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -890,6 +890,11 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) { body = ast_parse_assign_expr(pc); } + if (body == nullptr) { + Token *tok = eat_token(pc); + ast_error(pc, tok, "expected if body, found '%s'", token_name(tok->id)); + } + Token *err_payload = nullptr; AstNode *else_body = nullptr; if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) { @@ -994,6 +999,11 @@ static AstNode *ast_parse_for_statement(ParseContext *pc) { body = ast_parse_assign_expr(pc); } + if (body == nullptr) { + Token *tok = eat_token(pc); + ast_error(pc, tok, "expected loop body, found '%s'", token_name(tok->id)); + } + AstNode *else_body = nullptr; if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) { else_body = ast_expect(pc, ast_parse_statement); @@ -1023,6 +1033,11 @@ static AstNode *ast_parse_while_statement(ParseContext *pc) { body = ast_parse_assign_expr(pc); } + if (body == nullptr) { + Token *tok = eat_token(pc); + ast_error(pc, tok, "expected loop body, found '%s'", token_name(tok->id)); + } + Token *err_payload = nullptr; AstNode *else_body = nullptr; if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) { diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 15ac7d6f1b..7896a0b732 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -230,6 +230,33 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:10:25: error: expression value is ignored", ); + cases.add( + "empty while loop body", + \\export fn a() void { + \\ while(true); + \\} + , + "tmp.zig:2:16: error: expected loop body, found ';'", + ); + + cases.add( + "empty for loop body", + \\export fn a() void { + \\ for(undefined) |x|; + \\} + , + "tmp.zig:2:23: error: expected loop body, found ';'", + ); + + cases.add( + "empty if body", + \\export fn a() void { + \\ if(true); + \\} + , + "tmp.zig:2:13: error: expected if body, found ';'", + ); + cases.add( "import outside package path", \\comptime{ -- cgit v1.2.3 From b7811d32690a9f3b4912635e16e6aa5ace25362c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 10 Jun 2019 00:45:24 -0400 Subject: whitespace cleanup --- src/parser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index af98a4be93..33f8836ef3 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -891,7 +891,7 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) { } if (body == nullptr) { - Token *tok = eat_token(pc); + Token *tok = eat_token(pc); ast_error(pc, tok, "expected if body, found '%s'", token_name(tok->id)); } @@ -1000,7 +1000,7 @@ static AstNode *ast_parse_for_statement(ParseContext *pc) { } if (body == nullptr) { - Token *tok = eat_token(pc); + Token *tok = eat_token(pc); ast_error(pc, tok, "expected loop body, found '%s'", token_name(tok->id)); } @@ -1034,7 +1034,7 @@ static AstNode *ast_parse_while_statement(ParseContext *pc) { } if (body == nullptr) { - Token *tok = eat_token(pc); + Token *tok = eat_token(pc); ast_error(pc, tok, "expected loop body, found '%s'", token_name(tok->id)); } -- cgit v1.2.3