| 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,10 +60,12 @@ ParamDeclList : token(LParen) list(ParamDecl, token(Comma)) token(RParen) |
| 60 | 60 | ||
| 61 | ParamDecl : token(Symbol) token(Colon) Type | token(Ellipsis) | 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 | PointerType : token(Ampersand) option(token(Const)) Type | 65 | PointerType : token(Ampersand) option(token(Const)) Type |
| 66 | 66 | ||
| 67 | MaybeType : token(Question) Type | ||
| 68 | |||
| 67 | ArrayType : token(LBracket) Type token(Semicolon) Expression token(RBracket) | 69 | ArrayType : token(LBracket) Type token(Semicolon) Expression token(RBracket) |
| 68 | 70 | ||
| 69 | Block : token(LBrace) list(option(Statement), token(Semicolon)) token(RBrace) | 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,7 +98,7 @@ AssignmentOperator : token(Eq) | token(TimesEq) | token(DivEq) | token(ModEq) | |
| 96 | 98 | ||
| 97 | BlockExpression : IfExpression | Block | WhileExpression | 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 | BoolOrExpression : BoolAndExpression token(BoolOr) BoolOrExpression | BoolAndExpression | 103 | BoolOrExpression : BoolAndExpression token(BoolOr) BoolOrExpression | BoolAndExpression |
| 102 | 104 | ||
| ... | @@ -104,13 +106,11 @@ ReturnExpression : token(Return) option(Expression) | ... | @@ -104,13 +106,11 @@ ReturnExpression : token(Return) option(Expression) |
| 104 | 106 | ||
| 105 | IfExpression : IfVarExpression | IfBoolExpression | 107 | IfExpression : IfVarExpression | IfBoolExpression |
| 106 | 108 | ||
| 107 | IfBoolExpression : token(If) option((token) Expression Block option(Else | ElseIf) | 109 | IfBoolExpression : token(If) token(LParen) Expression token(RParen) Expression option(Else) |
| 108 | |||
| 109 | IfVarExpression : token(If) (token(Const) | token(Var)) token(Symbol) option(token(Colon) Type) Token(MaybeAssign) Expression Block Option(Else | ElseIf) | ||
| 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 | BoolAndExpression : ComparisonExpression token(BoolAnd) BoolAndExpression | ComparisonExpression | 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,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 | static TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size) { | 155 | static TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size) { |
| 136 | auto existing_entry = child_type->arrays_by_size.maybe_get(array_size); | 156 | auto existing_entry = child_type->arrays_by_size.maybe_get(array_size); |
| 137 | if (existing_entry) { | 157 | if (existing_entry) { |
| ... | @@ -208,6 +228,20 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) { | ... | @@ -208,6 +228,20 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) { |
| 208 | } | 228 | } |
| 209 | return type_node->entry; | 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 | zig_unreachable(); | 246 | zig_unreachable(); |
| 213 | } | 247 | } |
src/analyze.hpp+1| ... | @@ -96,6 +96,7 @@ struct TypeTableEntry { | ... | @@ -96,6 +96,7 @@ struct TypeTableEntry { |
| 96 | TypeTableEntry *pointer_const_parent; | 96 | TypeTableEntry *pointer_const_parent; |
| 97 | TypeTableEntry *pointer_mut_parent; | 97 | TypeTableEntry *pointer_mut_parent; |
| 98 | HashMap<uint64_t, TypeTableEntry *, uint64_hash, uint64_eq> arrays_by_size; | 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,6 +225,12 @@ void ast_print(AstNode *node, int indent) { |
| 225 | ast_print(node->data.type.array_size, indent + 2); | 225 | ast_print(node->data.type.array_size, indent + 2); |
| 226 | break; | 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 | break; | 235 | break; |
| 230 | case NodeTypeReturnExpr: | 236 | case NodeTypeReturnExpr: |
| ... | @@ -920,7 +926,7 @@ static void ast_parse_type_assume_amp(ParseContext *pc, int *token_index, AstNod | ... | @@ -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 | PointerType : token(Ampersand) option(token(Const)) Type | 930 | PointerType : token(Ampersand) option(token(Const)) Type |
| 925 | ArrayType : token(LBracket) Type token(Semicolon) token(Number) token(RBracket) | 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,6 +947,9 @@ static AstNode *ast_parse_type(ParseContext *pc, int *token_index) { |
| 941 | ast_buf_from_token(pc, token, &node->data.type.primitive_name); | 947 | ast_buf_from_token(pc, token, &node->data.type.primitive_name); |
| 942 | } else if (token->id == TokenIdAmpersand) { | 948 | } else if (token->id == TokenIdAmpersand) { |
| 943 | ast_parse_type_assume_amp(pc, token_index, node); | 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 | } else if (token->id == TokenIdBoolAnd) { | 953 | } else if (token->id == TokenIdBoolAnd) { |
| 945 | // Pretend that we got 2 ampersand tokens | 954 | // Pretend that we got 2 ampersand tokens |
| 946 | node->data.type.type = AstNodeTypeTypePointer; | 955 | node->data.type.type = AstNodeTypeTypePointer; |
| ... | @@ -1636,10 +1645,9 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc, int *token_index, bool | ... | @@ -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 | 1648 | Else : token(Else) Expression |
| 1640 | Else : token(Else) Block | ||
| 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 | Token *else_token = &pc->tokens->at(*token_index); | 1651 | Token *else_token = &pc->tokens->at(*token_index); |
| 1644 | 1652 | ||
| 1645 | if (else_token->id != TokenIdKeywordElse) { | 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,17 +1659,13 @@ static AstNode *ast_parse_else_or_else_if(ParseContext *pc, int *token_index, bo |
| 1651 | } | 1659 | } |
| 1652 | *token_index += 1; | 1660 | *token_index += 1; |
| 1653 | 1661 | ||
| 1654 | AstNode *if_expr = ast_parse_if_expr(pc, token_index, false); | 1662 | return ast_parse_expression(pc, token_index, true); |
| 1655 | if (if_expr) | ||
| 1656 | return if_expr; | ||
| 1657 | |||
| 1658 | return ast_parse_block(pc, token_index, true); | ||
| 1659 | } | 1663 | } |
| 1660 | 1664 | ||
| 1661 | /* | 1665 | /* |
| 1662 | IfExpression : IfVarExpression | IfBoolExpression | 1666 | IfExpression : IfVarExpression | IfBoolExpression |
| 1663 | IfBoolExpression : token(If) option((token) Expression Block option(Else | ElseIf) | 1667 | IfBoolExpression : token(If) token(LParen) Expression token(RParen) Expression option(Else) |
| 1664 | IfVarExpression : token(If) (token(Const) | token(Var)) token(Symbol) option(token(Colon) Type) Token(Eq) Expression Block Option(Else | ElseIf) | 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 | static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool mandatory) { | 1670 | static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool mandatory) { |
| 1667 | Token *if_tok = &pc->tokens->at(*token_index); | 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,6 +1678,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda |
| 1674 | } | 1678 | } |
| 1675 | *token_index += 1; | 1679 | *token_index += 1; |
| 1676 | 1680 | ||
| 1681 | ast_eat_token(pc, token_index, TokenIdLParen); | ||
| 1682 | |||
| 1677 | Token *token = &pc->tokens->at(*token_index); | 1683 | Token *token = &pc->tokens->at(*token_index); |
| 1678 | if (token->id == TokenIdKeywordConst || token->id == TokenIdKeywordVar) { | 1684 | if (token->id == TokenIdKeywordConst || token->id == TokenIdKeywordVar) { |
| 1679 | AstNode *node = ast_create_node(pc, NodeTypeIfVarExpr, if_tok); | 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,14 +1701,16 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda |
| 1695 | } else { | 1701 | } else { |
| 1696 | ast_invalid_token_error(pc, eq_or_colon); | 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); | 1704 | ast_eat_token(pc, token_index, TokenIdRParen); |
| 1699 | node->data.if_var_expr.else_node = ast_parse_else_or_else_if(pc, token_index, false); | 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 | return node; | 1707 | return node; |
| 1701 | } else { | 1708 | } else { |
| 1702 | AstNode *node = ast_create_node(pc, NodeTypeIfBoolExpr, if_tok); | 1709 | AstNode *node = ast_create_node(pc, NodeTypeIfBoolExpr, if_tok); |
| 1703 | node->data.if_bool_expr.condition = ast_parse_expression(pc, token_index, true); | 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); | 1711 | ast_eat_token(pc, token_index, TokenIdRParen); |
| 1705 | node->data.if_bool_expr.else_node = ast_parse_else_or_else_if(pc, token_index, false); | 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 | return node; | 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,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 | static AstNode *ast_parse_while_expr(ParseContext *pc, int *token_index, bool mandatory) { | 1808 | static AstNode *ast_parse_while_expr(ParseContext *pc, int *token_index, bool mandatory) { |
| 1801 | Token *token = &pc->tokens->at(*token_index); | 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,8 +1819,13 @@ static AstNode *ast_parse_while_expr(ParseContext *pc, int *token_index, bool ma |
| 1811 | 1819 | ||
| 1812 | AstNode *node = ast_create_node(pc, NodeTypeWhileExpr, token); | 1820 | AstNode *node = ast_create_node(pc, NodeTypeWhileExpr, token); |
| 1813 | 1821 | ||
| 1822 | ast_eat_token(pc, token_index, TokenIdLParen); | ||
| 1814 | node->data.while_expr.condition = ast_parse_expression(pc, token_index, true); | 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 | return node; | 1830 | return node; |
| 1818 | } | 1831 | } |
src/parser.hpp+1| ... | @@ -95,6 +95,7 @@ enum AstNodeTypeType { | ... | @@ -95,6 +95,7 @@ enum AstNodeTypeType { |
| 95 | AstNodeTypeTypePrimitive, | 95 | AstNodeTypeTypePrimitive, |
| 96 | AstNodeTypeTypePointer, | 96 | AstNodeTypeTypePointer, |
| 97 | AstNodeTypeTypeArray, | 97 | AstNodeTypeTypeArray, |
| 98 | AstNodeTypeTypeMaybe, | ||
| 98 | }; | 99 | }; |
| 99 | 100 | ||
| 100 | struct AstNodeType { | 101 | struct AstNodeType { |
test/run_tests.cpp+49-49| ... | @@ -184,17 +184,17 @@ static void add_compiling_test_cases(void) { | ... | @@ -184,17 +184,17 @@ static void add_compiling_test_cases(void) { |
| 184 | use "std.zig"; | 184 | use "std.zig"; |
| 185 | 185 | ||
| 186 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | 186 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 187 | if 1 != 0 { | 187 | if (1 != 0) { |
| 188 | print_str("1 is true\n"); | 188 | print_str("1 is true\n"); |
| 189 | } else { | 189 | } else { |
| 190 | print_str("1 is false\n"); | 190 | print_str("1 is false\n"); |
| 191 | } | 191 | } |
| 192 | if 0 != 0 { | 192 | if (0 != 0) { |
| 193 | print_str("0 is true\n"); | 193 | print_str("0 is true\n"); |
| 194 | } else if 1 - 1 != 0 { | 194 | } else if (1 - 1 != 0) { |
| 195 | print_str("1 - 1 is true\n"); | 195 | print_str("1 - 1 is true\n"); |
| 196 | } | 196 | } |
| 197 | if !(0 != 0) { | 197 | if (!(0 != 0)) { |
| 198 | print_str("!0 is true\n"); | 198 | print_str("!0 is true\n"); |
| 199 | } | 199 | } |
| 200 | return 0; | 200 | return 0; |
| ... | @@ -209,7 +209,7 @@ static void add_compiling_test_cases(void) { | ... | @@ -209,7 +209,7 @@ static void add_compiling_test_cases(void) { |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | 211 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 212 | if add(22, 11) == 33 { | 212 | if (add(22, 11) == 33) { |
| 213 | print_str("pass\n"); | 213 | print_str("pass\n"); |
| 214 | } | 214 | } |
| 215 | return 0; | 215 | return 0; |
| ... | @@ -220,7 +220,7 @@ static void add_compiling_test_cases(void) { | ... | @@ -220,7 +220,7 @@ static void add_compiling_test_cases(void) { |
| 220 | use "std.zig"; | 220 | use "std.zig"; |
| 221 | 221 | ||
| 222 | fn loop(a : i32) { | 222 | fn loop(a : i32) { |
| 223 | if a == 0 { | 223 | if (a == 0) { |
| 224 | goto done; | 224 | goto done; |
| 225 | } | 225 | } |
| 226 | print_str("loop\n"); | 226 | print_str("loop\n"); |
| ... | @@ -304,7 +304,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | ... | @@ -304,7 +304,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 304 | 304 | ||
| 305 | var i = 0 as i32; | 305 | var i = 0 as i32; |
| 306 | loop_start: | 306 | loop_start: |
| 307 | if i == 3 { | 307 | if (i == 3) { |
| 308 | goto done; | 308 | goto done; |
| 309 | } | 309 | } |
| 310 | print_str("loop\n"); | 310 | print_str("loop\n"); |
| ... | @@ -323,7 +323,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | ... | @@ -323,7 +323,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 323 | 323 | ||
| 324 | var i : i32 = 0; | 324 | var i : i32 = 0; |
| 325 | loop_start: | 325 | loop_start: |
| 326 | if i == 5 { | 326 | if (i == 5) { |
| 327 | goto loop_end; | 327 | goto loop_end; |
| 328 | } | 328 | } |
| 329 | array[i] = i + 1; | 329 | array[i] = i + 1; |
| ... | @@ -335,7 +335,7 @@ loop_end: | ... | @@ -335,7 +335,7 @@ loop_end: |
| 335 | i = 0; | 335 | i = 0; |
| 336 | var accumulator = 0 as i32; | 336 | var accumulator = 0 as i32; |
| 337 | loop_2_start: | 337 | loop_2_start: |
| 338 | if i == 5 { | 338 | if (i == 5) { |
| 339 | goto loop_2_end; | 339 | goto loop_2_end; |
| 340 | } | 340 | } |
| 341 | 341 | ||
| ... | @@ -345,7 +345,7 @@ loop_2_start: | ... | @@ -345,7 +345,7 @@ loop_2_start: |
| 345 | goto loop_2_start; | 345 | goto loop_2_start; |
| 346 | loop_2_end: | 346 | loop_2_end: |
| 347 | 347 | ||
| 348 | if accumulator == 15 { | 348 | if (accumulator == 15) { |
| 349 | print_str("OK\n"); | 349 | print_str("OK\n"); |
| 350 | } | 350 | } |
| 351 | 351 | ||
| ... | @@ -368,18 +368,18 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | ... | @@ -368,18 +368,18 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 368 | use "std.zig"; | 368 | use "std.zig"; |
| 369 | 369 | ||
| 370 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | 370 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 371 | if false || false || false { print_str("BAD 1\n"); } | 371 | if (false || false || false) { print_str("BAD 1\n"); } |
| 372 | if true && true && false { print_str("BAD 2\n"); } | 372 | if (true && true && false) { print_str("BAD 2\n"); } |
| 373 | if 1 | 2 | 4 != 7 { print_str("BAD 3\n"); } | 373 | if (1 | 2 | 4 != 7) { print_str("BAD 3\n"); } |
| 374 | if 3 ^ 6 ^ 8 != 13 { print_str("BAD 4\n"); } | 374 | if (3 ^ 6 ^ 8 != 13) { print_str("BAD 4\n"); } |
| 375 | if 7 & 14 & 28 != 4 { print_str("BAD 5\n"); } | 375 | if (7 & 14 & 28 != 4) { print_str("BAD 5\n"); } |
| 376 | if 9 << 1 << 2 != 9 << 3 { print_str("BAD 6\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"); } | 377 | if (90 >> 1 >> 2 != 90 >> 3) { print_str("BAD 7\n"); } |
| 378 | if 100 - 1 + 1000 != 1099 { print_str("BAD 8\n"); } | 378 | if (100 - 1 + 1000 != 1099) { print_str("BAD 8\n"); } |
| 379 | if 5 * 4 / 2 % 3 != 1 { print_str("BAD 9\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"); } | 380 | if (5 as i32 as i32 != 5) { print_str("BAD 10\n"); } |
| 381 | if !!false { print_str("BAD 11\n"); } | 381 | if (!!false) { print_str("BAD 11\n"); } |
| 382 | if 7 != --7 { print_str("BAD 12\n"); } | 382 | if (7 != --7) { print_str("BAD 12\n"); } |
| 383 | 383 | ||
| 384 | print_str("OK\n"); | 384 | print_str("OK\n"); |
| 385 | return 0; | 385 | return 0; |
| ... | @@ -390,17 +390,17 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | ... | @@ -390,17 +390,17 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 390 | use "std.zig"; | 390 | use "std.zig"; |
| 391 | 391 | ||
| 392 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | 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 | print_str("OK 1\n"); | 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 | print_str("BAD 2\n"); | 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 | print_str("BAD 3\n"); | 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 | } else { | 404 | } else { |
| 405 | print_str("OK 4\n"); | 405 | print_str("OK 4\n"); |
| 406 | } | 406 | } |
| ... | @@ -414,18 +414,18 @@ use "std.zig"; | ... | @@ -414,18 +414,18 @@ use "std.zig"; |
| 414 | 414 | ||
| 415 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | 415 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 416 | var i : i32 = 0; | 416 | var i : i32 = 0; |
| 417 | i += 5; if i != 5 { print_str("BAD +=\n"); } | 417 | i += 5; if (i != 5) { print_str("BAD +=\n"); } |
| 418 | i -= 2; if i != 3 { print_str("BAD -=\n"); } | 418 | i -= 2; if (i != 3) { print_str("BAD -=\n"); } |
| 419 | i *= 20; if i != 60 { print_str("BAD *=\n"); } | 419 | i *= 20; if (i != 60) { print_str("BAD *=\n"); } |
| 420 | i /= 3; if i != 20 { print_str("BAD /=\n"); } | 420 | i /= 3; if (i != 20) { print_str("BAD /=\n"); } |
| 421 | i %= 11; if i != 9 { print_str("BAD %=\n"); } | 421 | i %= 11; if (i != 9) { print_str("BAD %=\n"); } |
| 422 | i <<= 1; if i != 18 { print_str("BAD <<=\n"); } | 422 | i <<= 1; if (i != 18) { print_str("BAD <<=\n"); } |
| 423 | i >>= 2; if i != 4 { print_str("BAD >>=\n"); } | 423 | i >>= 2; if (i != 4) { print_str("BAD >>=\n"); } |
| 424 | i = 6; | 424 | i = 6; |
| 425 | i &= 5; if i != 4 { print_str("BAD &=\n"); } | 425 | i &= 5; if (i != 4) { print_str("BAD &=\n"); } |
| 426 | i ^= 6; if i != 2 { print_str("BAD ^=\n"); } | 426 | i ^= 6; if (i != 2) { print_str("BAD ^=\n"); } |
| 427 | i = 6; | 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 | print_str("OK\n"); | 430 | print_str("OK\n"); |
| 431 | return 0; | 431 | return 0; |
| ... | @@ -570,7 +570,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | ... | @@ -570,7 +570,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 570 | foo.b = foo.a == 1; | 570 | foo.b = foo.a == 1; |
| 571 | test_foo(foo); | 571 | test_foo(foo); |
| 572 | test_mutation(&foo); | 572 | test_mutation(&foo); |
| 573 | if foo.c != 100 { | 573 | if (foo.c != 100) { |
| 574 | print_str("BAD\n"); | 574 | print_str("BAD\n"); |
| 575 | } | 575 | } |
| 576 | test_point_to_self(); | 576 | test_point_to_self(); |
| ... | @@ -585,7 +585,7 @@ struct Foo { | ... | @@ -585,7 +585,7 @@ struct Foo { |
| 585 | c : f32, | 585 | c : f32, |
| 586 | } | 586 | } |
| 587 | fn test_foo(foo : Foo) { | 587 | fn test_foo(foo : Foo) { |
| 588 | if !foo.b { | 588 | if (!foo.b) { |
| 589 | print_str("BAD\n"); | 589 | print_str("BAD\n"); |
| 590 | } | 590 | } |
| 591 | } | 591 | } |
| ... | @@ -610,7 +610,7 @@ fn test_point_to_self() { | ... | @@ -610,7 +610,7 @@ fn test_point_to_self() { |
| 610 | 610 | ||
| 611 | root.next = &node; | 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 | print_str("BAD\n"); | 614 | print_str("BAD\n"); |
| 615 | } | 615 | } |
| 616 | } | 616 | } |
| ... | @@ -620,15 +620,15 @@ fn test_byval_assign() { | ... | @@ -620,15 +620,15 @@ fn test_byval_assign() { |
| 620 | 620 | ||
| 621 | foo1.a = 1234; | 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 | foo2 = foo1; | 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 | fn test_initializer() { | 629 | fn test_initializer() { |
| 630 | const val = Val { .x = 42 }; | 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 | )SOURCE", "OK\n"); | 633 | )SOURCE", "OK\n"); |
| 634 | 634 | ||
| ... | @@ -639,9 +639,9 @@ const g1 : i32 = 1233 + 1; | ... | @@ -639,9 +639,9 @@ const g1 : i32 = 1233 + 1; |
| 639 | var g2 : i32; | 639 | var g2 : i32; |
| 640 | 640 | ||
| 641 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | 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 | g2 = g1; | 643 | g2 = g1; |
| 644 | if g2 != 1234 { print_str("BAD\n"); } | 644 | if (g2 != 1234) { print_str("BAD\n"); } |
| 645 | print_str("OK\n"); | 645 | print_str("OK\n"); |
| 646 | return 0; | 646 | return 0; |
| 647 | } | 647 | } |
| ... | @@ -651,7 +651,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | ... | @@ -651,7 +651,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 651 | use "std.zig"; | 651 | use "std.zig"; |
| 652 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | 652 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 653 | var i : i32 = 0; | 653 | var i : i32 = 0; |
| 654 | while i < 4 { | 654 | while (i < 4) { |
| 655 | print_str("loop\n"); | 655 | print_str("loop\n"); |
| 656 | i += 1; | 656 | i += 1; |
| 657 | } | 657 | } |
| ... | @@ -663,10 +663,10 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | ... | @@ -663,10 +663,10 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 663 | use "std.zig"; | 663 | use "std.zig"; |
| 664 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | 664 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 665 | var i : i32 = 0; | 665 | var i : i32 = 0; |
| 666 | while true { | 666 | while (true) { |
| 667 | print_str("loop\n"); | 667 | print_str("loop\n"); |
| 668 | i += 1; | 668 | i += 1; |
| 669 | if i < 4 { | 669 | if (i < 4) { |
| 670 | continue; | 670 | continue; |
| 671 | } | 671 | } |
| 672 | break; | 672 | break; |
| ... | @@ -871,8 +871,8 @@ fn f() { | ... | @@ -871,8 +871,8 @@ fn f() { |
| 871 | 871 | ||
| 872 | add_compile_fail_case("missing else clause", R"SOURCE( | 872 | add_compile_fail_case("missing else clause", R"SOURCE( |
| 873 | fn f() { | 873 | fn f() { |
| 874 | const x : i32 = if true { 1 }; | 874 | const x : i32 = if (true) { 1 }; |
| 875 | const y = if true { 1 as i32 }; | 875 | const y = if (true) { 1 as i32 }; |
| 876 | } | 876 | } |
| 877 | )SOURCE", 2, ".tmp_source.zig:3:21: error: expected type 'i32', got 'void'", | 877 | )SOURCE", 2, ".tmp_source.zig:3:21: error: expected type 'i32', got 'void'", |
| 878 | ".tmp_source.zig:4:15: error: incompatible types: 'i32' and 'void'"); | 878 | ".tmp_source.zig:4:15: error: incompatible types: 'i32' and 'void'"); |