authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-15 17:29:44-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-15 17:29:44-07:00
log431d8f946fc1340475bd6d849d74a741fd119251
tree13f42f86e534e3917bcfd7dbfe5a8a96668fb2ef
parent423ee0689be4f93b2613a5e42e7411887a9a46ad

implicit casting from constant size array to string

closes #36

5 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";
3use "std.zig";3use "std.zig";
44
5pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {5pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
6 // TODO implicit coercion from array to string6 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}
620620
621static TypeTableEntry *resolve_type_compatibility(CodeGen *g, AstNode *node,621static 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 }
649662
...@@ -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}
657670
658static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, AstNode *parent_node,671static 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 }
670684
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);
673687
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 }
875889
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;
877893
878 // special casing this for now, TODO think about casting and do a general solution894 // 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}
11901204
1191static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,1205static 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 }
12621276
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 }
14581472
14591473
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);
14861500
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;
17struct BlockContext;17struct BlockContext;
18struct TypeTableEntry;18struct TypeTableEntry;
19struct VariableTableEntry;19struct VariableTableEntry;
20struct CastNode;
2021
21struct TypeTableEntryPointer {22struct 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 scope214 FnTableEntry *fn_entry; // null at the module scope
214 BlockContext *parent; // null when this is the root215 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};
219220
...@@ -261,6 +262,8 @@ struct CastNode {...@@ -261,6 +262,8 @@ struct CastNode {
261 // if op is CastOpArrayToString, this will be a pointer to262 // if op is CastOpArrayToString, this will be a pointer to
262 // the string struct on the stack263 // the string struct on the stack
263 LLVMValueRef ptr;264 LLVMValueRef ptr;
265 TypeTableEntry *type;
266 AstNode *source_node;
264};267};
265268
266struct ExprNode {269struct ExprNode {
...@@ -270,7 +273,6 @@ struct ExprNode {...@@ -270,7 +273,6 @@ struct ExprNode {
270 BlockContext *block_context;273 BlockContext *block_context;
271274
272 // may be null for no cast275 // may be null for no cast
273 TypeTableEntry *cast_type;
274 CastNode implicit_cast;276 CastNode implicit_cast;
275};277};
276278
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);
10401040
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;
10431043
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) {
12481248
1249 // allocate structs which are the result of casts1249 // 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 }
12591256
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 }
122122
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 comment137 /// this is a documentation comment
138 /// doc comment line 2138 /// 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) {
185185
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) {
210210
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);
228228
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 {
253use "std.zig";253use "std.zig";
254254
255pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {255pub 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";
267pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {267pub 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 }
272272
273 const c = {273 const c = {
274 const no_conflict = 10 as i32;274 const no_conflict = 10 as i32;
275 no_conflict275 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 {
290fn void_fun(a : i32, b : void, c : i32) {290fn 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";
300300
301pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {301pub 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"); }
304304
305 var i = 0 as i32;305 var i = 0 as i32;
306loop_start:306loop_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;
313done:313done:
...@@ -346,7 +346,7 @@ loop_2_start:...@@ -346,7 +346,7 @@ loop_2_start:
346loop_2_end:346loop_2_end:
347347
348 if accumulator == 15 {348 if accumulator == 15 {
349 print_str("OK\n" as string);349 print_str("OK\n");
350 }350 }
351351
352 return 0;352 return 0;
...@@ -358,7 +358,7 @@ loop_2_end:...@@ -358,7 +358,7 @@ loop_2_end:
358use "std.zig";358use "std.zig";
359359
360export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {360export 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 {
368use "std.zig";368use "std.zig";
369369
370export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {370export 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"); }
383383
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 {
390use "std.zig";390use "std.zig";
391391
392export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {392export 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 }
399399
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 }
407407
408 return 0;408 return 0;
...@@ -414,20 +414,20 @@ use "std.zig";...@@ -414,20 +414,20 @@ use "std.zig";
414414
415export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {415export 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"); }
429429
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}
579fn test_foo(foo : Foo) {579fn 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;
590var g2 : i32;590var g2 : i32;
591591
592export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {592export 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");