| author | |
| committer | |
| log | 431d8f946fc1340475bd6d849d74a741fd119251 |
| tree | 13f42f86e534e3917bcfd7dbfe5a8a96668fb2ef |
| parent | 423ee0689be4f93b2613a5e42e7411887a9a46ad |
closes #365 files changed, 98 insertions(+), 86 deletions(-)
example/hello_world/hello.zig+1-2| ... | @@ -3,7 +3,6 @@ export executable "hello"; | ... | @@ -3,7 +3,6 @@ export executable "hello"; |
| 3 | use "std.zig"; | 3 | use "std.zig"; |
| 4 | 4 | ||
| 5 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | 5 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 6 | // TODO implicit coercion from array to string | 6 | print_str("Hello, world!\n"); |
| 7 | print_str("Hello, world!\n" as string); | ||
| 8 | return 0; | 7 | return 0; |
| 9 | } | 8 | } |
src/analyze.cpp+31-17| ... | @@ -618,7 +618,7 @@ static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type, | ... | @@ -618,7 +618,7 @@ static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type, |
| 618 | zig_unreachable(); | 618 | zig_unreachable(); |
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | static TypeTableEntry *resolve_type_compatibility(CodeGen *g, AstNode *node, | 621 | static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *context, AstNode *node, |
| 622 | TypeTableEntry *expected_type, TypeTableEntry *actual_type) | 622 | TypeTableEntry *expected_type, TypeTableEntry *actual_type) |
| 623 | { | 623 | { |
| 624 | if (expected_type == nullptr) | 624 | if (expected_type == nullptr) |
| ... | @@ -642,8 +642,21 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, AstNode *node, | ... | @@ -642,8 +642,21 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, AstNode *node, |
| 642 | expected_type->data.integral.is_signed == actual_type->data.integral.is_signed && | 642 | expected_type->data.integral.is_signed == actual_type->data.integral.is_signed && |
| 643 | expected_type->size_in_bits > actual_type->size_in_bits) | 643 | expected_type->size_in_bits > actual_type->size_in_bits) |
| 644 | { | 644 | { |
| 645 | node->codegen_node->expr_node.cast_type = expected_type; | 645 | node->codegen_node->expr_node.implicit_cast.type = expected_type; |
| 646 | node->codegen_node->expr_node.implicit_cast.op = CastOpIntWidenOrShorten; | 646 | node->codegen_node->expr_node.implicit_cast.op = CastOpIntWidenOrShorten; |
| 647 | node->codegen_node->expr_node.implicit_cast.source_node = node; | ||
| 648 | return expected_type; | ||
| 649 | } | ||
| 650 | |||
| 651 | // implicit constant sized array to string conversion | ||
| 652 | if (expected_type == g->builtin_types.entry_string && | ||
| 653 | actual_type->id == TypeTableEntryIdArray && | ||
| 654 | actual_type->data.array.child_type == g->builtin_types.entry_u8) | ||
| 655 | { | ||
| 656 | node->codegen_node->expr_node.implicit_cast.type = expected_type; | ||
| 657 | node->codegen_node->expr_node.implicit_cast.op = CastOpArrayToString; | ||
| 658 | node->codegen_node->expr_node.implicit_cast.source_node = node; | ||
| 659 | context->cast_expr_alloca_list.append(&node->codegen_node->expr_node.implicit_cast); | ||
| 647 | return expected_type; | 660 | return expected_type; |
| 648 | } | 661 | } |
| 649 | 662 | ||
| ... | @@ -655,7 +668,8 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, AstNode *node, | ... | @@ -655,7 +668,8 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, AstNode *node, |
| 655 | return g->builtin_types.entry_invalid; | 668 | return g->builtin_types.entry_invalid; |
| 656 | } | 669 | } |
| 657 | 670 | ||
| 658 | static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, AstNode *parent_node, | 671 | static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, BlockContext *block_context, |
| 672 | AstNode *parent_node, | ||
| 659 | AstNode *child1, AstNode *child2, | 673 | AstNode *child1, AstNode *child2, |
| 660 | TypeTableEntry *type1, TypeTableEntry *type2) | 674 | TypeTableEntry *type1, TypeTableEntry *type2) |
| 661 | { | 675 | { |
| ... | @@ -668,8 +682,8 @@ static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, AstNode *pare | ... | @@ -668,8 +682,8 @@ static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, AstNode *pare |
| 668 | return parent_type; | 682 | return parent_type; |
| 669 | } | 683 | } |
| 670 | 684 | ||
| 671 | resolve_type_compatibility(g, child1, parent_type, type1); | 685 | resolve_type_compatibility(g, block_context, child1, parent_type, type1); |
| 672 | resolve_type_compatibility(g, child2, parent_type, type2); | 686 | resolve_type_compatibility(g, block_context, child2, parent_type, type2); |
| 673 | 687 | ||
| 674 | return parent_type; | 688 | return parent_type; |
| 675 | } | 689 | } |
| ... | @@ -874,6 +888,8 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -874,6 +888,8 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 874 | } | 888 | } |
| 875 | 889 | ||
| 876 | CastNode *cast_node = &node->codegen_node->data.cast_node; | 890 | CastNode *cast_node = &node->codegen_node->data.cast_node; |
| 891 | cast_node->source_node = node; | ||
| 892 | cast_node->type = wanted_type; | ||
| 877 | 893 | ||
| 878 | // special casing this for now, TODO think about casting and do a general solution | 894 | // special casing this for now, TODO think about casting and do a general solution |
| 879 | if (wanted_type == g->builtin_types.entry_isize && | 895 | if (wanted_type == g->builtin_types.entry_isize && |
| ... | @@ -891,7 +907,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -891,7 +907,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 891 | actual_type->data.array.child_type == g->builtin_types.entry_u8) | 907 | actual_type->data.array.child_type == g->builtin_types.entry_u8) |
| 892 | { | 908 | { |
| 893 | cast_node->op = CastOpArrayToString; | 909 | cast_node->op = CastOpArrayToString; |
| 894 | context->cast_expr_alloca_list.append(node); | 910 | context->cast_expr_alloca_list.append(cast_node); |
| 895 | return wanted_type; | 911 | return wanted_type; |
| 896 | } else if (actual_type->id == TypeTableEntryIdNumberLiteral && | 912 | } else if (actual_type->id == TypeTableEntryIdNumberLiteral && |
| 897 | num_lit_fits_in_other_type(g, actual_type, wanted_type)) | 913 | num_lit_fits_in_other_type(g, actual_type, wanted_type)) |
| ... | @@ -1022,10 +1038,8 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -1022,10 +1038,8 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, |
| 1022 | } | 1038 | } |
| 1023 | case BinOpTypeBoolOr: | 1039 | case BinOpTypeBoolOr: |
| 1024 | case BinOpTypeBoolAnd: | 1040 | case BinOpTypeBoolAnd: |
| 1025 | analyze_expression(g, import, context, g->builtin_types.entry_bool, | 1041 | analyze_expression(g, import, context, g->builtin_types.entry_bool, node->data.bin_op_expr.op1); |
| 1026 | node->data.bin_op_expr.op1); | 1042 | analyze_expression(g, import, context, g->builtin_types.entry_bool, node->data.bin_op_expr.op2); |
| 1027 | analyze_expression(g, import, context, g->builtin_types.entry_bool, | ||
| 1028 | node->data.bin_op_expr.op2); | ||
| 1029 | return g->builtin_types.entry_bool; | 1043 | return g->builtin_types.entry_bool; |
| 1030 | case BinOpTypeCmpEq: | 1044 | case BinOpTypeCmpEq: |
| 1031 | case BinOpTypeCmpNotEq: | 1045 | case BinOpTypeCmpNotEq: |
| ... | @@ -1188,8 +1202,8 @@ static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableE | ... | @@ -1188,8 +1202,8 @@ static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableE |
| 1188 | return nullptr; | 1202 | return nullptr; |
| 1189 | } | 1203 | } |
| 1190 | 1204 | ||
| 1191 | static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 1205 | static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import, |
| 1192 | TypeTableEntry *expected_type, AstNode *node) | 1206 | BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node) |
| 1193 | { | 1207 | { |
| 1194 | TypeTableEntry *num_lit_type = g->num_lit_types[node->data.number_literal.kind]; | 1208 | TypeTableEntry *num_lit_type = g->num_lit_types[node->data.number_literal.kind]; |
| 1195 | if (node->data.number_literal.overflow) { | 1209 | if (node->data.number_literal.overflow) { |
| ... | @@ -1199,7 +1213,7 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry | ... | @@ -1199,7 +1213,7 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry |
| 1199 | } else if (expected_type) { | 1213 | } else if (expected_type) { |
| 1200 | NumberLiteralNode *codegen_num_lit = &node->codegen_node->data.num_lit_node; | 1214 | NumberLiteralNode *codegen_num_lit = &node->codegen_node->data.num_lit_node; |
| 1201 | assert(!codegen_num_lit->resolved_type); | 1215 | assert(!codegen_num_lit->resolved_type); |
| 1202 | codegen_num_lit->resolved_type = resolve_type_compatibility(g, node, expected_type, num_lit_type); | 1216 | codegen_num_lit->resolved_type = resolve_type_compatibility(g, block_context, node, expected_type, num_lit_type); |
| 1203 | return codegen_num_lit->resolved_type; | 1217 | return codegen_num_lit->resolved_type; |
| 1204 | } else { | 1218 | } else { |
| 1205 | return num_lit_type; | 1219 | return num_lit_type; |
| ... | @@ -1260,7 +1274,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -1260,7 +1274,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 1260 | actual_return_type = g->builtin_types.entry_invalid; | 1274 | actual_return_type = g->builtin_types.entry_invalid; |
| 1261 | } | 1275 | } |
| 1262 | 1276 | ||
| 1263 | resolve_type_compatibility(g, node, expected_return_type, actual_return_type); | 1277 | resolve_type_compatibility(g, context, node, expected_return_type, actual_return_type); |
| 1264 | } else { | 1278 | } else { |
| 1265 | add_node_error(g, node, buf_sprintf("return expression outside function definition")); | 1279 | add_node_error(g, node, buf_sprintf("return expression outside function definition")); |
| 1266 | } | 1280 | } |
| ... | @@ -1453,14 +1467,14 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -1453,14 +1467,14 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 1453 | else_type = analyze_expression(g, import, context, expected_type, node->data.if_expr.else_node); | 1467 | else_type = analyze_expression(g, import, context, expected_type, node->data.if_expr.else_node); |
| 1454 | } else { | 1468 | } else { |
| 1455 | else_type = g->builtin_types.entry_void; | 1469 | else_type = g->builtin_types.entry_void; |
| 1456 | else_type = resolve_type_compatibility(g, node, expected_type, else_type); | 1470 | else_type = resolve_type_compatibility(g, context, node, expected_type, else_type); |
| 1457 | } | 1471 | } |
| 1458 | 1472 | ||
| 1459 | 1473 | ||
| 1460 | if (expected_type) { | 1474 | if (expected_type) { |
| 1461 | return_type = (then_type->id == TypeTableEntryIdUnreachable) ? else_type : then_type; | 1475 | return_type = (then_type->id == TypeTableEntryIdUnreachable) ? else_type : then_type; |
| 1462 | } else { | 1476 | } else { |
| 1463 | return_type = resolve_peer_type_compatibility(g, node, | 1477 | return_type = resolve_peer_type_compatibility(g, context, node, |
| 1464 | node->data.if_expr.then_block, node->data.if_expr.else_node, | 1478 | node->data.if_expr.then_block, node->data.if_expr.else_node, |
| 1465 | then_type, else_type); | 1479 | then_type, else_type); |
| 1466 | } | 1480 | } |
| ... | @@ -1482,7 +1496,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -1482,7 +1496,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 1482 | zig_unreachable(); | 1496 | zig_unreachable(); |
| 1483 | } | 1497 | } |
| 1484 | assert(return_type); | 1498 | assert(return_type); |
| 1485 | resolve_type_compatibility(g, node, expected_type, return_type); | 1499 | resolve_type_compatibility(g, context, node, expected_type, return_type); |
| 1486 | 1500 | ||
| 1487 | node->codegen_node->expr_node.type_entry = return_type; | 1501 | node->codegen_node->expr_node.type_entry = return_type; |
| 1488 | node->codegen_node->expr_node.block_context = context; | 1502 | node->codegen_node->expr_node.block_context = context; |
src/analyze.hpp+4-2| ... | @@ -17,6 +17,7 @@ struct FnTableEntry; | ... | @@ -17,6 +17,7 @@ struct FnTableEntry; |
| 17 | struct BlockContext; | 17 | struct BlockContext; |
| 18 | struct TypeTableEntry; | 18 | struct TypeTableEntry; |
| 19 | struct VariableTableEntry; | 19 | struct VariableTableEntry; |
| 20 | struct CastNode; | ||
| 20 | 21 | ||
| 21 | struct TypeTableEntryPointer { | 22 | struct TypeTableEntryPointer { |
| 22 | TypeTableEntry *pointer_child; | 23 | TypeTableEntry *pointer_child; |
| ... | @@ -213,7 +214,7 @@ struct BlockContext { | ... | @@ -213,7 +214,7 @@ struct BlockContext { |
| 213 | FnTableEntry *fn_entry; // null at the module scope | 214 | FnTableEntry *fn_entry; // null at the module scope |
| 214 | BlockContext *parent; // null when this is the root | 215 | BlockContext *parent; // null when this is the root |
| 215 | HashMap<Buf *, VariableTableEntry *, buf_hash, buf_eql_buf> variable_table; | 216 | HashMap<Buf *, VariableTableEntry *, buf_hash, buf_eql_buf> variable_table; |
| 216 | ZigList<AstNode *> cast_expr_alloca_list; | 217 | ZigList<CastNode *> cast_expr_alloca_list; |
| 217 | LLVMZigDIScope *di_scope; | 218 | LLVMZigDIScope *di_scope; |
| 218 | }; | 219 | }; |
| 219 | 220 | ||
| ... | @@ -261,6 +262,8 @@ struct CastNode { | ... | @@ -261,6 +262,8 @@ struct CastNode { |
| 261 | // if op is CastOpArrayToString, this will be a pointer to | 262 | // if op is CastOpArrayToString, this will be a pointer to |
| 262 | // the string struct on the stack | 263 | // the string struct on the stack |
| 263 | LLVMValueRef ptr; | 264 | LLVMValueRef ptr; |
| 265 | TypeTableEntry *type; | ||
| 266 | AstNode *source_node; | ||
| 264 | }; | 267 | }; |
| 265 | 268 | ||
| 266 | struct ExprNode { | 269 | struct ExprNode { |
| ... | @@ -270,7 +273,6 @@ struct ExprNode { | ... | @@ -270,7 +273,6 @@ struct ExprNode { |
| 270 | BlockContext *block_context; | 273 | BlockContext *block_context; |
| 271 | 274 | ||
| 272 | // may be null for no cast | 275 | // may be null for no cast |
| 273 | TypeTableEntry *cast_type; | ||
| 274 | CastNode implicit_cast; | 276 | CastNode implicit_cast; |
| 275 | }; | 277 | }; |
| 276 | 278 |
src/codegen.cpp+4-7| ... | @@ -1039,7 +1039,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { | ... | @@ -1039,7 +1039,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { |
| 1039 | assert(node->codegen_node); | 1039 | assert(node->codegen_node); |
| 1040 | 1040 | ||
| 1041 | TypeTableEntry *actual_type = node->codegen_node->expr_node.type_entry; | 1041 | TypeTableEntry *actual_type = node->codegen_node->expr_node.type_entry; |
| 1042 | TypeTableEntry *cast_type = node->codegen_node->expr_node.cast_type; | 1042 | TypeTableEntry *cast_type = node->codegen_node->expr_node.implicit_cast.type; |
| 1043 | 1043 | ||
| 1044 | return cast_type ? gen_bare_cast(g, node, val, actual_type, cast_type, | 1044 | return cast_type ? gen_bare_cast(g, node, val, actual_type, cast_type, |
| 1045 | &node->codegen_node->expr_node.implicit_cast) : val; | 1045 | &node->codegen_node->expr_node.implicit_cast) : val; |
| ... | @@ -1248,12 +1248,9 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -1248,12 +1248,9 @@ static void do_code_gen(CodeGen *g) { |
| 1248 | 1248 | ||
| 1249 | // allocate structs which are the result of casts | 1249 | // allocate structs which are the result of casts |
| 1250 | for (int cea_i = 0; cea_i < block_context->cast_expr_alloca_list.length; cea_i += 1) { | 1250 | for (int cea_i = 0; cea_i < block_context->cast_expr_alloca_list.length; cea_i += 1) { |
| 1251 | AstNode *cast_expr_node = block_context->cast_expr_alloca_list.at(cea_i); | 1251 | CastNode *cast_node = block_context->cast_expr_alloca_list.at(cea_i); |
| 1252 | assert(cast_expr_node->type == NodeTypeCastExpr); | 1252 | add_debug_source_node(g, cast_node->source_node); |
| 1253 | CastNode *cast_codegen = &cast_expr_node->codegen_node->data.cast_node; | 1253 | cast_node->ptr = LLVMBuildAlloca(g->builder, cast_node->type->type_ref, ""); |
| 1254 | TypeTableEntry *type_entry = get_type_for_type_node(g, cast_expr_node->data.cast_expr.type); | ||
| 1255 | add_debug_source_node(g, cast_expr_node); | ||
| 1256 | cast_codegen->ptr = LLVMBuildAlloca(g->builder, type_entry->type_ref, ""); | ||
| 1257 | } | 1254 | } |
| 1258 | } | 1255 | } |
| 1259 | 1256 |
test/run_tests.cpp+58-58| ... | @@ -121,7 +121,7 @@ static void add_compiling_test_cases(void) { | ... | @@ -121,7 +121,7 @@ static void add_compiling_test_cases(void) { |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | fn this_is_a_function() -> unreachable { | 123 | fn this_is_a_function() -> unreachable { |
| 124 | print_str("OK\n" as string); | 124 | print_str("OK\n"); |
| 125 | exit(0); | 125 | exit(0); |
| 126 | } | 126 | } |
| 127 | )SOURCE", "OK\n"); | 127 | )SOURCE", "OK\n"); |
| ... | @@ -137,7 +137,7 @@ static void add_compiling_test_cases(void) { | ... | @@ -137,7 +137,7 @@ static void add_compiling_test_cases(void) { |
| 137 | /// this is a documentation comment | 137 | /// this is a documentation comment |
| 138 | /// doc comment line 2 | 138 | /// doc comment line 2 |
| 139 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | 139 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 140 | print_str(/* mid-line comment /* nested */ */ "OK\n" as string); | 140 | print_str(/* mid-line comment /* nested */ */ "OK\n"); |
| 141 | return 0; | 141 | return 0; |
| 142 | } | 142 | } |
| 143 | )SOURCE", "OK\n"); | 143 | )SOURCE", "OK\n"); |
| ... | @@ -185,17 +185,17 @@ static void add_compiling_test_cases(void) { | ... | @@ -185,17 +185,17 @@ static void add_compiling_test_cases(void) { |
| 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" as string); | 188 | print_str("1 is true\n"); |
| 189 | } else { | 189 | } else { |
| 190 | print_str("1 is false\n" as string); | 190 | print_str("1 is false\n"); |
| 191 | } | 191 | } |
| 192 | if 0 != 0 { | 192 | if 0 != 0 { |
| 193 | print_str("0 is true\n" as string); | 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" as string); | 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" as string); | 198 | print_str("!0 is true\n"); |
| 199 | } | 199 | } |
| 200 | return 0; | 200 | return 0; |
| 201 | } | 201 | } |
| ... | @@ -210,7 +210,7 @@ static void add_compiling_test_cases(void) { | ... | @@ -210,7 +210,7 @@ static void add_compiling_test_cases(void) { |
| 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" as string); | 213 | print_str("pass\n"); |
| 214 | } | 214 | } |
| 215 | return 0; | 215 | return 0; |
| 216 | } | 216 | } |
| ... | @@ -223,7 +223,7 @@ static void add_compiling_test_cases(void) { | ... | @@ -223,7 +223,7 @@ static void add_compiling_test_cases(void) { |
| 223 | if a == 0 { | 223 | if a == 0 { |
| 224 | goto done; | 224 | goto done; |
| 225 | } | 225 | } |
| 226 | print_str("loop\n" as string); | 226 | print_str("loop\n"); |
| 227 | loop(a - 1); | 227 | loop(a - 1); |
| 228 | 228 | ||
| 229 | done: | 229 | done: |
| ... | @@ -243,7 +243,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | ... | @@ -243,7 +243,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 243 | const a : i32 = 1; | 243 | const a : i32 = 1; |
| 244 | const b = 2 as i32; | 244 | const b = 2 as i32; |
| 245 | if (a + b == 3) { | 245 | if (a + b == 3) { |
| 246 | print_str("OK\n" as string); | 246 | print_str("OK\n"); |
| 247 | } | 247 | } |
| 248 | return 0; | 248 | return 0; |
| 249 | } | 249 | } |
| ... | @@ -253,10 +253,10 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | ... | @@ -253,10 +253,10 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 253 | use "std.zig"; | 253 | use "std.zig"; |
| 254 | 254 | ||
| 255 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | 255 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 256 | if (true) { print_str("OK 1\n" as string); } | 256 | if (true) { print_str("OK 1\n"); } |
| 257 | if (false) { print_str("BAD 1\n" as string); } | 257 | if (false) { print_str("BAD 1\n"); } |
| 258 | if (!true) { print_str("BAD 2\n" as string); } | 258 | if (!true) { print_str("BAD 2\n"); } |
| 259 | if (!false) { print_str("OK 2\n" as string); } | 259 | if (!false) { print_str("OK 2\n"); } |
| 260 | return 0; | 260 | return 0; |
| 261 | } | 261 | } |
| 262 | )SOURCE", "OK 1\nOK 2\n"); | 262 | )SOURCE", "OK 1\nOK 2\n"); |
| ... | @@ -267,14 +267,14 @@ use "std.zig"; | ... | @@ -267,14 +267,14 @@ use "std.zig"; |
| 267 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | 267 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 268 | if (true) { | 268 | if (true) { |
| 269 | const no_conflict : i32 = 5; | 269 | const no_conflict : i32 = 5; |
| 270 | if (no_conflict == 5) { print_str("OK 1\n" as string); } | 270 | if (no_conflict == 5) { print_str("OK 1\n"); } |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | const c = { | 273 | const c = { |
| 274 | const no_conflict = 10 as i32; | 274 | const no_conflict = 10 as i32; |
| 275 | no_conflict | 275 | no_conflict |
| 276 | }; | 276 | }; |
| 277 | if (c == 10) { print_str("OK 2\n" as string); } | 277 | if (c == 10) { print_str("OK 2\n"); } |
| 278 | return 0; | 278 | return 0; |
| 279 | } | 279 | } |
| 280 | )SOURCE", "OK 1\nOK 2\n"); | 280 | )SOURCE", "OK 1\nOK 2\n"); |
| ... | @@ -290,7 +290,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | ... | @@ -290,7 +290,7 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 290 | fn void_fun(a : i32, b : void, c : i32) { | 290 | fn void_fun(a : i32, b : void, c : i32) { |
| 291 | const v = b; | 291 | const v = b; |
| 292 | const vv : void = if (a == 1) {v} else {}; | 292 | const vv : void = if (a == 1) {v} else {}; |
| 293 | if (a + c == 3) { print_str("OK\n" as string); } | 293 | if (a + c == 3) { print_str("OK\n"); } |
| 294 | return vv; | 294 | return vv; |
| 295 | } | 295 | } |
| 296 | )SOURCE", "OK\n"); | 296 | )SOURCE", "OK\n"); |
| ... | @@ -300,14 +300,14 @@ use "std.zig"; | ... | @@ -300,14 +300,14 @@ use "std.zig"; |
| 300 | 300 | ||
| 301 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | 301 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 302 | var zero : i32; | 302 | var zero : i32; |
| 303 | if (zero == 0) { print_str("zero\n" as string); } | 303 | if (zero == 0) { print_str("zero\n"); } |
| 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" as string); | 310 | print_str("loop\n"); |
| 311 | i = i + 1; | 311 | i = i + 1; |
| 312 | goto loop_start; | 312 | goto loop_start; |
| 313 | done: | 313 | done: |
| ... | @@ -346,7 +346,7 @@ loop_2_start: | ... | @@ -346,7 +346,7 @@ 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" as string); | 349 | print_str("OK\n"); |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | return 0; | 352 | return 0; |
| ... | @@ -358,7 +358,7 @@ loop_2_end: | ... | @@ -358,7 +358,7 @@ loop_2_end: |
| 358 | use "std.zig"; | 358 | use "std.zig"; |
| 359 | 359 | ||
| 360 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | 360 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 361 | print_str("Hello, world!\n" as string); | 361 | print_str("Hello, world!\n"); |
| 362 | return 0; | 362 | return 0; |
| 363 | } | 363 | } |
| 364 | )SOURCE", "Hello, world!\n"); | 364 | )SOURCE", "Hello, world!\n"); |
| ... | @@ -368,20 +368,20 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | ... | @@ -368,20 +368,20 @@ 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" as string); } | 371 | if false || false || false { print_str("BAD 1\n"); } |
| 372 | if true && true && false { print_str("BAD 2\n" as string); } | 372 | if true && true && false { print_str("BAD 2\n"); } |
| 373 | if 1 | 2 | 4 != 7 { print_str("BAD 3\n" as string); } | 373 | if 1 | 2 | 4 != 7 { print_str("BAD 3\n"); } |
| 374 | if 3 ^ 6 ^ 8 != 13 { print_str("BAD 4\n" as string); } | 374 | if 3 ^ 6 ^ 8 != 13 { print_str("BAD 4\n"); } |
| 375 | if 7 & 14 & 28 != 4 { print_str("BAD 5\n" as string); } | 375 | if 7 & 14 & 28 != 4 { print_str("BAD 5\n"); } |
| 376 | if 9 << 1 << 2 != 9 << 3 { print_str("BAD 6\n" as string); } | 376 | if 9 << 1 << 2 != 9 << 3 { print_str("BAD 6\n"); } |
| 377 | if 90 >> 1 >> 2 != 90 >> 3 { print_str("BAD 7\n" as string); } | 377 | if 90 >> 1 >> 2 != 90 >> 3 { print_str("BAD 7\n"); } |
| 378 | if 100 - 1 + 1000 != 1099 { print_str("BAD 8\n" as string); } | 378 | if 100 - 1 + 1000 != 1099 { print_str("BAD 8\n"); } |
| 379 | if 5 * 4 / 2 % 3 != 1 { print_str("BAD 9\n" as string); } | 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" as string); } | 380 | if 5 as i32 as i32 != 5 { print_str("BAD 10\n"); } |
| 381 | if !!false { print_str("BAD 11\n" as string); } | 381 | if !!false { print_str("BAD 11\n"); } |
| 382 | if 7 != --7 { print_str("BAD 12\n" as string); } | 382 | if 7 != --7 { print_str("BAD 12\n"); } |
| 383 | 383 | ||
| 384 | print_str("OK\n" as string); | 384 | print_str("OK\n"); |
| 385 | return 0; | 385 | return 0; |
| 386 | } | 386 | } |
| 387 | )SOURCE", "OK\n"); | 387 | )SOURCE", "OK\n"); |
| ... | @@ -390,19 +390,19 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | ... | @@ -390,19 +390,19 @@ 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" as string); false } { | 393 | if true || { print_str("BAD 1\n"); false } { |
| 394 | print_str("OK 1\n" as string); | 394 | print_str("OK 1\n"); |
| 395 | } | 395 | } |
| 396 | if false || { print_str("OK 2\n" as string); false } { | 396 | if false || { print_str("OK 2\n"); false } { |
| 397 | print_str("BAD 2\n" as string); | 397 | print_str("BAD 2\n"); |
| 398 | } | 398 | } |
| 399 | 399 | ||
| 400 | if true && { print_str("OK 3\n" as string); false } { | 400 | if true && { print_str("OK 3\n"); false } { |
| 401 | print_str("BAD 3\n" as string); | 401 | print_str("BAD 3\n"); |
| 402 | } | 402 | } |
| 403 | if false && { print_str("BAD 4\n" as string); false } { | 403 | if false && { print_str("BAD 4\n"); false } { |
| 404 | } else { | 404 | } else { |
| 405 | print_str("OK 4\n" as string); | 405 | print_str("OK 4\n"); |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | return 0; | 408 | return 0; |
| ... | @@ -414,20 +414,20 @@ use "std.zig"; | ... | @@ -414,20 +414,20 @@ 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" as string); } | 417 | i += 5; if i != 5 { print_str("BAD +=\n"); } |
| 418 | i -= 2; if i != 3 { print_str("BAD -=\n" as string); } | 418 | i -= 2; if i != 3 { print_str("BAD -=\n"); } |
| 419 | i *= 20; if i != 60 { print_str("BAD *=\n" as string); } | 419 | i *= 20; if i != 60 { print_str("BAD *=\n"); } |
| 420 | i /= 3; if i != 20 { print_str("BAD /=\n" as string); } | 420 | i /= 3; if i != 20 { print_str("BAD /=\n"); } |
| 421 | i %= 11; if i != 9 { print_str("BAD %=\n" as string); } | 421 | i %= 11; if i != 9 { print_str("BAD %=\n"); } |
| 422 | i <<= 1; if i != 18 { print_str("BAD <<=\n" as string); } | 422 | i <<= 1; if i != 18 { print_str("BAD <<=\n"); } |
| 423 | i >>= 2; if i != 4 { print_str("BAD >>=\n" as string); } | 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" as string); } | 425 | i &= 5; if i != 4 { print_str("BAD &=\n"); } |
| 426 | i ^= 6; if i != 2 { print_str("BAD ^=\n" as string); } | 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" as string); } | 428 | i |= 3; if i != 7 { print_str("BAD |=\n"); } |
| 429 | 429 | ||
| 430 | print_str("OK\n" as string); | 430 | print_str("OK\n"); |
| 431 | return 0; | 431 | return 0; |
| 432 | } | 432 | } |
| 433 | )SOURCE", "OK\n"); | 433 | )SOURCE", "OK\n"); |
| ... | @@ -578,7 +578,7 @@ struct Foo { | ... | @@ -578,7 +578,7 @@ struct Foo { |
| 578 | } | 578 | } |
| 579 | fn test_foo(foo : Foo) { | 579 | fn test_foo(foo : Foo) { |
| 580 | if foo.b { | 580 | if foo.b { |
| 581 | print_str("OK\n" as string); | 581 | print_str("OK\n"); |
| 582 | } | 582 | } |
| 583 | } | 583 | } |
| 584 | )SOURCE", "OK\n"); | 584 | )SOURCE", "OK\n"); |
| ... | @@ -590,10 +590,10 @@ const g1 : i32 = 1233 + 1; | ... | @@ -590,10 +590,10 @@ const g1 : i32 = 1233 + 1; |
| 590 | var g2 : i32; | 590 | var g2 : i32; |
| 591 | 591 | ||
| 592 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { | 592 | export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 593 | if g2 != 0 { print_str("BAD\n" as string); } | 593 | if g2 != 0 { print_str("BAD\n"); } |
| 594 | g2 = g1; | 594 | g2 = g1; |
| 595 | if g2 != 1234 { print_str("BAD\n" as string); } | 595 | if g2 != 1234 { print_str("BAD\n"); } |
| 596 | print_str("OK\n" as string); | 596 | print_str("OK\n"); |
| 597 | return 0; | 597 | return 0; |
| 598 | } | 598 | } |
| 599 | )SOURCE", "OK\n"); | 599 | )SOURCE", "OK\n"); |