authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-17 00:56:35-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-17 00:56:35-04:00
log99fc2bd4ddbe36994153f6426f0001d338e90bef
treee5f2be82ac4ae7793212d218ff20422912fd5d32
parentb73307befb49dd3b131d99ecf1c7f3fb54578ec8
parent942d384831196acf24868c32ef84409b05441960

Merge remote-tracking branch 'origin/master' into pointer-reform


6 files changed, 215 insertions(+), 53 deletions(-)

src/target.cpp+1-1
......@@ -702,6 +702,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
702702 case OsLinux:
703703 case OsMacOSX:
704704 case OsZen:
705 case OsOpenBSD:
705706 switch (id) {
706707 case CIntTypeShort:
707708 case CIntTypeUShort:
......@@ -742,7 +743,6 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
742743 case OsKFreeBSD:
743744 case OsLv2:
744745 case OsNetBSD:
745 case OsOpenBSD:
746746 case OsSolaris:
747747 case OsHaiku:
748748 case OsMinix:
std/fmt/index.zig+58-29
......@@ -26,6 +26,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
2626 Buf,
2727 BufWidth,
2828 Bytes,
29 BytesBase,
2930 BytesWidth,
3031 };
3132
......@@ -97,6 +98,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
9798 },
9899 'B' => {
99100 width = 0;
101 radix = 1000;
100102 state = State.Bytes;
101103 },
102104 else => @compileError("Unknown format character: " ++ []u8{c}),
......@@ -212,7 +214,24 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
212214 },
213215 State.Bytes => switch (c) {
214216 '}' => {
215 try formatBytes(args[next_arg], 0, context, Errors, output);
217 try formatBytes(args[next_arg], 0, radix, context, Errors, output);
218 next_arg += 1;
219 state = State.Start;
220 start_index = i + 1;
221 },
222 'i' => {
223 radix = 1024;
224 state = State.BytesBase;
225 },
226 '0' ... '9' => {
227 width_start = i;
228 state = State.BytesWidth;
229 },
230 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
231 },
232 State.BytesBase => switch (c) {
233 '}' => {
234 try formatBytes(args[next_arg], 0, radix, context, Errors, output);
216235 next_arg += 1;
217236 state = State.Start;
218237 start_index = i + 1;
......@@ -226,7 +245,7 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
226245 State.BytesWidth => switch (c) {
227246 '}' => {
228247 width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
229 try formatBytes(args[next_arg], width, context, Errors, output);
248 try formatBytes(args[next_arg], width, radix, context, Errors, output);
230249 next_arg += 1;
231250 state = State.Start;
232251 start_index = i + 1;
......@@ -543,7 +562,7 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com
543562 }
544563}
545564
546pub fn formatBytes(value: var, width: ?usize,
565pub fn formatBytes(value: var, width: ?usize, comptime radix: usize,
547566 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
548567{
549568 if (value == 0) {
......@@ -551,16 +570,26 @@ pub fn formatBytes(value: var, width: ?usize,
551570 }
552571
553572 const mags = " KMGTPEZY";
554 const magnitude = math.min(math.log2(value) / 10, mags.len - 1);
555 const new_value = f64(value) / math.pow(f64, 1024, f64(magnitude));
573 const magnitude = switch (radix) {
574 1000 => math.min(math.log2(value) / comptime math.log2(1000), mags.len - 1),
575 1024 => math.min(math.log2(value) / 10, mags.len - 1),
576 else => unreachable,
577 };
578 const new_value = f64(value) / math.pow(f64, f64(radix), f64(magnitude));
556579 const suffix = mags[magnitude];
557580
558581 try formatFloatDecimal(new_value, width, context, Errors, output);
559582
560 if (suffix != ' ') {
561 try output(context, (&suffix)[0..1]);
583 if (suffix == ' ') {
584 return output(context, "B");
562585 }
563 return output(context, "B");
586
587 const buf = switch (radix) {
588 1000 => []u8 { suffix, 'B' },
589 1024 => []u8 { suffix, 'i', 'B' },
590 else => unreachable,
591 };
592 return output(context, buf);
564593}
565594
566595pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
......@@ -773,41 +802,27 @@ test "parse unsigned comptime" {
773802
774803test "fmt.format" {
775804 {
776 var buf1: [32]u8 = undefined;
777805 const value: ?i32 = 1234;
778 const result = try bufPrint(buf1[0..], "nullable: {}\n", value);
779 assert(mem.eql(u8, result, "nullable: 1234\n"));
806 try testFmt("nullable: 1234\n", "nullable: {}\n", value);
780807 }
781808 {
782 var buf1: [32]u8 = undefined;
783809 const value: ?i32 = null;
784 const result = try bufPrint(buf1[0..], "nullable: {}\n", value);
785 assert(mem.eql(u8, result, "nullable: null\n"));
810 try testFmt("nullable: null\n", "nullable: {}\n", value);
786811 }
787812 {
788 var buf1: [32]u8 = undefined;
789813 const value: error!i32 = 1234;
790 const result = try bufPrint(buf1[0..], "error union: {}\n", value);
791 assert(mem.eql(u8, result, "error union: 1234\n"));
814 try testFmt("error union: 1234\n", "error union: {}\n", value);
792815 }
793816 {
794 var buf1: [32]u8 = undefined;
795817 const value: error!i32 = error.InvalidChar;
796 const result = try bufPrint(buf1[0..], "error union: {}\n", value);
797 assert(mem.eql(u8, result, "error union: error.InvalidChar\n"));
818 try testFmt("error union: error.InvalidChar\n", "error union: {}\n", value);
798819 }
799820 {
800 var buf1: [32]u8 = undefined;
801821 const value: u3 = 0b101;
802 const result = try bufPrint(buf1[0..], "u3: {}\n", value);
803 assert(mem.eql(u8, result, "u3: 5\n"));
804 }
805 {
806 var buf1: [32]u8 = undefined;
807 const value: usize = 63 * 1024 * 1024;
808 const result = try bufPrint(buf1[0..], "file size: {B}\n", value);
809 assert(mem.eql(u8, result, "file size: 63MB\n"));
822 try testFmt("u3: 5\n", "u3: {}\n", value);
810823 }
824 try testFmt("file size: 63MiB\n", "file size: {Bi}\n", usize(63 * 1024 * 1024));
825 try testFmt("file size: 66.06MB\n", "file size: {B2}\n", usize(63 * 1024 * 1024));
811826 {
812827 // Dummy field because of https://github.com/zig-lang/zig/issues/557.
813828 const Struct = struct {
......@@ -1025,6 +1040,20 @@ test "fmt.format" {
10251040 }
10261041}
10271042
1043fn testFmt(expected: []const u8, comptime template: []const u8, args: ...) !void {
1044 var buf: [100]u8 = undefined;
1045 const result = try bufPrint(buf[0..], template, args);
1046 if (mem.eql(u8, result, expected))
1047 return;
1048
1049 std.debug.warn("\n====== expected this output: =========\n");
1050 std.debug.warn("{}", expected);
1051 std.debug.warn("\n======== instead found this: =========\n");
1052 std.debug.warn("{}", result);
1053 std.debug.warn("\n======================================\n");
1054 return error.TestFailed;
1055}
1056
10281057pub fn trim(buf: []const u8) []const u8 {
10291058 var start: usize = 0;
10301059 while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) {}
std/segmented_list.zig+10-6
......@@ -294,21 +294,25 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
294294
295295 return &it.list.dynamic_segments[it.shelf_index][it.box_index];
296296 }
297
298 pub fn set(it: &Iterator, index: usize) void {
299 it.index = index;
300 if (index < prealloc_item_count) return;
301 it.shelf_index = shelfIndex(index);
302 it.box_index = boxIndex(index, it.shelf_index);
303 it.shelf_size = shelfSize(it.shelf_index);
304 }
297305 };
298306
299307 pub fn iterator(self: &Self, start_index: usize) Iterator {
300308 var it = Iterator{
301309 .list = self,
302 .index = start_index,
310 .index = undefined,
303311 .shelf_index = undefined,
304312 .box_index = undefined,
305313 .shelf_size = undefined,
306314 };
307 if (start_index >= prealloc_item_count) {
308 it.shelf_index = shelfIndex(start_index);
309 it.box_index = boxIndex(start_index, it.shelf_index);
310 it.shelf_size = shelfSize(it.shelf_index);
311 }
315 it.set(start_index);
312316 return it;
313317 }
314318 };
std/zig/parse.zig+9-1
......@@ -927,6 +927,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
927927 continue;
928928 },
929929 State.Else => |dest| {
930 const old_index = tok_it.index;
931 var need_index_restore = false;
932 while (try eatLineComment(arena, &tok_it, &tree)) |_| {
933 need_index_restore = true;
934 }
930935 if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {
931936 const node = try arena.construct(ast.Node.Else{
932937 .base = ast.Node{ .id = ast.Node.Id.Else },
......@@ -940,6 +945,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
940945 try stack.append(State{ .Payload = OptionalCtx{ .Optional = &node.payload } });
941946 continue;
942947 } else {
948 if (need_index_restore) {
949 tok_it.set(old_index);
950 }
943951 continue;
944952 }
945953 },
......@@ -1297,7 +1305,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
12971305 },
12981306
12991307 State.SwitchCaseCommaOrEnd => |list_state| {
1300 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) {
1308 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {
13011309 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
13021310 (list_state.ptr).* = end;
13031311 continue;
std/zig/parser_test.zig+92
......@@ -1,3 +1,95 @@
1test "zig fmt: comment after if before another if" {
2 try testCanonical(
3 \\test "aoeu" {
4 \\ if (x) {
5 \\ foo();
6 \\ }
7 \\ // comment
8 \\ if (x) {
9 \\ bar();
10 \\ }
11 \\}
12 \\
13 );
14}
15
16test "zig fmt: line comment between if block and else keyword" {
17 try testTransform(
18 \\test "aoeu" {
19 \\ // cexp(finite|nan +- i inf|nan) = nan + i nan
20 \\ if ((hx & 0x7fffffff) != 0x7f800000) {
21 \\ return Complex(f32).new(y - y, y - y);
22 \\ }
23 \\ // cexp(-inf +- i inf|nan) = 0 + i0
24 \\ else if (hx & 0x80000000 != 0) {
25 \\ return Complex(f32).new(0, 0);
26 \\ }
27 \\ // cexp(+inf +- i inf|nan) = inf + i nan
28 \\ // another comment
29 \\ else {
30 \\ return Complex(f32).new(x, y - y);
31 \\ }
32 \\}
33 ,
34 \\test "aoeu" {
35 \\ // cexp(finite|nan +- i inf|nan) = nan + i nan
36 \\ if ((hx & 0x7fffffff) != 0x7f800000) {
37 \\ return Complex(f32).new(y - y, y - y);
38 \\ } // cexp(-inf +- i inf|nan) = 0 + i0
39 \\ else if (hx & 0x80000000 != 0) {
40 \\ return Complex(f32).new(0, 0);
41 \\ } // cexp(+inf +- i inf|nan) = inf + i nan
42 \\ // another comment
43 \\ else {
44 \\ return Complex(f32).new(x, y - y);
45 \\ }
46 \\}
47 \\
48 );
49}
50
51test "zig fmt: same line comments in expression" {
52 try testCanonical(
53 \\test "aoeu" {
54 \\ const x = ( // a
55 \\ 0 // b
56 \\ ); // c
57 \\}
58 \\
59 );
60}
61
62test "zig fmt: add comma on last switch prong" {
63 try testTransform(
64 \\test "aoeu" {
65 \\switch (self.init_arg_expr) {
66 \\ InitArg.Type => |t| { },
67 \\ InitArg.None,
68 \\ InitArg.Enum => { }
69 \\}
70 \\ switch (self.init_arg_expr) {
71 \\ InitArg.Type => |t| { },
72 \\ InitArg.None,
73 \\ InitArg.Enum => { }//line comment
74 \\ }
75 \\}
76 ,
77 \\test "aoeu" {
78 \\ switch (self.init_arg_expr) {
79 \\ InitArg.Type => |t| {},
80 \\ InitArg.None,
81 \\ InitArg.Enum => {},
82 \\ }
83 \\ switch (self.init_arg_expr) {
84 \\ InitArg.Type => |t| {},
85 \\ InitArg.None,
86 \\ InitArg.Enum => {}, //line comment
87 \\ }
88 \\}
89 \\
90 );
91}
92
193test "zig fmt: same-line doc comment on variable declaration" {
294 try testTransform(
395 \\pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space
std/zig/render.zig+45-16
......@@ -81,7 +81,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i
8181 }
8282 try stream.print("{}: ", tree.tokenSlice(field.name_token));
8383 try renderExpression(allocator, stream, tree, indent, field.type_expr);
84 try renderToken(tree, stream, field.lastToken() + 1, indent, true);
84 try renderToken(tree, stream, field.lastToken() + 1, indent, true, true);
8585 },
8686 ast.Node.Id.UnionTag => {
8787 const tag = @fieldParentPtr(ast.Node.UnionTag, "base", decl);
......@@ -514,9 +514,9 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
514514 ast.Node.Id.GroupedExpression => {
515515 const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base);
516516
517 try stream.write("(");
517 try renderToken(tree, stream, grouped_expr.lparen, indent, false, false);
518518 try renderExpression(allocator, stream, tree, indent, grouped_expr.expr);
519 try stream.write(")");
519 try renderToken(tree, stream, grouped_expr.rparen, indent, false, false);
520520 },
521521
522522 ast.Node.Id.FieldInitializer => {
......@@ -528,7 +528,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
528528
529529 ast.Node.Id.IntegerLiteral => {
530530 const integer_literal = @fieldParentPtr(ast.Node.IntegerLiteral, "base", base);
531 try stream.print("{}", tree.tokenSlice(integer_literal.token));
531 try renderToken(tree, stream, integer_literal.token, indent, false, false);
532532 },
533533 ast.Node.Id.FloatLiteral => {
534534 const float_literal = @fieldParentPtr(ast.Node.FloatLiteral, "base", base);
......@@ -536,7 +536,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
536536 },
537537 ast.Node.Id.StringLiteral => {
538538 const string_literal = @fieldParentPtr(ast.Node.StringLiteral, "base", base);
539 try stream.print("{}", tree.tokenSlice(string_literal.token));
539 try renderToken(tree, stream, string_literal.token, indent, false, false);
540540 },
541541 ast.Node.Id.CharLiteral => {
542542 const char_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base);
......@@ -830,7 +830,20 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
830830 }
831831
832832 try renderExpression(allocator, stream, tree, indent, switch_case.expr);
833 try renderToken(tree, stream, switch_case.lastToken() + 1, indent, true);
833 {
834 // Handle missing comma after last switch case
835 var index = switch_case.lastToken() + 1;
836 switch (tree.tokens.at(index).id) {
837 Token.Id.RBrace => {
838 try stream.write(",");
839 },
840 Token.Id.LineComment => {
841 try stream.write(", ");
842 try renderToken(tree, stream, index, indent, true, true);
843 },
844 else => try renderToken(tree, stream, index, indent, true, true),
845 }
846 }
834847 },
835848 ast.Node.Id.SwitchElse => {
836849 const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base);
......@@ -838,6 +851,15 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
838851 },
839852 ast.Node.Id.Else => {
840853 const else_node = @fieldParentPtr(ast.Node.Else, "base", base);
854
855 var prev_tok_index = else_node.else_token - 1;
856 while (tree.tokens.at(prev_tok_index).id == Token.Id.LineComment) : (prev_tok_index -= 1) { }
857 prev_tok_index += 1;
858 while (prev_tok_index < else_node.else_token) : (prev_tok_index += 1) {
859 try stream.print("{}\n", tree.tokenSlice(prev_tok_index));
860 try stream.writeByteNTimes(' ', indent);
861 }
862
841863 try stream.print("{}", tree.tokenSlice(else_node.else_token));
842864
843865 const block_body = switch (else_node.body.id) {
......@@ -959,7 +981,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
959981 try stream.print("{} (", tree.tokenSlice(if_node.if_token));
960982
961983 try renderExpression(allocator, stream, tree, indent, if_node.condition);
962 try renderToken(tree, stream, if_node.condition.lastToken() + 1, indent, false);
984 try renderToken(tree, stream, if_node.condition.lastToken() + 1, indent, false, true);
963985
964986 if (if_node.payload) |payload| {
965987 try renderExpression(allocator, stream, tree, indent, payload);
......@@ -1118,11 +1140,11 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
11181140
11191141fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, var_decl: &ast.Node.VarDecl) (@typeOf(stream).Child.Error || Error)!void {
11201142 if (var_decl.visib_token) |visib_token| {
1121 try stream.print("{} ", tree.tokenSlice(visib_token));
1143 try renderToken(tree, stream, visib_token, indent, false, true);
11221144 }
11231145
11241146 if (var_decl.extern_export_token) |extern_export_token| {
1125 try stream.print("{} ", tree.tokenSlice(extern_export_token));
1147 try renderToken(tree, stream, extern_export_token, indent, false, true);
11261148
11271149 if (var_decl.lib_name) |lib_name| {
11281150 try renderExpression(allocator, stream, tree, indent, lib_name);
......@@ -1131,10 +1153,11 @@ fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent
11311153 }
11321154
11331155 if (var_decl.comptime_token) |comptime_token| {
1134 try stream.print("{} ", tree.tokenSlice(comptime_token));
1156 try renderToken(tree, stream, comptime_token, indent, false, true);
11351157 }
11361158
1137 try stream.print("{} {}", tree.tokenSlice(var_decl.mut_token), tree.tokenSlice(var_decl.name_token));
1159 try renderToken(tree, stream, var_decl.mut_token, indent, false, true);
1160 try renderToken(tree, stream, var_decl.name_token, indent, false, false);
11381161
11391162 if (var_decl.type_node) |type_node| {
11401163 try stream.write(": ");
......@@ -1153,14 +1176,14 @@ fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent
11531176 try renderExpression(allocator, stream, tree, indent, init_node);
11541177 }
11551178
1156 try renderToken(tree, stream, var_decl.semicolon_token, indent, true);
1179 try renderToken(tree, stream, var_decl.semicolon_token, indent, true, false);
11571180}
11581181
11591182fn maybeRenderSemicolon(stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node) (@typeOf(stream).Child.Error || Error)!void {
11601183 if (base.requireSemiColon()) {
11611184 const semicolon_index = base.lastToken() + 1;
11621185 assert(tree.tokens.at(semicolon_index).id == Token.Id.Semicolon);
1163 try renderToken(tree, stream, semicolon_index, indent, true);
1186 try renderToken(tree, stream, semicolon_index, indent, true, true);
11641187 }
11651188}
11661189
......@@ -1195,7 +1218,7 @@ fn renderStatement(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, inde
11951218 }
11961219}
11971220
1198fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, line_break: bool) (@typeOf(stream).Child.Error || Error)!void {
1221fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, line_break: bool, space: bool) (@typeOf(stream).Child.Error || Error)!void {
11991222 const token = tree.tokens.at(token_index);
12001223 try stream.write(tree.tokenSlicePtr(token));
12011224
......@@ -1206,13 +1229,19 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent
12061229 try stream.print(" {}", tree.tokenSlicePtr(next_token));
12071230 if (!line_break) {
12081231 try stream.write("\n");
1209 try stream.writeByteNTimes(' ', indent + indent_delta);
1232
1233 const after_comment_token = tree.tokens.at(token_index + 2);
1234 const next_line_indent = switch (after_comment_token.id) {
1235 Token.Id.RParen, Token.Id.RBrace, Token.Id.RBracket => indent,
1236 else => indent + indent_delta,
1237 };
1238 try stream.writeByteNTimes(' ', next_line_indent);
12101239 return;
12111240 }
12121241 }
12131242 }
12141243
1215 if (!line_break) {
1244 if (!line_break and space) {
12161245 try stream.writeByte(' ');
12171246 }
12181247}