| author | |
| committer | |
| log | a43fdc1620fa24c8c606f748505766bfd53d1049 |
| tree | a421b5989d7ec14361f16a5790faf946d21a3bb9 |
| parent | 4172c2916684655a9742de99384be8110922ed07 |
- Forward declare int builtins, so the definitions aren't assumed incorrectly
- Add define to handle MSVC not support static const in function parameter array lengths
- Fixup several spots where int128 support was assumed.
- Support zig_align
- Support zig_export
- Stub out some missing non-builtin functions
- Added StringLiteral to automatically split string literals when they get to 16380 in size,
which is the maxmimum pre-concatenation string literal size on MSVC.2 files changed, 151 insertions(+), 57 deletions(-)
lib/zig.h+38-18| ... | @@ -38,6 +38,12 @@ typedef char bool; | ... | @@ -38,6 +38,12 @@ typedef char bool; |
| 38 | #define zig_threadlocal zig_threadlocal_unavailable | 38 | #define zig_threadlocal zig_threadlocal_unavailable |
| 39 | #endif | 39 | #endif |
| 40 | 40 | ||
| 41 | #if _MSC_VER | ||
| 42 | #define zig_const_arr | ||
| 43 | #else | ||
| 44 | #define zig_const_arr static const | ||
| 45 | #endif | ||
| 46 | |||
| 41 | #if zig_has_attribute(naked) || defined(__GNUC__) | 47 | #if zig_has_attribute(naked) || defined(__GNUC__) |
| 42 | #define zig_naked __attribute__((naked)) | 48 | #define zig_naked __attribute__((naked)) |
| 43 | #elif defined(_MSC_VER) | 49 | #elif defined(_MSC_VER) |
| ... | @@ -65,7 +71,7 @@ typedef char bool; | ... | @@ -65,7 +71,7 @@ typedef char bool; |
| 65 | #elif zig_has_attribute(aligned) | 71 | #elif zig_has_attribute(aligned) |
| 66 | #define zig_align(alignment) __attribute__((aligned(alignment))) | 72 | #define zig_align(alignment) __attribute__((aligned(alignment))) |
| 67 | #elif _MSC_VER | 73 | #elif _MSC_VER |
| 68 | #define zig_align zig_align_unavailable | 74 | #define zig_align(alignment) __declspec(align(alignment)) |
| 69 | #else | 75 | #else |
| 70 | #define zig_align zig_align_unavailable | 76 | #define zig_align zig_align_unavailable |
| 71 | #endif | 77 | #endif |
| ... | @@ -73,7 +79,8 @@ typedef char bool; | ... | @@ -73,7 +79,8 @@ typedef char bool; |
| 73 | #if zig_has_attribute(aligned) | 79 | #if zig_has_attribute(aligned) |
| 74 | #define zig_align_fn(alignment) __attribute__((aligned(alignment))) | 80 | #define zig_align_fn(alignment) __attribute__((aligned(alignment))) |
| 75 | #elif _MSC_VER | 81 | #elif _MSC_VER |
| 76 | #define zig_align_fn zig_align_fn_unavailable | 82 | // TODO: Figure out how to do this under MSVC |
| 83 | #define zig_align_fn(alignment) | ||
| 77 | #else | 84 | #else |
| 78 | #define zig_align_fn zig_align_fn_unavailable | 85 | #define zig_align_fn zig_align_fn_unavailable |
| 79 | #endif | 86 | #endif |
| ... | @@ -92,6 +99,9 @@ typedef char bool; | ... | @@ -92,6 +99,9 @@ typedef char bool; |
| 92 | 99 | ||
| 93 | #if zig_has_attribute(alias) | 100 | #if zig_has_attribute(alias) |
| 94 | #define zig_export(sig, symbol, name) zig_extern sig __attribute__((alias(symbol))) | 101 | #define zig_export(sig, symbol, name) zig_extern sig __attribute__((alias(symbol))) |
| 102 | #elif _MSC_VER | ||
| 103 | #define zig_export(sig, symbol, name) sig;\ | ||
| 104 | __pragma(comment(linker, "/alternatename:" name "=" symbol )) | ||
| 95 | #else | 105 | #else |
| 96 | #define zig_export(sig, symbol, name) __asm(name " = " symbol) | 106 | #define zig_export(sig, symbol, name) __asm(name " = " symbol) |
| 97 | #endif | 107 | #endif |
| ... | @@ -1327,13 +1337,15 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) { | ... | @@ -1327,13 +1337,15 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1327 | return res; | 1337 | return res; |
| 1328 | } | 1338 | } |
| 1329 | 1339 | ||
| 1330 | static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) { | 1340 | // TODO: Implement |
| 1331 | return zig_sub_i128(zig_div_trunc_i128(lhs, rhs), (((lhs.hi ^ rhs.hi) & zig_rem_i128(lhs, rhs).hi) < zig_as_i64(0)) ? zig_as_i128(0, 1) : zig_as_i128(0, 0)); | 1341 | static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs); |
| 1332 | } | 1342 | |
| 1343 | // TODO: Implement | ||
| 1344 | static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs); | ||
| 1333 | 1345 | ||
| 1334 | static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) { | 1346 | static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1335 | zig_i128 rem = zig_rem_i128(lhs, rhs); | 1347 | zig_i128 rem = zig_rem_i128(lhs, rhs); |
| 1336 | return rem + (((lhs.hi ^ rhs.hi) & rem.hi) < zig_as_i64(0) ? rhs : zig_as_i128(0, 0)); | 1348 | return zig_add_i128(rem, (((lhs.hi ^ rhs.hi) & rem.hi) < zig_as_i64(0) ? rhs : zig_as_i128(0, 0))); |
| 1337 | } | 1349 | } |
| 1338 | 1350 | ||
| 1339 | #endif /* zig_has_int128 */ | 1351 | #endif /* zig_has_int128 */ |
| ... | @@ -1358,7 +1370,7 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) { | ... | @@ -1358,7 +1370,7 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1358 | } | 1370 | } |
| 1359 | 1371 | ||
| 1360 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, zig_u8 rhs) { | 1372 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, zig_u8 rhs) { |
| 1361 | zig_i128 sign_mask = zig_cmp_i128(lhs, zig_as_i128(0, 0)) < zig_as_i32(0) ? -zig_as_i128(0, 1) : zig_as_i128(0, 0); | 1373 | zig_i128 sign_mask = zig_cmp_i128(lhs, zig_as_i128(0, 0)) < zig_as_i32(0) ? zig_sub_i128(zig_as_i128(0, 0), zig_as_i128(0, 1)) : zig_as_i128(0, 0); |
| 1362 | return zig_xor_i128(zig_bitcast_i128(zig_shr_u128(zig_bitcast_u128(zig_xor_i128(lhs, sign_mask)), rhs)), sign_mask); | 1374 | return zig_xor_i128(zig_bitcast_i128(zig_shr_u128(zig_bitcast_u128(zig_xor_i128(lhs, sign_mask)), rhs)), sign_mask); |
| 1363 | } | 1375 | } |
| 1364 | 1376 | ||
| ... | @@ -1375,7 +1387,7 @@ static inline zig_u128 zig_shlw_u128(zig_u128 lhs, zig_u8 rhs, zig_u8 bits) { | ... | @@ -1375,7 +1387,7 @@ static inline zig_u128 zig_shlw_u128(zig_u128 lhs, zig_u8 rhs, zig_u8 bits) { |
| 1375 | } | 1387 | } |
| 1376 | 1388 | ||
| 1377 | static inline zig_i128 zig_shlw_i128(zig_i128 lhs, zig_u8 rhs, zig_u8 bits) { | 1389 | static inline zig_i128 zig_shlw_i128(zig_i128 lhs, zig_u8 rhs, zig_u8 bits) { |
| 1378 | return zig_wrap_i128(zig_bitcast_i128(zig_shl_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits); | 1390 | return zig_wrap_i128(zig_bitcast_i128(zig_shl_u128(zig_bitcast_u128(lhs), rhs)), bits); |
| 1379 | } | 1391 | } |
| 1380 | 1392 | ||
| 1381 | static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { | 1393 | static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| ... | @@ -1394,6 +1406,9 @@ static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { | ... | @@ -1394,6 +1406,9 @@ static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1394 | return zig_wrap_i128(zig_bitcast_i128(zig_sub_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits); | 1406 | return zig_wrap_i128(zig_bitcast_i128(zig_sub_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits); |
| 1395 | } | 1407 | } |
| 1396 | 1408 | ||
| 1409 | // TODO: Implement | ||
| 1410 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs); | ||
| 1411 | |||
| 1397 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { | 1412 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1398 | return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits); | 1413 | return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits); |
| 1399 | } | 1414 | } |
| ... | @@ -1496,15 +1511,15 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_ | ... | @@ -1496,15 +1511,15 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_ |
| 1496 | 1511 | ||
| 1497 | #else /* zig_has_int128 */ | 1512 | #else /* zig_has_int128 */ |
| 1498 | 1513 | ||
| 1499 | static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs) { | 1514 | /* static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs) { */ |
| 1500 | return zig_addo_u64(&res->hi, lhs.hi, rhs.hi, UINT64_MAX) | | 1515 | /* return zig_addo_u64(&res->hi, lhs.hi, rhs.hi, UINT64_MAX) | */ |
| 1501 | zig_addo_u64(&res->hi, res->hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT64_MAX)); | 1516 | /* zig_addo_u64(&res->hi, res->hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT64_MAX)); */ |
| 1502 | } | 1517 | /* } */ |
| 1503 | 1518 | ||
| 1504 | static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs) { | 1519 | /* static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs) { */ |
| 1505 | return zig_subo_u64(&res->hi, lhs.hi, rhs.hi, UINT64_MAX) | | 1520 | /* return zig_subo_u64(&res->hi, lhs.hi, rhs.hi, UINT64_MAX) | */ |
| 1506 | zig_subo_u64(&res->hi, res->hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT64_MAX)); | 1521 | /* zig_subo_u64(&res->hi, res->hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT64_MAX)); */ |
| 1507 | } | 1522 | /* } */ |
| 1508 | 1523 | ||
| 1509 | #endif /* zig_has_int128 */ | 1524 | #endif /* zig_has_int128 */ |
| 1510 | 1525 | ||
| ... | @@ -1512,7 +1527,12 @@ static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { | ... | @@ -1512,7 +1527,12 @@ static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1512 | zig_u128 res; | 1527 | zig_u128 res; |
| 1513 | if (zig_cmp_u128(rhs, zig_as_u128(0, bits)) >= zig_as_i32(0)) | 1528 | if (zig_cmp_u128(rhs, zig_as_u128(0, bits)) >= zig_as_i32(0)) |
| 1514 | return zig_cmp_u128(lhs, zig_as_u128(0, 0)) != zig_as_i32(0) ? zig_maxInt(u128, bits) : lhs; | 1529 | return zig_cmp_u128(lhs, zig_as_u128(0, 0)) != zig_as_i32(0) ? zig_maxInt(u128, bits) : lhs; |
| 1530 | |||
| 1531 | #if zig_has_int128 | ||
| 1515 | return zig_shlo_u128(&res, lhs, (zig_u8)rhs, bits) ? zig_maxInt(u128, bits) : res; | 1532 | return zig_shlo_u128(&res, lhs, (zig_u8)rhs, bits) ? zig_maxInt(u128, bits) : res; |
| 1533 | #else | ||
| 1534 | return zig_shlo_u128(&res, lhs, (zig_u8)rhs.lo, bits) ? zig_maxInt(u128, bits) : res; | ||
| 1535 | #endif | ||
| 1516 | } | 1536 | } |
| 1517 | 1537 | ||
| 1518 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { | 1538 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| ... | @@ -1593,7 +1613,7 @@ static inline zig_u128 zig_byte_swap_u128(zig_u128 val, zig_u8 bits) { | ... | @@ -1593,7 +1613,7 @@ static inline zig_u128 zig_byte_swap_u128(zig_u128 val, zig_u8 bits) { |
| 1593 | } | 1613 | } |
| 1594 | 1614 | ||
| 1595 | static inline zig_i128 zig_byte_swap_i128(zig_i128 val, zig_u8 bits) { | 1615 | static inline zig_i128 zig_byte_swap_i128(zig_i128 val, zig_u8 bits) { |
| 1596 | return zig_byte_swap_u128(zig_bitcast_u128(val), bits); | 1616 | return zig_bitcast_i128(zig_byte_swap_u128(zig_bitcast_u128(val), bits)); |
| 1597 | } | 1617 | } |
| 1598 | 1618 | ||
| 1599 | static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, zig_u8 bits) { | 1619 | static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, zig_u8 bits) { |
| ... | @@ -1603,7 +1623,7 @@ static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, zig_u8 bits) { | ... | @@ -1603,7 +1623,7 @@ static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, zig_u8 bits) { |
| 1603 | } | 1623 | } |
| 1604 | 1624 | ||
| 1605 | static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) { | 1625 | static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) { |
| 1606 | return zig_bit_reverse_u128(zig_bitcast_u128(val), bits); | 1626 | return zig_bitcast_i128(zig_bit_reverse_u128(zig_bitcast_u128(val), bits)); |
| 1607 | } | 1627 | } |
| 1608 | 1628 | ||
| 1609 | /* ========================= Floating Point Support ========================= */ | 1629 | /* ========================= Floating Point Support ========================= */ |
src/codegen/c.zig+113-39| ... | @@ -848,12 +848,13 @@ pub const DeclGen = struct { | ... | @@ -848,12 +848,13 @@ pub const DeclGen = struct { |
| 848 | 848 | ||
| 849 | const ai = ty.arrayInfo(); | 849 | const ai = ty.arrayInfo(); |
| 850 | if (ai.elem_type.eql(Type.u8, dg.module)) { | 850 | if (ai.elem_type.eql(Type.u8, dg.module)) { |
| 851 | try writer.writeByte('"'); | 851 | var literal = stringLiteral(writer); |
| 852 | try literal.start(); | ||
| 852 | const c_len = ty.arrayLenIncludingSentinel(); | 853 | const c_len = ty.arrayLenIncludingSentinel(); |
| 853 | var index: usize = 0; | 854 | var index: usize = 0; |
| 854 | while (index < c_len) : (index += 1) | 855 | while (index < c_len) : (index += 1) |
| 855 | try writeStringLiteralChar(writer, 0xaa); | 856 | try literal.writeChar(0xaa); |
| 856 | return writer.writeByte('"'); | 857 | return literal.end(); |
| 857 | } else { | 858 | } else { |
| 858 | try writer.writeByte('{'); | 859 | try writer.writeByte('{'); |
| 859 | const c_len = ty.arrayLenIncludingSentinel(); | 860 | const c_len = ty.arrayLenIncludingSentinel(); |
| ... | @@ -1060,23 +1061,40 @@ pub const DeclGen = struct { | ... | @@ -1060,23 +1061,40 @@ pub const DeclGen = struct { |
| 1060 | defer arena.deinit(); | 1061 | defer arena.deinit(); |
| 1061 | const arena_allocator = arena.allocator(); | 1062 | const arena_allocator = arena.allocator(); |
| 1062 | 1063 | ||
| 1064 | // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal | ||
| 1065 | const max_string_initializer_len = 65535; | ||
| 1066 | |||
| 1063 | const ai = ty.arrayInfo(); | 1067 | const ai = ty.arrayInfo(); |
| 1064 | if (ai.elem_type.eql(Type.u8, dg.module)) { | 1068 | if (ai.elem_type.eql(Type.u8, dg.module)) { |
| 1065 | try writer.writeByte('"'); | 1069 | if (ai.len <= max_string_initializer_len) { |
| 1066 | var index: usize = 0; | 1070 | var literal = stringLiteral(writer); |
| 1067 | while (index < ai.len) : (index += 1) { | 1071 | try literal.start(); |
| 1068 | const elem_val = try val.elemValue(dg.module, arena_allocator, index); | 1072 | var index: usize = 0; |
| 1069 | const elem_val_u8 = if (elem_val.isUndef()) | 1073 | while (index < ai.len) : (index += 1) { |
| 1070 | undefPattern(u8) | 1074 | const elem_val = try val.elemValue(dg.module, arena_allocator, index); |
| 1071 | else | 1075 | const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(target)); |
| 1072 | @intCast(u8, elem_val.toUnsignedInt(target)); | 1076 | try literal.writeChar(elem_val_u8); |
| 1073 | try writeStringLiteralChar(writer, elem_val_u8); | 1077 | } |
| 1074 | } | 1078 | if (ai.sentinel) |s| { |
| 1075 | if (ai.sentinel) |s| { | 1079 | const s_u8 = @intCast(u8, s.toUnsignedInt(target)); |
| 1076 | const s_u8 = @intCast(u8, s.toUnsignedInt(target)); | 1080 | try literal.writeChar(s_u8); |
| 1077 | try writeStringLiteralChar(writer, s_u8); | 1081 | } |
| 1082 | try literal.end(); | ||
| 1083 | } else { | ||
| 1084 | try writer.writeByte('{'); | ||
| 1085 | var index: usize = 0; | ||
| 1086 | while (index < ai.len) : (index += 1) { | ||
| 1087 | if (index != 0) try writer.writeByte(','); | ||
| 1088 | const elem_val = try val.elemValue(dg.module, arena_allocator, index); | ||
| 1089 | const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(target)); | ||
| 1090 | try writer.print("'\\x{x}'", .{ elem_val_u8 }); | ||
| 1091 | } | ||
| 1092 | if (ai.sentinel) |s| { | ||
| 1093 | if (index != 0) try writer.writeByte(','); | ||
| 1094 | try dg.renderValue(writer, ai.elem_type, s, .Initializer); | ||
| 1095 | } | ||
| 1096 | try writer.writeByte('}'); | ||
| 1078 | } | 1097 | } |
| 1079 | try writer.writeByte('"'); | ||
| 1080 | } else { | 1098 | } else { |
| 1081 | try writer.writeByte('{'); | 1099 | try writer.writeByte('{'); |
| 1082 | var index: usize = 0; | 1100 | var index: usize = 0; |
| ... | @@ -2134,7 +2152,7 @@ pub const DeclGen = struct { | ... | @@ -2134,7 +2152,7 @@ pub const DeclGen = struct { |
| 2134 | const c_len_val = Value.initPayload(&c_len_pl.base); | 2152 | const c_len_val = Value.initPayload(&c_len_pl.base); |
| 2135 | 2153 | ||
| 2136 | try suffix_writer.writeByte('['); | 2154 | try suffix_writer.writeByte('['); |
| 2137 | if (mutability == .ConstArgument and depth == 0) try suffix_writer.writeAll("static const "); | 2155 | if (mutability == .ConstArgument and depth == 0) try suffix_writer.writeAll("zig_const_arr "); |
| 2138 | try suffix.writer().print("{}]", .{try dg.fmtIntLiteral(Type.usize, c_len_val)}); | 2156 | try suffix.writer().print("{}]", .{try dg.fmtIntLiteral(Type.usize, c_len_val)}); |
| 2139 | render_ty = array_info.elem_type; | 2157 | render_ty = array_info.elem_type; |
| 2140 | depth += 1; | 2158 | depth += 1; |
| ... | @@ -6793,6 +6811,68 @@ fn compilerRtAbbrev(ty: Type, target: std.Target) []const u8 { | ... | @@ -6793,6 +6811,68 @@ fn compilerRtAbbrev(ty: Type, target: std.Target) []const u8 { |
| 6793 | } else unreachable; | 6811 | } else unreachable; |
| 6794 | } | 6812 | } |
| 6795 | 6813 | ||
| 6814 | fn StringLiteral(comptime WriterType: type) type { | ||
| 6815 | // msvc has a length limit of 16380 per string literal (before concatenation) | ||
| 6816 | const max_char_len = 4; | ||
| 6817 | const max_len = 16380 - max_char_len; | ||
| 6818 | |||
| 6819 | return struct { | ||
| 6820 | cur_len: usize = 0, | ||
| 6821 | counting_writer: std.io.CountingWriter(WriterType), | ||
| 6822 | |||
| 6823 | pub const Error = WriterType.Error; | ||
| 6824 | |||
| 6825 | const Self = @This(); | ||
| 6826 | |||
| 6827 | pub fn start(self: *Self) Error!void { | ||
| 6828 | const writer = self.counting_writer.writer(); | ||
| 6829 | try writer.writeByte('\"'); | ||
| 6830 | } | ||
| 6831 | |||
| 6832 | pub fn end(self: *Self) Error!void { | ||
| 6833 | const writer = self.counting_writer.writer(); | ||
| 6834 | try writer.writeByte('\"'); | ||
| 6835 | } | ||
| 6836 | |||
| 6837 | fn writeStringLiteralChar(writer: anytype, c: u8) !void { | ||
| 6838 | switch (c) { | ||
| 6839 | 7 => try writer.writeAll("\\a"), | ||
| 6840 | 8 => try writer.writeAll("\\b"), | ||
| 6841 | '\t' => try writer.writeAll("\\t"), | ||
| 6842 | '\n' => try writer.writeAll("\\n"), | ||
| 6843 | 11 => try writer.writeAll("\\v"), | ||
| 6844 | 12 => try writer.writeAll("\\f"), | ||
| 6845 | '\r' => try writer.writeAll("\\r"), | ||
| 6846 | '"', '\'', '?', '\\' => try writer.print("\\{c}", .{c}), | ||
| 6847 | else => switch (c) { | ||
| 6848 | ' '...'~' => try writer.writeByte(c), | ||
| 6849 | else => try writer.print("\\{o:0>3}", .{c}), | ||
| 6850 | }, | ||
| 6851 | } | ||
| 6852 | } | ||
| 6853 | |||
| 6854 | pub fn writeChar(self: *Self, c: u8) Error!void { | ||
| 6855 | const writer = self.counting_writer.writer(); | ||
| 6856 | |||
| 6857 | if (self.cur_len == 0 and self.counting_writer.bytes_written > 1) | ||
| 6858 | try writer.writeAll("\"\""); | ||
| 6859 | |||
| 6860 | const len = self.counting_writer.bytes_written; | ||
| 6861 | try writeStringLiteralChar(writer, c); | ||
| 6862 | |||
| 6863 | const char_length = self.counting_writer.bytes_written - len; | ||
| 6864 | assert(char_length <= max_char_len); | ||
| 6865 | self.cur_len += char_length; | ||
| 6866 | |||
| 6867 | if (self.cur_len >= max_len) self.cur_len = 0; | ||
| 6868 | } | ||
| 6869 | }; | ||
| 6870 | } | ||
| 6871 | |||
| 6872 | fn stringLiteral(child_stream: anytype) StringLiteral(@TypeOf(child_stream)) { | ||
| 6873 | return .{ .counting_writer = std.io.countingWriter(child_stream) }; | ||
| 6874 | } | ||
| 6875 | |||
| 6796 | fn formatStringLiteral( | 6876 | fn formatStringLiteral( |
| 6797 | str: []const u8, | 6877 | str: []const u8, |
| 6798 | comptime fmt: []const u8, | 6878 | comptime fmt: []const u8, |
| ... | @@ -6800,33 +6880,18 @@ fn formatStringLiteral( | ... | @@ -6800,33 +6880,18 @@ fn formatStringLiteral( |
| 6800 | writer: anytype, | 6880 | writer: anytype, |
| 6801 | ) @TypeOf(writer).Error!void { | 6881 | ) @TypeOf(writer).Error!void { |
| 6802 | if (fmt.len != 1 or fmt[0] != 's') @compileError("Invalid fmt: " ++ fmt); | 6882 | if (fmt.len != 1 or fmt[0] != 's') @compileError("Invalid fmt: " ++ fmt); |
| 6803 | try writer.writeByte('\"'); | 6883 | |
| 6884 | var literal = stringLiteral(writer); | ||
| 6885 | try literal.start(); | ||
| 6804 | for (str) |c| | 6886 | for (str) |c| |
| 6805 | try writeStringLiteralChar(writer, c); | 6887 | try literal.writeChar(c); |
| 6806 | try writer.writeByte('\"'); | 6888 | try literal.end(); |
| 6807 | } | 6889 | } |
| 6808 | 6890 | ||
| 6809 | fn fmtStringLiteral(str: []const u8) std.fmt.Formatter(formatStringLiteral) { | 6891 | fn fmtStringLiteral(str: []const u8) std.fmt.Formatter(formatStringLiteral) { |
| 6810 | return .{ .data = str }; | 6892 | return .{ .data = str }; |
| 6811 | } | 6893 | } |
| 6812 | 6894 | ||
| 6813 | fn writeStringLiteralChar(writer: anytype, c: u8) !void { | ||
| 6814 | switch (c) { | ||
| 6815 | 7 => try writer.writeAll("\\a"), | ||
| 6816 | 8 => try writer.writeAll("\\b"), | ||
| 6817 | '\t' => try writer.writeAll("\\t"), | ||
| 6818 | '\n' => try writer.writeAll("\\n"), | ||
| 6819 | 11 => try writer.writeAll("\\v"), | ||
| 6820 | 12 => try writer.writeAll("\\f"), | ||
| 6821 | '\r' => try writer.writeAll("\\r"), | ||
| 6822 | '"', '\'', '?', '\\' => try writer.print("\\{c}", .{c}), | ||
| 6823 | else => switch (c) { | ||
| 6824 | ' '...'~' => try writer.writeByte(c), | ||
| 6825 | else => try writer.print("\\{o:0>3}", .{c}), | ||
| 6826 | }, | ||
| 6827 | } | ||
| 6828 | } | ||
| 6829 | |||
| 6830 | fn undefPattern(comptime IntType: type) IntType { | 6895 | fn undefPattern(comptime IntType: type) IntType { |
| 6831 | const int_info = @typeInfo(IntType).Int; | 6896 | const int_info = @typeInfo(IntType).Int; |
| 6832 | const UnsignedType = std.meta.Int(.unsigned, int_info.bits); | 6897 | const UnsignedType = std.meta.Int(.unsigned, int_info.bits); |
| ... | @@ -6905,7 +6970,15 @@ fn formatIntLiteral( | ... | @@ -6905,7 +6970,15 @@ fn formatIntLiteral( |
| 6905 | return writer.print("{s}_{s}", .{ abbrev, if (int.positive) "MAX" else "MIN" }); | 6970 | return writer.print("{s}_{s}", .{ abbrev, if (int.positive) "MAX" else "MIN" }); |
| 6906 | } | 6971 | } |
| 6907 | 6972 | ||
| 6908 | if (!int.positive) try writer.writeByte('-'); | 6973 | // TODO: If > 64 bit, need to use a subtract from zero fn here instead of negate |
| 6974 | if (!int.positive) { | ||
| 6975 | if (c_bits > 64) { | ||
| 6976 | try writer.print("zig_sub_{c}{d}(zig_as_{c}{d}(0, 0), ", .{ signAbbrev(int_info.signedness), c_bits, signAbbrev(int_info.signedness), c_bits }); | ||
| 6977 | } else { | ||
| 6978 | try writer.writeByte('-'); | ||
| 6979 | } | ||
| 6980 | } | ||
| 6981 | |||
| 6909 | switch (data.ty.tag()) { | 6982 | switch (data.ty.tag()) { |
| 6910 | .c_short, .c_ushort, .c_int, .c_uint, .c_long, .c_ulong, .c_longlong, .c_ulonglong => {}, | 6983 | .c_short, .c_ushort, .c_int, .c_uint, .c_long, .c_ulong, .c_longlong, .c_ulonglong => {}, |
| 6911 | else => try writer.print("zig_as_{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }), | 6984 | else => try writer.print("zig_as_{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }), |
| ... | @@ -6976,6 +7049,7 @@ fn formatIntLiteral( | ... | @@ -6976,6 +7049,7 @@ fn formatIntLiteral( |
| 6976 | .mod = data.mod, | 7049 | .mod = data.mod, |
| 6977 | }, fmt, options, writer); | 7050 | }, fmt, options, writer); |
| 6978 | 7051 | ||
| 7052 | if (!int.positive and c_bits > 64) try writer.writeByte(')'); | ||
| 6979 | return writer.writeByte(')'); | 7053 | return writer.writeByte(')'); |
| 6980 | } | 7054 | } |
| 6981 | 7055 |