| author | |
| committer | |
| log | b3ac5c16ecc8dd9da661dcb9d15a6c36a8e4167b |
| tree | 4539ac7b88906ef03540639f19e2f37ce0bf319f |
| parent | 7ba99e9715c1fa3cd00fe6d9ac74b9a15eeac706 |
closes #397 files changed, 141 insertions(+), 73 deletions(-)
doc/langref.md+7-7| ... | ... | @@ -60,10 +60,12 @@ ParamDeclList : token(LParen) list(ParamDecl, token(Comma)) token(RParen) |
| 60 | 60 | |
| 61 | 61 | ParamDecl : token(Symbol) token(Colon) Type | token(Ellipsis) |
| 62 | 62 | |
| 63 | Type : token(Symbol) | token(Unreachable) | token(Void) | PointerType | ArrayType | |
| 63 | Type : token(Symbol) | token(Unreachable) | token(Void) | PointerType | ArrayType | MaybeType | |
| 64 | 64 | |
| 65 | 65 | PointerType : token(Ampersand) option(token(Const)) Type |
| 66 | 66 | |
| 67 | MaybeType : token(Question) Type | |
| 68 | ||
| 67 | 69 | ArrayType : token(LBracket) Type token(Semicolon) Expression token(RBracket) |
| 68 | 70 | |
| 69 | 71 | Block : token(LBrace) list(option(Statement), token(Semicolon)) token(RBrace) |
| ... | ... | @@ -96,7 +98,7 @@ AssignmentOperator : token(Eq) | token(TimesEq) | token(DivEq) | token(ModEq) | |
| 96 | 98 | |
| 97 | 99 | BlockExpression : IfExpression | Block | WhileExpression |
| 98 | 100 | |
| 99 | WhileExpression : token(While) Expression Block | |
| 101 | WhileExpression : token(While) token(LParen) Expression token(RParen) Expression | |
| 100 | 102 | |
| 101 | 103 | BoolOrExpression : BoolAndExpression token(BoolOr) BoolOrExpression | BoolAndExpression |
| 102 | 104 | |
| ... | ... | @@ -104,13 +106,11 @@ ReturnExpression : token(Return) option(Expression) |
| 104 | 106 | |
| 105 | 107 | IfExpression : IfVarExpression | IfBoolExpression |
| 106 | 108 | |
| 107 | IfBoolExpression : token(If) option((token) Expression Block option(Else | ElseIf) | |
| 108 | ||
| 109 | IfVarExpression : token(If) (token(Const) | token(Var)) token(Symbol) option(token(Colon) Type) Token(MaybeAssign) Expression Block Option(Else | ElseIf) | |
| 109 | IfBoolExpression : token(If) token(LParen) Expression token(RParen) Expression option(Else) | |
| 110 | 110 | |
| 111 | ElseIf : token(Else) IfExpression | |
| 111 | IfVarExpression : token(If) token(LParen) (token(Const) | token(Var)) token(Symbol) option(token(Colon) Type) Token(MaybeAssign) Expression token(RParen) Expression Option(Else) | |
| 112 | 112 | |
| 113 | Else : token(Else) Block | |
| 113 | Else : token(Else) Expression | |
| 114 | 114 | |
| 115 | 115 | BoolAndExpression : ComparisonExpression token(BoolAnd) BoolAndExpression | ComparisonExpression |
| 116 | 116 |
example/maybe_type/main.zig created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | export executable "maybe_type"; | |
| 2 | ||
| 3 | use "std.zig"; | |
| 4 | ||
| 5 | fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | |
| 6 | const x : ?bool = true; | |
| 7 | ||
| 8 | if (const y ?= x) { | |
| 9 | if (y) { | |
| 10 | print_str("x is true\n"); | |
| 11 | } else { | |
| 12 | print_str("x is false\n"); | |
| 13 | } | |
| 14 | } else { | |
| 15 | print_str("x is none\n"); | |
| 16 | } | |
| 17 | ||
| 18 | return 0; | |
| 19 | } |
src/analyze.cpp+34| ... | ... | @@ -132,6 +132,26 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool |
| 132 | 132 | } |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | static TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { | |
| 136 | if (child_type->maybe_parent) { | |
| 137 | return child_type->maybe_parent; | |
| 138 | } else { | |
| 139 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMaybe); | |
| 140 | // TODO entry->type_ref | |
| 141 | buf_resize(&entry->name, 0); | |
| 142 | buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name)); | |
| 143 | // TODO entry->size_in_bits | |
| 144 | // TODO entry->align_in_bits | |
| 145 | assert(child_type->di_type); | |
| 146 | // TODO entry->di_type | |
| 147 | entry->data.maybe.child_type = child_type; | |
| 148 | ||
| 149 | g->type_table.put(&entry->name, entry); | |
| 150 | child_type->maybe_parent = entry; | |
| 151 | return entry; | |
| 152 | } | |
| 153 | } | |
| 154 | ||
| 135 | 155 | static TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size) { |
| 136 | 156 | auto existing_entry = child_type->arrays_by_size.maybe_get(array_size); |
| 137 | 157 | if (existing_entry) { |
| ... | ... | @@ -208,6 +228,20 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) { |
| 208 | 228 | } |
| 209 | 229 | return type_node->entry; |
| 210 | 230 | } |
| 231 | case AstNodeTypeTypeMaybe: | |
| 232 | { | |
| 233 | resolve_type(g, node->data.type.child_type); | |
| 234 | TypeTableEntry *child_type = node->data.type.child_type->codegen_node->data.type_node.entry; | |
| 235 | assert(child_type); | |
| 236 | if (child_type->id == TypeTableEntryIdUnreachable) { | |
| 237 | add_node_error(g, node, | |
| 238 | buf_create_from_str("maybe unreachable type not allowed")); | |
| 239 | } else if (child_type->id == TypeTableEntryIdInvalid) { | |
| 240 | return child_type; | |
| 241 | } | |
| 242 | type_node->entry = get_maybe_type(g, child_type); | |
| 243 | return type_node->entry; | |
| 244 | } | |
| 211 | 245 | } |
| 212 | 246 | zig_unreachable(); |
| 213 | 247 | } |
src/analyze.hpp+1| ... | ... | @@ -96,6 +96,7 @@ struct TypeTableEntry { |
| 96 | 96 | TypeTableEntry *pointer_const_parent; |
| 97 | 97 | TypeTableEntry *pointer_mut_parent; |
| 98 | 98 | HashMap<uint64_t, TypeTableEntry *, uint64_hash, uint64_eq> arrays_by_size; |
| 99 | TypeTableEntry *maybe_parent; | |
| 99 | 100 | |
| 100 | 101 | }; |
| 101 | 102 |
src/parser.cpp+30-17| ... | ... | @@ -225,6 +225,12 @@ void ast_print(AstNode *node, int indent) { |
| 225 | 225 | ast_print(node->data.type.array_size, indent + 2); |
| 226 | 226 | break; |
| 227 | 227 | } |
| 228 | case AstNodeTypeTypeMaybe: | |
| 229 | { | |
| 230 | fprintf(stderr, "MaybeType\n"); | |
| 231 | ast_print(node->data.type.child_type, indent + 2); | |
| 232 | break; | |
| 233 | } | |
| 228 | 234 | } |
| 229 | 235 | break; |
| 230 | 236 | case NodeTypeReturnExpr: |
| ... | ... | @@ -920,7 +926,7 @@ static void ast_parse_type_assume_amp(ParseContext *pc, int *token_index, AstNod |
| 920 | 926 | } |
| 921 | 927 | |
| 922 | 928 | /* |
| 923 | Type : token(Symbol) | token(Unreachable) | token(Void) | PointerType | ArrayType | |
| 929 | Type : token(Symbol) | token(Unreachable) | token(Void) | PointerType | ArrayType | MaybeType | |
| 924 | 930 | PointerType : token(Ampersand) option(token(Const)) Type |
| 925 | 931 | ArrayType : token(LBracket) Type token(Semicolon) token(Number) token(RBracket) |
| 926 | 932 | */ |
| ... | ... | @@ -941,6 +947,9 @@ static AstNode *ast_parse_type(ParseContext *pc, int *token_index) { |
| 941 | 947 | ast_buf_from_token(pc, token, &node->data.type.primitive_name); |
| 942 | 948 | } else if (token->id == TokenIdAmpersand) { |
| 943 | 949 | ast_parse_type_assume_amp(pc, token_index, node); |
| 950 | } else if (token->id == TokenIdMaybe) { | |
| 951 | node->data.type.type = AstNodeTypeTypeMaybe; | |
| 952 | node->data.type.child_type = ast_parse_type(pc, token_index); | |
| 944 | 953 | } else if (token->id == TokenIdBoolAnd) { |
| 945 | 954 | // Pretend that we got 2 ampersand tokens |
| 946 | 955 | node->data.type.type = AstNodeTypeTypePointer; |
| ... | ... | @@ -1636,10 +1645,9 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc, int *token_index, bool |
| 1636 | 1645 | } |
| 1637 | 1646 | |
| 1638 | 1647 | /* |
| 1639 | ElseIf : token(Else) IfExpression | |
| 1640 | Else : token(Else) Block | |
| 1648 | Else : token(Else) Expression | |
| 1641 | 1649 | */ |
| 1642 | static AstNode *ast_parse_else_or_else_if(ParseContext *pc, int *token_index, bool mandatory) { | |
| 1650 | static AstNode *ast_parse_else(ParseContext *pc, int *token_index, bool mandatory) { | |
| 1643 | 1651 | Token *else_token = &pc->tokens->at(*token_index); |
| 1644 | 1652 | |
| 1645 | 1653 | if (else_token->id != TokenIdKeywordElse) { |
| ... | ... | @@ -1651,17 +1659,13 @@ static AstNode *ast_parse_else_or_else_if(ParseContext *pc, int *token_index, bo |
| 1651 | 1659 | } |
| 1652 | 1660 | *token_index += 1; |
| 1653 | 1661 | |
| 1654 | AstNode *if_expr = ast_parse_if_expr(pc, token_index, false); | |
| 1655 | if (if_expr) | |
| 1656 | return if_expr; | |
| 1657 | ||
| 1658 | return ast_parse_block(pc, token_index, true); | |
| 1662 | return ast_parse_expression(pc, token_index, true); | |
| 1659 | 1663 | } |
| 1660 | 1664 | |
| 1661 | 1665 | /* |
| 1662 | 1666 | IfExpression : IfVarExpression | IfBoolExpression |
| 1663 | IfBoolExpression : token(If) option((token) Expression Block option(Else | ElseIf) | |
| 1664 | IfVarExpression : token(If) (token(Const) | token(Var)) token(Symbol) option(token(Colon) Type) Token(Eq) Expression Block Option(Else | ElseIf) | |
| 1667 | IfBoolExpression : token(If) token(LParen) Expression token(RParen) Expression option(Else) | |
| 1668 | IfVarExpression : token(If) token(LParen) (token(Const) | token(Var)) token(Symbol) option(token(Colon) Type) Token(MaybeAssign) Expression token(RParen) Expression Option(Else) | |
| 1665 | 1669 | */ |
| 1666 | 1670 | static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool mandatory) { |
| 1667 | 1671 | Token *if_tok = &pc->tokens->at(*token_index); |
| ... | ... | @@ -1674,6 +1678,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda |
| 1674 | 1678 | } |
| 1675 | 1679 | *token_index += 1; |
| 1676 | 1680 | |
| 1681 | ast_eat_token(pc, token_index, TokenIdLParen); | |
| 1682 | ||
| 1677 | 1683 | Token *token = &pc->tokens->at(*token_index); |
| 1678 | 1684 | if (token->id == TokenIdKeywordConst || token->id == TokenIdKeywordVar) { |
| 1679 | 1685 | AstNode *node = ast_create_node(pc, NodeTypeIfVarExpr, if_tok); |
| ... | ... | @@ -1695,14 +1701,16 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda |
| 1695 | 1701 | } else { |
| 1696 | 1702 | ast_invalid_token_error(pc, eq_or_colon); |
| 1697 | 1703 | } |
| 1698 | node->data.if_var_expr.then_block = ast_parse_block(pc, token_index, true); | |
| 1699 | node->data.if_var_expr.else_node = ast_parse_else_or_else_if(pc, token_index, false); | |
| 1704 | ast_eat_token(pc, token_index, TokenIdRParen); | |
| 1705 | node->data.if_var_expr.then_block = ast_parse_expression(pc, token_index, true); | |
| 1706 | node->data.if_var_expr.else_node = ast_parse_else(pc, token_index, false); | |
| 1700 | 1707 | return node; |
| 1701 | 1708 | } else { |
| 1702 | 1709 | AstNode *node = ast_create_node(pc, NodeTypeIfBoolExpr, if_tok); |
| 1703 | 1710 | node->data.if_bool_expr.condition = ast_parse_expression(pc, token_index, true); |
| 1704 | node->data.if_bool_expr.then_block = ast_parse_block(pc, token_index, true); | |
| 1705 | node->data.if_bool_expr.else_node = ast_parse_else_or_else_if(pc, token_index, false); | |
| 1711 | ast_eat_token(pc, token_index, TokenIdRParen); | |
| 1712 | node->data.if_bool_expr.then_block = ast_parse_expression(pc, token_index, true); | |
| 1713 | node->data.if_bool_expr.else_node = ast_parse_else(pc, token_index, false); | |
| 1706 | 1714 | return node; |
| 1707 | 1715 | } |
| 1708 | 1716 | } |
| ... | ... | @@ -1795,7 +1803,7 @@ static AstNode *ast_parse_bool_or_expr(ParseContext *pc, int *token_index, bool |
| 1795 | 1803 | } |
| 1796 | 1804 | |
| 1797 | 1805 | /* |
| 1798 | WhileExpression : token(While) Expression Block | |
| 1806 | WhileExpression : token(While) token(LParen) Expression token(RParen) Expression | |
| 1799 | 1807 | */ |
| 1800 | 1808 | static AstNode *ast_parse_while_expr(ParseContext *pc, int *token_index, bool mandatory) { |
| 1801 | 1809 | Token *token = &pc->tokens->at(*token_index); |
| ... | ... | @@ -1811,8 +1819,13 @@ static AstNode *ast_parse_while_expr(ParseContext *pc, int *token_index, bool ma |
| 1811 | 1819 | |
| 1812 | 1820 | AstNode *node = ast_create_node(pc, NodeTypeWhileExpr, token); |
| 1813 | 1821 | |
| 1822 | ast_eat_token(pc, token_index, TokenIdLParen); | |
| 1814 | 1823 | node->data.while_expr.condition = ast_parse_expression(pc, token_index, true); |
| 1815 | node->data.while_expr.body = ast_parse_block(pc, token_index, true); | |
| 1824 | ast_eat_token(pc, token_index, TokenIdRParen); | |
| 1825 | ||
| 1826 | node->data.while_expr.body = ast_parse_expression(pc, token_index, true); | |
| 1827 | ||
| 1828 | ||
| 1816 | 1829 | |
| 1817 | 1830 | return node; |
| 1818 | 1831 | } |
src/parser.hpp+1| ... | ... | @@ -95,6 +95,7 @@ enum AstNodeTypeType { |
| 95 | 95 | AstNodeTypeTypePrimitive, |
| 96 | 96 | AstNodeTypeTypePointer, |
| 97 | 97 | AstNodeTypeTypeArray, |
| 98 | AstNodeTypeTypeMaybe, | |
| 98 | 99 | }; |
| 99 | 100 | |
| 100 | 101 | struct AstNodeType { |
test/run_tests.cpp+49-49| ... | ... | @@ -184,17 +184,17 @@ static void add_compiling_test_cases(void) { |
| 184 | 184 | use "std.zig"; |
| 185 | 185 | |
| 186 | 186 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 187 | if 1 != 0 { | |
| 187 | if (1 != 0) { | |
| 188 | 188 | print_str("1 is true\n"); |
| 189 | 189 | } else { |
| 190 | 190 | print_str("1 is false\n"); |
| 191 | 191 | } |
| 192 | if 0 != 0 { | |
| 192 | if (0 != 0) { | |
| 193 | 193 | print_str("0 is true\n"); |
| 194 | } else if 1 - 1 != 0 { | |
| 194 | } else if (1 - 1 != 0) { | |
| 195 | 195 | print_str("1 - 1 is true\n"); |
| 196 | 196 | } |
| 197 | if !(0 != 0) { | |
| 197 | if (!(0 != 0)) { | |
| 198 | 198 | print_str("!0 is true\n"); |
| 199 | 199 | } |
| 200 | 200 | return 0; |
| ... | ... | @@ -209,7 +209,7 @@ static void add_compiling_test_cases(void) { |
| 209 | 209 | } |
| 210 | 210 | |
| 211 | 211 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 212 | if add(22, 11) == 33 { | |
| 212 | if (add(22, 11) == 33) { | |
| 213 | 213 | print_str("pass\n"); |
| 214 | 214 | } |
| 215 | 215 | return 0; |
| ... | ... | @@ -220,7 +220,7 @@ static void add_compiling_test_cases(void) { |
| 220 | 220 | use "std.zig"; |
| 221 | 221 | |
| 222 | 222 | fn loop(a : i32) { |
| 223 | if a == 0 { | |
| 223 | if (a == 0) { | |
| 224 | 224 | goto done; |
| 225 | 225 | } |
| 226 | 226 | print_str("loop\n"); |
| ... | ... | @@ -304,7 +304,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 304 | 304 | |
| 305 | 305 | var i = 0 as i32; |
| 306 | 306 | loop_start: |
| 307 | if i == 3 { | |
| 307 | if (i == 3) { | |
| 308 | 308 | goto done; |
| 309 | 309 | } |
| 310 | 310 | print_str("loop\n"); |
| ... | ... | @@ -323,7 +323,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 323 | 323 | |
| 324 | 324 | var i : i32 = 0; |
| 325 | 325 | loop_start: |
| 326 | if i == 5 { | |
| 326 | if (i == 5) { | |
| 327 | 327 | goto loop_end; |
| 328 | 328 | } |
| 329 | 329 | array[i] = i + 1; |
| ... | ... | @@ -335,7 +335,7 @@ loop_end: |
| 335 | 335 | i = 0; |
| 336 | 336 | var accumulator = 0 as i32; |
| 337 | 337 | loop_2_start: |
| 338 | if i == 5 { | |
| 338 | if (i == 5) { | |
| 339 | 339 | goto loop_2_end; |
| 340 | 340 | } |
| 341 | 341 | |
| ... | ... | @@ -345,7 +345,7 @@ loop_2_start: |
| 345 | 345 | goto loop_2_start; |
| 346 | 346 | loop_2_end: |
| 347 | 347 | |
| 348 | if accumulator == 15 { | |
| 348 | if (accumulator == 15) { | |
| 349 | 349 | print_str("OK\n"); |
| 350 | 350 | } |
| 351 | 351 | |
| ... | ... | @@ -368,18 +368,18 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 368 | 368 | use "std.zig"; |
| 369 | 369 | |
| 370 | 370 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 371 | if false || false || false { print_str("BAD 1\n"); } | |
| 372 | if true && true && false { print_str("BAD 2\n"); } | |
| 373 | if 1 | 2 | 4 != 7 { print_str("BAD 3\n"); } | |
| 374 | if 3 ^ 6 ^ 8 != 13 { print_str("BAD 4\n"); } | |
| 375 | if 7 & 14 & 28 != 4 { print_str("BAD 5\n"); } | |
| 376 | if 9 << 1 << 2 != 9 << 3 { print_str("BAD 6\n"); } | |
| 377 | if 90 >> 1 >> 2 != 90 >> 3 { print_str("BAD 7\n"); } | |
| 378 | if 100 - 1 + 1000 != 1099 { print_str("BAD 8\n"); } | |
| 379 | if 5 * 4 / 2 % 3 != 1 { print_str("BAD 9\n"); } | |
| 380 | if 5 as i32 as i32 != 5 { print_str("BAD 10\n"); } | |
| 381 | if !!false { print_str("BAD 11\n"); } | |
| 382 | if 7 != --7 { print_str("BAD 12\n"); } | |
| 371 | if (false || false || false) { print_str("BAD 1\n"); } | |
| 372 | if (true && true && false) { print_str("BAD 2\n"); } | |
| 373 | if (1 | 2 | 4 != 7) { print_str("BAD 3\n"); } | |
| 374 | if (3 ^ 6 ^ 8 != 13) { print_str("BAD 4\n"); } | |
| 375 | if (7 & 14 & 28 != 4) { print_str("BAD 5\n"); } | |
| 376 | if (9 << 1 << 2 != 9 << 3) { print_str("BAD 6\n"); } | |
| 377 | if (90 >> 1 >> 2 != 90 >> 3) { print_str("BAD 7\n"); } | |
| 378 | if (100 - 1 + 1000 != 1099) { print_str("BAD 8\n"); } | |
| 379 | if (5 * 4 / 2 % 3 != 1) { print_str("BAD 9\n"); } | |
| 380 | if (5 as i32 as i32 != 5) { print_str("BAD 10\n"); } | |
| 381 | if (!!false) { print_str("BAD 11\n"); } | |
| 382 | if (7 != --7) { print_str("BAD 12\n"); } | |
| 383 | 383 | |
| 384 | 384 | print_str("OK\n"); |
| 385 | 385 | return 0; |
| ... | ... | @@ -390,17 +390,17 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 390 | 390 | use "std.zig"; |
| 391 | 391 | |
| 392 | 392 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 393 | if true || { print_str("BAD 1\n"); false } { | |
| 393 | if (true || { print_str("BAD 1\n"); false }) { | |
| 394 | 394 | print_str("OK 1\n"); |
| 395 | 395 | } |
| 396 | if false || { print_str("OK 2\n"); false } { | |
| 396 | if (false || { print_str("OK 2\n"); false }) { | |
| 397 | 397 | print_str("BAD 2\n"); |
| 398 | 398 | } |
| 399 | 399 | |
| 400 | if true && { print_str("OK 3\n"); false } { | |
| 400 | if (true && { print_str("OK 3\n"); false }) { | |
| 401 | 401 | print_str("BAD 3\n"); |
| 402 | 402 | } |
| 403 | if false && { print_str("BAD 4\n"); false } { | |
| 403 | if (false && { print_str("BAD 4\n"); false }) { | |
| 404 | 404 | } else { |
| 405 | 405 | print_str("OK 4\n"); |
| 406 | 406 | } |
| ... | ... | @@ -414,18 +414,18 @@ use "std.zig"; |
| 414 | 414 | |
| 415 | 415 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 416 | 416 | var i : i32 = 0; |
| 417 | i += 5; if i != 5 { print_str("BAD +=\n"); } | |
| 418 | i -= 2; if i != 3 { print_str("BAD -=\n"); } | |
| 419 | i *= 20; if i != 60 { print_str("BAD *=\n"); } | |
| 420 | i /= 3; if i != 20 { print_str("BAD /=\n"); } | |
| 421 | i %= 11; if i != 9 { print_str("BAD %=\n"); } | |
| 422 | i <<= 1; if i != 18 { print_str("BAD <<=\n"); } | |
| 423 | i >>= 2; if i != 4 { print_str("BAD >>=\n"); } | |
| 417 | i += 5; if (i != 5) { print_str("BAD +=\n"); } | |
| 418 | i -= 2; if (i != 3) { print_str("BAD -=\n"); } | |
| 419 | i *= 20; if (i != 60) { print_str("BAD *=\n"); } | |
| 420 | i /= 3; if (i != 20) { print_str("BAD /=\n"); } | |
| 421 | i %= 11; if (i != 9) { print_str("BAD %=\n"); } | |
| 422 | i <<= 1; if (i != 18) { print_str("BAD <<=\n"); } | |
| 423 | i >>= 2; if (i != 4) { print_str("BAD >>=\n"); } | |
| 424 | 424 | i = 6; |
| 425 | i &= 5; if i != 4 { print_str("BAD &=\n"); } | |
| 426 | i ^= 6; if i != 2 { print_str("BAD ^=\n"); } | |
| 425 | i &= 5; if (i != 4) { print_str("BAD &=\n"); } | |
| 426 | i ^= 6; if (i != 2) { print_str("BAD ^=\n"); } | |
| 427 | 427 | i = 6; |
| 428 | i |= 3; if i != 7 { print_str("BAD |=\n"); } | |
| 428 | i |= 3; if (i != 7) { print_str("BAD |=\n"); } | |
| 429 | 429 | |
| 430 | 430 | print_str("OK\n"); |
| 431 | 431 | return 0; |
| ... | ... | @@ -570,7 +570,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 570 | 570 | foo.b = foo.a == 1; |
| 571 | 571 | test_foo(foo); |
| 572 | 572 | test_mutation(&foo); |
| 573 | if foo.c != 100 { | |
| 573 | if (foo.c != 100) { | |
| 574 | 574 | print_str("BAD\n"); |
| 575 | 575 | } |
| 576 | 576 | test_point_to_self(); |
| ... | ... | @@ -585,7 +585,7 @@ struct Foo { |
| 585 | 585 | c : f32, |
| 586 | 586 | } |
| 587 | 587 | fn test_foo(foo : Foo) { |
| 588 | if !foo.b { | |
| 588 | if (!foo.b) { | |
| 589 | 589 | print_str("BAD\n"); |
| 590 | 590 | } |
| 591 | 591 | } |
| ... | ... | @@ -610,7 +610,7 @@ fn test_point_to_self() { |
| 610 | 610 | |
| 611 | 611 | root.next = &node; |
| 612 | 612 | |
| 613 | if node.next.next.next.val.x != 1 { | |
| 613 | if (node.next.next.next.val.x != 1) { | |
| 614 | 614 | print_str("BAD\n"); |
| 615 | 615 | } |
| 616 | 616 | } |
| ... | ... | @@ -620,15 +620,15 @@ fn test_byval_assign() { |
| 620 | 620 | |
| 621 | 621 | foo1.a = 1234; |
| 622 | 622 | |
| 623 | if foo2.a != 0 { print_str("BAD\n"); } | |
| 623 | if (foo2.a != 0) { print_str("BAD\n"); } | |
| 624 | 624 | |
| 625 | 625 | foo2 = foo1; |
| 626 | 626 | |
| 627 | if foo2.a != 1234 { print_str("BAD - byval assignment failed\n"); } | |
| 627 | if (foo2.a != 1234) { print_str("BAD - byval assignment failed\n"); } | |
| 628 | 628 | } |
| 629 | 629 | fn test_initializer() { |
| 630 | 630 | const val = Val { .x = 42 }; |
| 631 | if val.x != 42 { print_str("BAD\n"); } | |
| 631 | if (val.x != 42) { print_str("BAD\n"); } | |
| 632 | 632 | } |
| 633 | 633 | )SOURCE", "OK\n"); |
| 634 | 634 | |
| ... | ... | @@ -639,9 +639,9 @@ const g1 : i32 = 1233 + 1; |
| 639 | 639 | var g2 : i32; |
| 640 | 640 | |
| 641 | 641 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 642 | if g2 != 0 { print_str("BAD\n"); } | |
| 642 | if (g2 != 0) { print_str("BAD\n"); } | |
| 643 | 643 | g2 = g1; |
| 644 | if g2 != 1234 { print_str("BAD\n"); } | |
| 644 | if (g2 != 1234) { print_str("BAD\n"); } | |
| 645 | 645 | print_str("OK\n"); |
| 646 | 646 | return 0; |
| 647 | 647 | } |
| ... | ... | @@ -651,7 +651,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 651 | 651 | use "std.zig"; |
| 652 | 652 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 653 | 653 | var i : i32 = 0; |
| 654 | while i < 4 { | |
| 654 | while (i < 4) { | |
| 655 | 655 | print_str("loop\n"); |
| 656 | 656 | i += 1; |
| 657 | 657 | } |
| ... | ... | @@ -663,10 +663,10 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 663 | 663 | use "std.zig"; |
| 664 | 664 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 665 | 665 | var i : i32 = 0; |
| 666 | while true { | |
| 666 | while (true) { | |
| 667 | 667 | print_str("loop\n"); |
| 668 | 668 | i += 1; |
| 669 | if i < 4 { | |
| 669 | if (i < 4) { | |
| 670 | 670 | continue; |
| 671 | 671 | } |
| 672 | 672 | break; |
| ... | ... | @@ -871,8 +871,8 @@ fn f() { |
| 871 | 871 | |
| 872 | 872 | add_compile_fail_case("missing else clause", R"SOURCE( |
| 873 | 873 | fn f() { |
| 874 | const x : i32 = if true { 1 }; | |
| 875 | const y = if true { 1 as i32 }; | |
| 874 | const x : i32 = if (true) { 1 }; | |
| 875 | const y = if (true) { 1 as i32 }; | |
| 876 | 876 | } |
| 877 | 877 | )SOURCE", 2, ".tmp_source.zig:3:21: error: expected type 'i32', got 'void'", |
| 878 | 878 | ".tmp_source.zig:4:15: error: incompatible types: 'i32' and 'void'"); |