authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-26 16:37:55-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-26 16:37:55-04:00
log0ab888c639dffcc48bc08a6ff186aa3da0ecbf74
treea094c3c1e9a38cc26e4fdf4c3cb45acd945bddcf
parent85ca611af1d7401dd336f4655a0ab15640cc8424

zig fmt: parse extra comma in asm expressions


4 files changed, 120 insertions(+), 29 deletions(-)

std/zig/ast.zig+1-1
......@@ -2071,7 +2071,7 @@ pub const Node = struct {
20712071
20722072 const OutputList = SegmentedList(&AsmOutput, 2);
20732073 const InputList = SegmentedList(&AsmInput, 2);
2074 const ClobberList = SegmentedList(&Node, 2);
2074 const ClobberList = SegmentedList(TokenIndex, 2);
20752075
20762076 pub fn iterate(self: &Asm, index: usize) ?&Node {
20772077 var i = index;
std/zig/parse.zig+5-3
......@@ -1153,9 +1153,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
11531153 continue;
11541154 },
11551155 State.AsmClobberItems => |items| {
1156 stack.append(State{ .AsmClobberItems = items }) catch unreachable;
1157 try stack.append(State{ .IfToken = Token.Id.Comma });
1158 try stack.append(State{ .StringLiteral = OptionalCtx{ .Required = try items.addOne() } });
1156 while (eatToken(&tok_it, &tree, Token.Id.StringLiteral)) |strlit| {
1157 try items.push(strlit);
1158 if (eatToken(&tok_it, &tree, Token.Id.Comma) == null)
1159 break;
1160 }
11591161 continue;
11601162 },
11611163
std/zig/parser_test.zig+43-1
......@@ -1,3 +1,44 @@
1test "zig fmt: simple asm" {
2 try testTransform(
3 \\comptime {
4 \\ asm volatile (
5 \\ \\.globl aoeu;
6 \\ \\.type aoeu, @function;
7 \\ \\.set aoeu, derp;
8 \\ );
9 \\
10 \\ asm ("not real assembly"
11 \\ :[a] "x" (x),);
12 \\ asm ("not real assembly"
13 \\ :[a] "x" (->i32),:[a] "x" (1),);
14 \\ asm ("still not real assembly"
15 \\ :::"a","b",);
16 \\}
17 ,
18 \\comptime {
19 \\ asm volatile (
20 \\ \\.globl aoeu;
21 \\ \\.type aoeu, @function;
22 \\ \\.set aoeu, derp;
23 \\ );
24 \\
25 \\ asm ("not real assembly"
26 \\ : [a] "x" (x)
27 \\ );
28 \\ asm ("not real assembly"
29 \\ : [a] "x" (-> i32)
30 \\ : [a] "x" (1)
31 \\ );
32 \\ asm ("still not real assembly"
33 \\ :
34 \\ :
35 \\ : "a", "b"
36 \\ );
37 \\}
38 \\
39 );
40}
41
142test "zig fmt: nested struct literal with one item" {
243 try testCanonical(
344 \\const a = foo{
......@@ -1295,7 +1336,8 @@ test "zig fmt: inline asm" {
12951336 \\ : [ret] "={rax}" (-> usize)
12961337 \\ : [number] "{rax}" (number),
12971338 \\ [arg1] "{rdi}" (arg1)
1298 \\ : "rcx", "r11");
1339 \\ : "rcx", "r11"
1340 \\ );
12991341 \\}
13001342 \\
13011343 );
std/zig/render.zig+71-24
......@@ -1203,19 +1203,35 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
12031203 try renderToken(tree, stream, tree.nextToken(asm_node.asm_token), indent, Space.None); // (
12041204 }
12051205
1206 if (asm_node.outputs.len == 0 and asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
1207 try renderExpression(allocator, stream, tree, indent, asm_node.template, Space.None);
1208 try renderToken(tree, stream, asm_node.rparen, indent, space);
1209 return;
1210 }
1211
12061212 try renderExpression(allocator, stream, tree, indent, asm_node.template, Space.Newline);
1213
12071214 const indent_once = indent + indent_delta;
12081215 try stream.writeByteNTimes(' ', indent_once);
1209 try stream.print(": ");
1216
1217 const colon1 = tree.nextToken(asm_node.template.lastToken());
12101218 const indent_extra = indent_once + 2;
12111219
1212 {
1220 const colon2 = if (asm_node.outputs.len == 0) blk: {
1221 try renderToken(tree, stream, colon1, indent, Space.Newline); // :
1222 try stream.writeByteNTimes(' ', indent_once);
1223
1224 break :blk tree.nextToken(colon1);
1225 } else blk: {
1226 try renderToken(tree, stream, colon1, indent, Space.Space); // :
1227
12131228 var it = asm_node.outputs.iterator(0);
1214 while (it.next()) |asm_output| {
1229 while (true) {
1230 const asm_output = ??it.next();
12151231 const node = &(asm_output.*).base;
1216 try renderExpression(allocator, stream, tree, indent_extra, node, Space.None);
12171232
12181233 if (it.peek()) |next_asm_output| {
1234 try renderExpression(allocator, stream, tree, indent_extra, node, Space.None);
12191235 const next_node = &(next_asm_output.*).base;
12201236
12211237 const comma = tree.prevToken(next_asm_output.*.firstToken());
......@@ -1223,21 +1239,38 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
12231239 try renderExtraNewline(tree, stream, next_node);
12241240
12251241 try stream.writeByteNTimes(' ', indent_extra);
1242 } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
1243 try renderExpression(allocator, stream, tree, indent_extra, node, Space.Newline);
1244 try stream.writeByteNTimes(' ', indent);
1245 try renderToken(tree, stream, asm_node.rparen, indent, space);
1246 return;
1247 } else {
1248 try renderExpression(allocator, stream, tree, indent_extra, node, Space.Newline);
1249 try stream.writeByteNTimes(' ', indent_once);
1250 const comma_or_colon = tree.nextToken(node.lastToken());
1251 break :blk switch (tree.tokens.at(comma_or_colon).id) {
1252 Token.Id.Comma => tree.nextToken(comma_or_colon),
1253 else => comma_or_colon,
1254 };
12261255 }
12271256 }
1228 }
1257 };
12291258
1230 try stream.write("\n");
1231 try stream.writeByteNTimes(' ', indent_once);
1232 try stream.write(": ");
1259 const colon3 = if (asm_node.inputs.len == 0) blk: {
1260 try renderToken(tree, stream, colon2, indent, Space.Newline); // :
1261 try stream.writeByteNTimes(' ', indent_once);
1262
1263 break :blk tree.nextToken(colon2);
1264 } else blk: {
1265 try renderToken(tree, stream, colon2, indent, Space.Space); // :
12331266
1234 {
12351267 var it = asm_node.inputs.iterator(0);
1236 while (it.next()) |asm_input| {
1268 while (true) {
1269 const asm_input = ??it.next();
12371270 const node = &(asm_input.*).base;
1238 try renderExpression(allocator, stream, tree, indent_extra, node, Space.None);
12391271
12401272 if (it.peek()) |next_asm_input| {
1273 try renderExpression(allocator, stream, tree, indent_extra, node, Space.None);
12411274 const next_node = &(next_asm_input.*).base;
12421275
12431276 const comma = tree.prevToken(next_asm_input.*.firstToken());
......@@ -1245,26 +1278,40 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
12451278 try renderExtraNewline(tree, stream, next_node);
12461279
12471280 try stream.writeByteNTimes(' ', indent_extra);
1281 } else if (asm_node.clobbers.len == 0) {
1282 try renderExpression(allocator, stream, tree, indent_extra, node, Space.Newline);
1283 try stream.writeByteNTimes(' ', indent);
1284 try renderToken(tree, stream, asm_node.rparen, indent, space); // )
1285 return;
1286 } else {
1287 try renderExpression(allocator, stream, tree, indent_extra, node, Space.Newline);
1288 try stream.writeByteNTimes(' ', indent_once);
1289 const comma_or_colon = tree.nextToken(node.lastToken());
1290 break :blk switch (tree.tokens.at(comma_or_colon).id) {
1291 Token.Id.Comma => tree.nextToken(comma_or_colon),
1292 else => comma_or_colon,
1293 };
12481294 }
12491295 }
1250 }
1296 };
12511297
1252 try stream.write("\n");
1253 try stream.writeByteNTimes(' ', indent_once);
1254 try stream.write(": ");
1298 try renderToken(tree, stream, colon3, indent, Space.Space); // :
12551299
1256 {
1257 var it = asm_node.clobbers.iterator(0);
1258 while (it.next()) |node| {
1259 try renderExpression(allocator, stream, tree, indent_once, node.*, Space.None);
1300 var it = asm_node.clobbers.iterator(0);
1301 while (true) {
1302 const clobber_token = ??it.next();
12601303
1261 if (it.peek() != null) {
1262 try stream.write(", ");
1263 }
1304 if (it.peek() == null) {
1305 try renderToken(tree, stream, clobber_token.*, indent_once, Space.Newline);
1306 try stream.writeByteNTimes(' ', indent);
1307 try renderToken(tree, stream, asm_node.rparen, indent, space);
1308 return;
1309 } else {
1310 try renderToken(tree, stream, clobber_token.*, indent_once, Space.None);
1311 const comma = tree.nextToken(clobber_token.*);
1312 try renderToken(tree, stream, comma, indent_once, Space.Space); // ,
12641313 }
12651314 }
1266
1267 try renderToken(tree, stream, asm_node.rparen, indent, space);
12681315 },
12691316
12701317 ast.Node.Id.AsmInput => {