authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-08 22:03:23-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-08 22:03:23-07:00
logb1d8a0a5a6680383bad09b904dba231204a430bd
tree8d65ad20ecdc5550380f786f58a9891fb6c4fdba
parentd869133a9fb96fb27a07c1e42c12c5270eae5940

zig fmt: asm expressions


4 files changed, 403 insertions(+), 260 deletions(-)

lib/std/zig/ast.zig+173-67
......@@ -419,13 +419,16 @@ pub const Tree = struct {
419419 n = extra.start;
420420 },
421421
422 .AsmOutput, .AsmInput => {
423 assert(token_tags[main_tokens[n] - 1] == .LBracket);
424 return main_tokens[n] - 1;
425 },
426
422427 .WhileSimple => unreachable, // TODO
423428 .WhileCont => unreachable, // TODO
424429 .While => unreachable, // TODO
425430 .ForSimple => unreachable, // TODO
426431 .For => unreachable, // TODO
427 .AsmOutput => unreachable, // TODO
428 .AsmInput => unreachable, // TODO
429432 .ErrorValue => unreachable, // TODO
430433 };
431434 }
......@@ -515,6 +518,9 @@ pub const Tree = struct {
515518 .GroupedExpression,
516519 .StringLiteral,
517520 .ErrorSetDecl,
521 .AsmSimple,
522 .AsmOutput,
523 .AsmInput,
518524 => return datas[n].rhs + end_offset,
519525
520526 .AnyType,
......@@ -566,6 +572,10 @@ pub const Tree = struct {
566572 n = tree.extra_data[members.end - 1]; // last parameter
567573 }
568574 },
575 .Asm => {
576 const extra = tree.extraData(datas[n].rhs, Node.Asm);
577 return extra.rparen + end_offset;
578 },
569579 .ContainerDeclArgComma,
570580 .SwitchComma,
571581 => {
......@@ -765,8 +775,6 @@ pub const Tree = struct {
765775 .TaggedUnionEnumTagComma => unreachable, // TODO
766776 .If => unreachable, // TODO
767777 .Continue => unreachable, // TODO
768 .AsmSimple => unreachable, // TODO
769 .Asm => unreachable, // TODO
770778 .SwitchRange => unreachable, // TODO
771779 .ArrayType => unreachable, // TODO
772780 .ArrayTypeSentinel => unreachable, // TODO
......@@ -778,8 +786,6 @@ pub const Tree = struct {
778786 .FnProtoMulti => unreachable, // TODO
779787 .FnProtoOne => unreachable, // TODO
780788 .FnProto => unreachable, // TODO
781 .AsmOutput => unreachable, // TODO
782 .AsmInput => unreachable, // TODO
783789 .ErrorValue => unreachable, // TODO
784790 };
785791 }
......@@ -790,7 +796,7 @@ pub const Tree = struct {
790796 return mem.indexOfScalar(u8, source, '\n') == null;
791797 }
792798
793 pub fn globalVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {
799 pub fn globalVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
794800 assert(tree.nodes.items(.tag)[node] == .GlobalVarDecl);
795801 const data = tree.nodes.items(.data)[node];
796802 const extra = tree.extraData(data.lhs, Node.GlobalVarDecl);
......@@ -803,7 +809,7 @@ pub const Tree = struct {
803809 });
804810 }
805811
806 pub fn localVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {
812 pub fn localVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
807813 assert(tree.nodes.items(.tag)[node] == .LocalVarDecl);
808814 const data = tree.nodes.items(.data)[node];
809815 const extra = tree.extraData(data.lhs, Node.LocalVarDecl);
......@@ -816,7 +822,7 @@ pub const Tree = struct {
816822 });
817823 }
818824
819 pub fn simpleVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {
825 pub fn simpleVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
820826 assert(tree.nodes.items(.tag)[node] == .SimpleVarDecl);
821827 const data = tree.nodes.items(.data)[node];
822828 return tree.fullVarDecl(.{
......@@ -828,7 +834,7 @@ pub const Tree = struct {
828834 });
829835 }
830836
831 pub fn alignedVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {
837 pub fn alignedVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
832838 assert(tree.nodes.items(.tag)[node] == .AlignedVarDecl);
833839 const data = tree.nodes.items(.data)[node];
834840 return tree.fullVarDecl(.{
......@@ -840,7 +846,7 @@ pub const Tree = struct {
840846 });
841847 }
842848
843 pub fn ifSimple(tree: Tree, node: Node.Index) Full.If {
849 pub fn ifSimple(tree: Tree, node: Node.Index) full.If {
844850 assert(tree.nodes.items(.tag)[node] == .IfSimple);
845851 const data = tree.nodes.items(.data)[node];
846852 return tree.fullIf(.{
......@@ -851,7 +857,7 @@ pub const Tree = struct {
851857 });
852858 }
853859
854 pub fn ifFull(tree: Tree, node: Node.Index) Full.If {
860 pub fn ifFull(tree: Tree, node: Node.Index) full.If {
855861 assert(tree.nodes.items(.tag)[node] == .If);
856862 const data = tree.nodes.items(.data)[node];
857863 const extra = tree.extraData(data.rhs, Node.If);
......@@ -863,7 +869,7 @@ pub const Tree = struct {
863869 });
864870 }
865871
866 pub fn containerField(tree: Tree, node: Node.Index) Full.ContainerField {
872 pub fn containerField(tree: Tree, node: Node.Index) full.ContainerField {
867873 assert(tree.nodes.items(.tag)[node] == .ContainerField);
868874 const data = tree.nodes.items(.data)[node];
869875 const extra = tree.extraData(data.rhs, Node.ContainerField);
......@@ -875,7 +881,7 @@ pub const Tree = struct {
875881 });
876882 }
877883
878 pub fn containerFieldInit(tree: Tree, node: Node.Index) Full.ContainerField {
884 pub fn containerFieldInit(tree: Tree, node: Node.Index) full.ContainerField {
879885 assert(tree.nodes.items(.tag)[node] == .ContainerFieldInit);
880886 const data = tree.nodes.items(.data)[node];
881887 return tree.fullContainerField(.{
......@@ -886,7 +892,7 @@ pub const Tree = struct {
886892 });
887893 }
888894
889 pub fn containerFieldAlign(tree: Tree, node: Node.Index) Full.ContainerField {
895 pub fn containerFieldAlign(tree: Tree, node: Node.Index) full.ContainerField {
890896 assert(tree.nodes.items(.tag)[node] == .ContainerFieldAlign);
891897 const data = tree.nodes.items(.data)[node];
892898 return tree.fullContainerField(.{
......@@ -897,7 +903,7 @@ pub const Tree = struct {
897903 });
898904 }
899905
900 pub fn fnProtoSimple(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) Full.FnProto {
906 pub fn fnProtoSimple(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnProto {
901907 assert(tree.nodes.items(.tag)[node] == .FnProtoSimple);
902908 const data = tree.nodes.items(.data)[node];
903909 buffer[0] = data.lhs;
......@@ -912,7 +918,7 @@ pub const Tree = struct {
912918 });
913919 }
914920
915 pub fn fnProtoMulti(tree: Tree, node: Node.Index) Full.FnProto {
921 pub fn fnProtoMulti(tree: Tree, node: Node.Index) full.FnProto {
916922 assert(tree.nodes.items(.tag)[node] == .FnProtoMulti);
917923 const data = tree.nodes.items(.data)[node];
918924 const params_range = tree.extraData(data.lhs, Node.SubRange);
......@@ -927,7 +933,7 @@ pub const Tree = struct {
927933 });
928934 }
929935
930 pub fn fnProtoOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) Full.FnProto {
936 pub fn fnProtoOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnProto {
931937 assert(tree.nodes.items(.tag)[node] == .FnProtoOne);
932938 const data = tree.nodes.items(.data)[node];
933939 const extra = tree.extraData(data.lhs, Node.FnProtoOne);
......@@ -943,7 +949,7 @@ pub const Tree = struct {
943949 });
944950 }
945951
946 pub fn fnProto(tree: Tree, node: Node.Index) Full.FnProto {
952 pub fn fnProto(tree: Tree, node: Node.Index) full.FnProto {
947953 assert(tree.nodes.items(.tag)[node] == .FnProto);
948954 const data = tree.nodes.items(.data)[node];
949955 const extra = tree.extraData(data.lhs, Node.FnProto);
......@@ -958,7 +964,7 @@ pub const Tree = struct {
958964 });
959965 }
960966
961 pub fn structInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) Full.StructInit {
967 pub fn structInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.StructInit {
962968 assert(tree.nodes.items(.tag)[node] == .StructInitOne);
963969 const data = tree.nodes.items(.data)[node];
964970 buffer[0] = data.rhs;
......@@ -970,7 +976,7 @@ pub const Tree = struct {
970976 });
971977 }
972978
973 pub fn structInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.StructInit {
979 pub fn structInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.StructInit {
974980 assert(tree.nodes.items(.tag)[node] == .StructInitDotTwo or
975981 tree.nodes.items(.tag)[node] == .StructInitDotTwoComma);
976982 const data = tree.nodes.items(.data)[node];
......@@ -988,7 +994,7 @@ pub const Tree = struct {
988994 });
989995 }
990996
991 pub fn structInitDot(tree: Tree, node: Node.Index) Full.StructInit {
997 pub fn structInitDot(tree: Tree, node: Node.Index) full.StructInit {
992998 assert(tree.nodes.items(.tag)[node] == .StructInitDot);
993999 const data = tree.nodes.items(.data)[node];
9941000 return tree.fullStructInit(.{
......@@ -998,7 +1004,7 @@ pub const Tree = struct {
9981004 });
9991005 }
10001006
1001 pub fn structInit(tree: Tree, node: Node.Index) Full.StructInit {
1007 pub fn structInit(tree: Tree, node: Node.Index) full.StructInit {
10021008 assert(tree.nodes.items(.tag)[node] == .StructInit);
10031009 const data = tree.nodes.items(.data)[node];
10041010 const fields_range = tree.extraData(data.rhs, Node.SubRange);
......@@ -1009,7 +1015,7 @@ pub const Tree = struct {
10091015 });
10101016 }
10111017
1012 pub fn arrayInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) Full.ArrayInit {
1018 pub fn arrayInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit {
10131019 assert(tree.nodes.items(.tag)[node] == .ArrayInitOne);
10141020 const data = tree.nodes.items(.data)[node];
10151021 buffer[0] = data.rhs;
......@@ -1023,7 +1029,7 @@ pub const Tree = struct {
10231029 };
10241030 }
10251031
1026 pub fn arrayInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ArrayInit {
1032 pub fn arrayInitDotTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ArrayInit {
10271033 assert(tree.nodes.items(.tag)[node] == .ArrayInitDotTwo or
10281034 tree.nodes.items(.tag)[node] == .ArrayInitDotTwoComma);
10291035 const data = tree.nodes.items(.data)[node];
......@@ -1043,7 +1049,7 @@ pub const Tree = struct {
10431049 };
10441050 }
10451051
1046 pub fn arrayInitDot(tree: Tree, node: Node.Index) Full.ArrayInit {
1052 pub fn arrayInitDot(tree: Tree, node: Node.Index) full.ArrayInit {
10471053 assert(tree.nodes.items(.tag)[node] == .ArrayInitDot);
10481054 const data = tree.nodes.items(.data)[node];
10491055 return .{
......@@ -1055,7 +1061,7 @@ pub const Tree = struct {
10551061 };
10561062 }
10571063
1058 pub fn arrayInit(tree: Tree, node: Node.Index) Full.ArrayInit {
1064 pub fn arrayInit(tree: Tree, node: Node.Index) full.ArrayInit {
10591065 assert(tree.nodes.items(.tag)[node] == .ArrayInit);
10601066 const data = tree.nodes.items(.data)[node];
10611067 const elem_range = tree.extraData(data.rhs, Node.SubRange);
......@@ -1068,7 +1074,7 @@ pub const Tree = struct {
10681074 };
10691075 }
10701076
1071 pub fn arrayType(tree: Tree, node: Node.Index) Full.ArrayType {
1077 pub fn arrayType(tree: Tree, node: Node.Index) full.ArrayType {
10721078 assert(tree.nodes.items(.tag)[node] == .ArrayType);
10731079 const data = tree.nodes.items(.data)[node];
10741080 return .{
......@@ -1081,7 +1087,7 @@ pub const Tree = struct {
10811087 };
10821088 }
10831089
1084 pub fn arrayTypeSentinel(tree: Tree, node: Node.Index) Full.ArrayType {
1090 pub fn arrayTypeSentinel(tree: Tree, node: Node.Index) full.ArrayType {
10851091 assert(tree.nodes.items(.tag)[node] == .ArrayTypeSentinel);
10861092 const data = tree.nodes.items(.data)[node];
10871093 const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel);
......@@ -1095,7 +1101,7 @@ pub const Tree = struct {
10951101 };
10961102 }
10971103
1098 pub fn ptrTypeAligned(tree: Tree, node: Node.Index) Full.PtrType {
1104 pub fn ptrTypeAligned(tree: Tree, node: Node.Index) full.PtrType {
10991105 assert(tree.nodes.items(.tag)[node] == .PtrTypeAligned);
11001106 const data = tree.nodes.items(.data)[node];
11011107 return tree.fullPtrType(.{
......@@ -1108,7 +1114,7 @@ pub const Tree = struct {
11081114 });
11091115 }
11101116
1111 pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) Full.PtrType {
1117 pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) full.PtrType {
11121118 assert(tree.nodes.items(.tag)[node] == .PtrTypeSentinel);
11131119 const data = tree.nodes.items(.data)[node];
11141120 return tree.fullPtrType(.{
......@@ -1121,7 +1127,7 @@ pub const Tree = struct {
11211127 });
11221128 }
11231129
1124 pub fn ptrType(tree: Tree, node: Node.Index) Full.PtrType {
1130 pub fn ptrType(tree: Tree, node: Node.Index) full.PtrType {
11251131 assert(tree.nodes.items(.tag)[node] == .PtrType);
11261132 const data = tree.nodes.items(.data)[node];
11271133 const extra = tree.extraData(data.lhs, Node.PtrType);
......@@ -1135,7 +1141,7 @@ pub const Tree = struct {
11351141 });
11361142 }
11371143
1138 pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) Full.PtrType {
1144 pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) full.PtrType {
11391145 assert(tree.nodes.items(.tag)[node] == .PtrTypeBitRange);
11401146 const data = tree.nodes.items(.data)[node];
11411147 const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange);
......@@ -1149,7 +1155,7 @@ pub const Tree = struct {
11491155 });
11501156 }
11511157
1152 pub fn sliceOpen(tree: Tree, node: Node.Index) Full.Slice {
1158 pub fn sliceOpen(tree: Tree, node: Node.Index) full.Slice {
11531159 assert(tree.nodes.items(.tag)[node] == .SliceOpen);
11541160 const data = tree.nodes.items(.data)[node];
11551161 return .{
......@@ -1163,7 +1169,7 @@ pub const Tree = struct {
11631169 };
11641170 }
11651171
1166 pub fn slice(tree: Tree, node: Node.Index) Full.Slice {
1172 pub fn slice(tree: Tree, node: Node.Index) full.Slice {
11671173 assert(tree.nodes.items(.tag)[node] == .Slice);
11681174 const data = tree.nodes.items(.data)[node];
11691175 const extra = tree.extraData(data.rhs, Node.Slice);
......@@ -1178,7 +1184,7 @@ pub const Tree = struct {
11781184 };
11791185 }
11801186
1181 pub fn sliceSentinel(tree: Tree, node: Node.Index) Full.Slice {
1187 pub fn sliceSentinel(tree: Tree, node: Node.Index) full.Slice {
11821188 assert(tree.nodes.items(.tag)[node] == .SliceSentinel);
11831189 const data = tree.nodes.items(.data)[node];
11841190 const extra = tree.extraData(data.rhs, Node.SliceSentinel);
......@@ -1193,7 +1199,7 @@ pub const Tree = struct {
11931199 };
11941200 }
11951201
1196 pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ContainerDecl {
1202 pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl {
11971203 assert(tree.nodes.items(.tag)[node] == .ContainerDeclTwo or
11981204 tree.nodes.items(.tag)[node] == .ContainerDeclTwoComma);
11991205 const data = tree.nodes.items(.data)[node];
......@@ -1212,7 +1218,7 @@ pub const Tree = struct {
12121218 });
12131219 }
12141220
1215 pub fn containerDecl(tree: Tree, node: Node.Index) Full.ContainerDecl {
1221 pub fn containerDecl(tree: Tree, node: Node.Index) full.ContainerDecl {
12161222 assert(tree.nodes.items(.tag)[node] == .ContainerDecl or
12171223 tree.nodes.items(.tag)[node] == .ContainerDeclComma);
12181224 const data = tree.nodes.items(.data)[node];
......@@ -1224,7 +1230,7 @@ pub const Tree = struct {
12241230 });
12251231 }
12261232
1227 pub fn containerDeclArg(tree: Tree, node: Node.Index) Full.ContainerDecl {
1233 pub fn containerDeclArg(tree: Tree, node: Node.Index) full.ContainerDecl {
12281234 assert(tree.nodes.items(.tag)[node] == .ContainerDeclArg or
12291235 tree.nodes.items(.tag)[node] == .ContainerDeclArgComma);
12301236 const data = tree.nodes.items(.data)[node];
......@@ -1237,7 +1243,7 @@ pub const Tree = struct {
12371243 });
12381244 }
12391245
1240 pub fn taggedUnionTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ContainerDecl {
1246 pub fn taggedUnionTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl {
12411247 assert(tree.nodes.items(.tag)[node] == .TaggedUnionTwo or
12421248 tree.nodes.items(.tag)[node] == .TaggedUnionTwoComma);
12431249 const data = tree.nodes.items(.data)[node];
......@@ -1257,7 +1263,7 @@ pub const Tree = struct {
12571263 });
12581264 }
12591265
1260 pub fn taggedUnion(tree: Tree, node: Node.Index) Full.ContainerDecl {
1266 pub fn taggedUnion(tree: Tree, node: Node.Index) full.ContainerDecl {
12611267 assert(tree.nodes.items(.tag)[node] == .TaggedUnion or
12621268 tree.nodes.items(.tag)[node] == .TaggedUnionComma);
12631269 const data = tree.nodes.items(.data)[node];
......@@ -1270,7 +1276,7 @@ pub const Tree = struct {
12701276 });
12711277 }
12721278
1273 pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) Full.ContainerDecl {
1279 pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) full.ContainerDecl {
12741280 assert(tree.nodes.items(.tag)[node] == .TaggedUnionEnumTag or
12751281 tree.nodes.items(.tag)[node] == .TaggedUnionEnumTagComma);
12761282 const data = tree.nodes.items(.data)[node];
......@@ -1284,7 +1290,7 @@ pub const Tree = struct {
12841290 });
12851291 }
12861292
1287 pub fn switchCaseOne(tree: Tree, node: Node.Index) Full.SwitchCase {
1293 pub fn switchCaseOne(tree: Tree, node: Node.Index) full.SwitchCase {
12881294 const data = &tree.nodes.items(.data)[node];
12891295 return tree.fullSwitchCase(.{
12901296 .values = if (data.lhs == 0) &.{} else @ptrCast([*]Node.Index, &data.lhs)[0..1],
......@@ -1293,7 +1299,7 @@ pub const Tree = struct {
12931299 });
12941300 }
12951301
1296 pub fn switchCase(tree: Tree, node: Node.Index) Full.SwitchCase {
1302 pub fn switchCase(tree: Tree, node: Node.Index) full.SwitchCase {
12971303 const data = tree.nodes.items(.data)[node];
12981304 const extra = tree.extraData(data.lhs, Node.SubRange);
12991305 return tree.fullSwitchCase(.{
......@@ -1303,9 +1309,30 @@ pub const Tree = struct {
13031309 });
13041310 }
13051311
1306 fn fullVarDecl(tree: Tree, info: Full.VarDecl.Ast) Full.VarDecl {
1312 pub fn asmSimple(tree: Tree, node: Node.Index) full.Asm {
1313 const data = tree.nodes.items(.data)[node];
1314 return tree.fullAsm(.{
1315 .asm_token = tree.nodes.items(.main_token)[node],
1316 .template = data.lhs,
1317 .items = &.{},
1318 .rparen = data.rhs,
1319 });
1320 }
1321
1322 pub fn asmFull(tree: Tree, node: Node.Index) full.Asm {
1323 const data = tree.nodes.items(.data)[node];
1324 const extra = tree.extraData(data.rhs, Node.Asm);
1325 return tree.fullAsm(.{
1326 .asm_token = tree.nodes.items(.main_token)[node],
1327 .template = data.lhs,
1328 .items = tree.extra_data[extra.items_start..extra.items_end],
1329 .rparen = extra.rparen,
1330 });
1331 }
1332
1333 fn fullVarDecl(tree: Tree, info: full.VarDecl.Ast) full.VarDecl {
13071334 const token_tags = tree.tokens.items(.tag);
1308 var result: Full.VarDecl = .{
1335 var result: full.VarDecl = .{
13091336 .ast = info,
13101337 .visib_token = null,
13111338 .extern_export_token = null,
......@@ -1328,9 +1355,9 @@ pub const Tree = struct {
13281355 return result;
13291356 }
13301357
1331 fn fullIf(tree: Tree, info: Full.If.Ast) Full.If {
1358 fn fullIf(tree: Tree, info: full.If.Ast) full.If {
13321359 const token_tags = tree.tokens.items(.tag);
1333 var result: Full.If = .{
1360 var result: full.If = .{
13341361 .ast = info,
13351362 .payload_token = null,
13361363 .error_token = null,
......@@ -1353,9 +1380,9 @@ pub const Tree = struct {
13531380 return result;
13541381 }
13551382
1356 fn fullContainerField(tree: Tree, info: Full.ContainerField.Ast) Full.ContainerField {
1383 fn fullContainerField(tree: Tree, info: full.ContainerField.Ast) full.ContainerField {
13571384 const token_tags = tree.tokens.items(.tag);
1358 var result: Full.ContainerField = .{
1385 var result: full.ContainerField = .{
13591386 .ast = info,
13601387 .comptime_token = null,
13611388 };
......@@ -1367,27 +1394,27 @@ pub const Tree = struct {
13671394 return result;
13681395 }
13691396
1370 fn fullFnProto(tree: Tree, info: Full.FnProto.Ast) Full.FnProto {
1397 fn fullFnProto(tree: Tree, info: full.FnProto.Ast) full.FnProto {
13711398 const token_tags = tree.tokens.items(.tag);
1372 var result: Full.FnProto = .{
1399 var result: full.FnProto = .{
13731400 .ast = info,
13741401 };
13751402 return result;
13761403 }
13771404
1378 fn fullStructInit(tree: Tree, info: Full.StructInit.Ast) Full.StructInit {
1405 fn fullStructInit(tree: Tree, info: full.StructInit.Ast) full.StructInit {
13791406 const token_tags = tree.tokens.items(.tag);
1380 var result: Full.StructInit = .{
1407 var result: full.StructInit = .{
13811408 .ast = info,
13821409 };
13831410 return result;
13841411 }
13851412
1386 fn fullPtrType(tree: Tree, info: Full.PtrType.Ast) Full.PtrType {
1413 fn fullPtrType(tree: Tree, info: full.PtrType.Ast) full.PtrType {
13871414 const token_tags = tree.tokens.items(.tag);
13881415 // TODO: looks like stage1 isn't quite smart enough to handle enum
13891416 // literals in some places here
1390 const Kind = Full.PtrType.Kind;
1417 const Kind = full.PtrType.Kind;
13911418 const kind: Kind = switch (token_tags[info.main_token]) {
13921419 .Asterisk => switch (token_tags[info.main_token + 1]) {
13931420 .RBracket => .many,
......@@ -1402,7 +1429,7 @@ pub const Tree = struct {
14021429 },
14031430 else => unreachable,
14041431 };
1405 var result: Full.PtrType = .{
1432 var result: full.PtrType = .{
14061433 .kind = kind,
14071434 .allowzero_token = null,
14081435 .const_token = null,
......@@ -1441,9 +1468,9 @@ pub const Tree = struct {
14411468 return result;
14421469 }
14431470
1444 fn fullContainerDecl(tree: Tree, info: Full.ContainerDecl.Ast) Full.ContainerDecl {
1471 fn fullContainerDecl(tree: Tree, info: full.ContainerDecl.Ast) full.ContainerDecl {
14451472 const token_tags = tree.tokens.items(.tag);
1446 var result: Full.ContainerDecl = .{
1473 var result: full.ContainerDecl = .{
14471474 .ast = info,
14481475 .layout_token = null,
14491476 };
......@@ -1454,9 +1481,9 @@ pub const Tree = struct {
14541481 return result;
14551482 }
14561483
1457 fn fullSwitchCase(tree: Tree, info: Full.SwitchCase.Ast) Full.SwitchCase {
1484 fn fullSwitchCase(tree: Tree, info: full.SwitchCase.Ast) full.SwitchCase {
14581485 const token_tags = tree.tokens.items(.tag);
1459 var result: Full.SwitchCase = .{
1486 var result: full.SwitchCase = .{
14601487 .ast = info,
14611488 .payload_token = null,
14621489 };
......@@ -1465,10 +1492,67 @@ pub const Tree = struct {
14651492 }
14661493 return result;
14671494 }
1495
1496 fn fullAsm(tree: Tree, info: full.Asm.Ast) full.Asm {
1497 const token_tags = tree.tokens.items(.tag);
1498 const node_tags = tree.nodes.items(.tag);
1499 var result: full.Asm = .{
1500 .ast = info,
1501 .volatile_token = null,
1502 .inputs = &.{},
1503 .outputs = &.{},
1504 .first_clobber = null,
1505 };
1506 if (token_tags[info.asm_token + 1] == .Keyword_volatile) {
1507 result.volatile_token = info.asm_token + 1;
1508 }
1509 const outputs_end: usize = for (info.items) |item, i| {
1510 switch (node_tags[item]) {
1511 .AsmOutput => continue,
1512 else => break i,
1513 }
1514 } else info.items.len;
1515
1516 result.outputs = info.items[0..outputs_end];
1517 result.inputs = info.items[outputs_end..];
1518
1519 if (info.items.len == 0) {
1520 // asm ("foo" ::: "a", "b");
1521 const template_token = tree.lastToken(info.template);
1522 if (token_tags[template_token + 1] == .Colon and
1523 token_tags[template_token + 2] == .Colon and
1524 token_tags[template_token + 3] == .Colon and
1525 token_tags[template_token + 4] == .StringLiteral)
1526 {
1527 result.first_clobber = template_token + 4;
1528 }
1529 } else if (result.inputs.len != 0) {
1530 // asm ("foo" :: [_] "" (y) : "a", "b");
1531 const last_input = result.inputs[result.inputs.len - 1];
1532 const rparen = tree.lastToken(last_input);
1533 if (token_tags[rparen + 1] == .Colon and
1534 token_tags[rparen + 2] == .StringLiteral)
1535 {
1536 result.first_clobber = rparen + 2;
1537 }
1538 } else {
1539 // asm ("foo" : [_] "" (x) :: "a", "b");
1540 const last_output = result.outputs[result.outputs.len - 1];
1541 const rparen = tree.lastToken(last_output);
1542 if (token_tags[rparen + 1] == .Colon and
1543 token_tags[rparen + 2] == .Colon and
1544 token_tags[rparen + 3] == .StringLiteral)
1545 {
1546 result.first_clobber = rparen + 3;
1547 }
1548 }
1549
1550 return result;
1551 }
14681552};
14691553
14701554/// Fully assembled AST node information.
1471pub const Full = struct {
1555pub const full = struct {
14721556 pub const VarDecl = struct {
14731557 visib_token: ?TokenIndex,
14741558 extern_export_token: ?TokenIndex,
......@@ -1624,6 +1708,21 @@ pub const Full = struct {
16241708 target_expr: Node.Index,
16251709 };
16261710 };
1711
1712 pub const Asm = struct {
1713 ast: Ast,
1714 volatile_token: ?TokenIndex,
1715 first_clobber: ?TokenIndex,
1716 outputs: []const Node.Index,
1717 inputs: []const Node.Index,
1718
1719 pub const Ast = struct {
1720 asm_token: TokenIndex,
1721 template: Node.Index,
1722 items: []const Node.Index,
1723 rparen: TokenIndex,
1724 };
1725 };
16271726};
16281727
16291728pub const Error = union(enum) {
......@@ -2234,15 +2333,15 @@ pub const Node = struct {
22342333 Block,
22352334 /// Same as BlockTwo but there is known to be a semicolon before the rbrace.
22362335 BlockSemicolon,
2237 /// `asm(lhs)`. rhs unused.
2336 /// `asm(lhs)`. rhs is the token index of the rparen.
22382337 AsmSimple,
2239 /// `asm(lhs, a)`. `sub_range_list[rhs]`.
2338 /// `asm(lhs, a)`. `Asm[rhs]`.
22402339 Asm,
2241 /// `[a] "b" (c)`. lhs is string literal token index, rhs is 0.
2242 /// `[a] "b" (-> rhs)`. lhs is the string literal token index, rhs is type expr.
2340 /// `[a] "b" (c)`. lhs is 0, rhs is token index of the rparen.
2341 /// `[a] "b" (-> lhs)`. rhs is token index of the rparen.
22432342 /// main_token is `a`.
22442343 AsmOutput,
2245 /// `[a] "b" (rhs)`. lhs is string literal token index.
2344 /// `[a] "b" (lhs)`. rhs is token index of the rparen.
22462345 /// main_token is `a`.
22472346 AsmInput,
22482347 /// `error.a`. lhs is token index of `.`. rhs is token index of `a`.
......@@ -2355,4 +2454,11 @@ pub const Node = struct {
23552454 /// Populated if callconv(A) is present.
23562455 callconv_expr: Index,
23572456 };
2457
2458 pub const Asm = struct {
2459 items_start: Index,
2460 items_end: Index,
2461 /// Needed to make lastToken() work.
2462 rparen: TokenIndex,
2463 };
23582464};
lib/std/zig/parse.zig+27-19
......@@ -472,7 +472,7 @@ const Parser = struct {
472472
473473 /// TestDecl <- KEYWORD_test STRINGLITERALSINGLE? Block
474474 fn expectTestDecl(p: *Parser) !Node.Index {
475 const test_token = try p.expectToken(.Keyword_test);
475 const test_token = p.assertToken(.Keyword_test);
476476 const name_token = p.eatToken(.StringLiteral);
477477 const block_node = try p.parseBlock();
478478 if (block_node == 0) return p.fail(.{ .ExpectedLBrace = .{ .token = p.tok_i } });
......@@ -739,7 +739,7 @@ const Parser = struct {
739739 /// ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
740740 fn expectContainerField(p: *Parser) !Node.Index {
741741 const comptime_token = p.eatToken(.Keyword_comptime);
742 const name_token = try p.expectToken(.Identifier);
742 const name_token = p.assertToken(.Identifier);
743743
744744 var align_expr: Node.Index = 0;
745745 var type_expr: Node.Index = 0;
......@@ -1846,7 +1846,7 @@ const Parser = struct {
18461846 /// / CurlySuffixExpr
18471847 fn parsePrimaryExpr(p: *Parser) !Node.Index {
18481848 switch (p.token_tags[p.tok_i]) {
1849 .Keyword_asm => return p.parseAsmExpr(),
1849 .Keyword_asm => return p.expectAsmExpr(),
18501850 .Keyword_if => return p.parseIfExpr(),
18511851 .Keyword_break => {
18521852 p.tok_i += 1;
......@@ -2910,19 +2910,19 @@ const Parser = struct {
29102910 /// StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL?
29112911 /// AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem?
29122912 /// AsmInputList <- (AsmInputItem COMMA)* AsmInputItem?
2913 fn parseAsmExpr(p: *Parser) !Node.Index {
2913 fn expectAsmExpr(p: *Parser) !Node.Index {
29142914 const asm_token = p.assertToken(.Keyword_asm);
29152915 _ = p.eatToken(.Keyword_volatile);
29162916 _ = try p.expectToken(.LParen);
29172917 const template = try p.expectExpr();
29182918
2919 if (p.eatToken(.RParen)) |_| {
2919 if (p.eatToken(.RParen)) |rparen| {
29202920 return p.addNode(.{
29212921 .tag = .AsmSimple,
29222922 .main_token = asm_token,
29232923 .data = .{
29242924 .lhs = template,
2925 .rhs = undefined,
2925 .rhs = rparen,
29262926 },
29272927 });
29282928 }
......@@ -2981,16 +2981,17 @@ const Parser = struct {
29812981 }
29822982 }
29832983 }
2984 _ = try p.expectToken(.RParen);
2984 const rparen = try p.expectToken(.RParen);
29852985 const span = try p.listToSpan(list.items);
29862986 return p.addNode(.{
29872987 .tag = .Asm,
29882988 .main_token = asm_token,
29892989 .data = .{
29902990 .lhs = template,
2991 .rhs = try p.addExtra(Node.SubRange{
2992 .start = span.start,
2993 .end = span.end,
2991 .rhs = try p.addExtra(Node.Asm{
2992 .items_start = span.start,
2993 .items_end = span.end,
2994 .rparen = rparen,
29942995 }),
29952996 },
29962997 });
......@@ -3001,16 +3002,23 @@ const Parser = struct {
30013002 _ = p.eatToken(.LBracket) orelse return null_node;
30023003 const identifier = try p.expectToken(.Identifier);
30033004 _ = try p.expectToken(.RBracket);
3004 const constraint = try p.expectToken(.StringLiteral);
3005 _ = try p.expectToken(.StringLiteral);
30053006 _ = try p.expectToken(.LParen);
3006 const rhs: Node.Index = if (p.eatToken(.Arrow)) |_| try p.expectTypeExpr() else null_node;
3007 _ = try p.expectToken(.RParen);
3007 const type_expr: Node.Index = blk: {
3008 if (p.eatToken(.Arrow)) |_| {
3009 break :blk try p.expectTypeExpr();
3010 } else {
3011 _ = try p.expectToken(.Identifier);
3012 break :blk null_node;
3013 }
3014 };
3015 const rparen = try p.expectToken(.RParen);
30083016 return p.addNode(.{
30093017 .tag = .AsmOutput,
30103018 .main_token = identifier,
30113019 .data = .{
3012 .lhs = constraint,
3013 .rhs = rhs,
3020 .lhs = type_expr,
3021 .rhs = rparen,
30143022 },
30153023 });
30163024 }
......@@ -3020,16 +3028,16 @@ const Parser = struct {
30203028 _ = p.eatToken(.LBracket) orelse return null_node;
30213029 const identifier = try p.expectToken(.Identifier);
30223030 _ = try p.expectToken(.RBracket);
3023 const constraint = try p.expectToken(.StringLiteral);
3031 _ = try p.expectToken(.StringLiteral);
30243032 _ = try p.expectToken(.LParen);
30253033 const expr = try p.expectExpr();
3026 _ = try p.expectToken(.RParen);
3034 const rparen = try p.expectToken(.RParen);
30273035 return p.addNode(.{
30283036 .tag = .AsmInput,
30293037 .main_token = identifier,
30303038 .data = .{
3031 .lhs = constraint,
3032 .rhs = expr,
3039 .lhs = expr,
3040 .rhs = rparen,
30333041 },
30343042 });
30353043 }
lib/std/zig/parser_test.zig+24-24
......@@ -313,30 +313,30 @@ test "zig fmt: builtin call with trailing comma" {
313313 );
314314}
315315
316//test "zig fmt: asm expression with comptime content" {
317// try testCanonical(
318// \\comptime {
319// \\ asm ("foo" ++ "bar");
320// \\}
321// \\pub fn main() void {
322// \\ asm volatile ("foo" ++ "bar");
323// \\ asm volatile ("foo" ++ "bar"
324// \\ : [_] "" (x)
325// \\ );
326// \\ asm volatile ("foo" ++ "bar"
327// \\ : [_] "" (x)
328// \\ : [_] "" (y)
329// \\ );
330// \\ asm volatile ("foo" ++ "bar"
331// \\ : [_] "" (x)
332// \\ : [_] "" (y)
333// \\ : "h", "e", "l", "l", "o"
334// \\ );
335// \\}
336// \\
337// );
338//}
339//
316test "zig fmt: asm expression with comptime content" {
317 try testCanonical(
318 \\comptime {
319 \\ asm ("foo" ++ "bar");
320 \\}
321 \\pub fn main() void {
322 \\ asm volatile ("foo" ++ "bar");
323 \\ asm volatile ("foo" ++ "bar"
324 \\ : [_] "" (x)
325 \\ );
326 \\ asm volatile ("foo" ++ "bar"
327 \\ : [_] "" (x)
328 \\ : [_] "" (y)
329 \\ );
330 \\ asm volatile ("foo" ++ "bar"
331 \\ : [_] "" (x)
332 \\ : [_] "" (y)
333 \\ : "h", "e", "l", "l", "o"
334 \\ );
335 \\}
336 \\
337 );
338}
339
340340//test "zig fmt: anytype struct field" {
341341// try testCanonical(
342342// \\pub const Pointer = struct {
lib/std/zig/render.zig+179-150
......@@ -816,118 +816,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
816816 .IfSimple => return renderIf(ais, tree, tree.ifSimple(node), space),
817817 .If => return renderIf(ais, tree, tree.ifFull(node), space),
818818
819 .Asm => unreachable, // TODO
820 .AsmSimple => unreachable, // TODO
821 .AsmOutput => unreachable, // TODO
822 .AsmInput => unreachable, // TODO
823 //.Asm => {
824 // const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base);
825
826 // try renderToken(ais, tree, asm_node.asm_token, Space.Space); // asm
827
828 // if (asm_node.volatile_token) |volatile_token| {
829 // try renderToken(ais, tree, volatile_token, Space.Space); // volatile
830 // try renderToken(ais, tree, tree.nextToken(volatile_token), Space.None); // (
831 // } else {
832 // try renderToken(ais, tree, tree.nextToken(asm_node.asm_token), Space.None); // (
833 // }
834
835 // asmblk: {
836 // ais.pushIndent();
837 // defer ais.popIndent();
838
839 // if (asm_node.outputs.len == 0 and asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
840 // try renderExpression(ais, tree, asm_node.template, Space.None);
841 // break :asmblk;
842 // }
843
844 // try renderExpression(ais, tree, asm_node.template, Space.Newline);
845
846 // ais.setIndentDelta(asm_indent_delta);
847 // defer ais.setIndentDelta(indent_delta);
848
849 // const colon1 = tree.nextToken(asm_node.template.lastToken());
850
851 // const colon2 = if (asm_node.outputs.len == 0) blk: {
852 // try renderToken(ais, tree, colon1, Space.Newline); // :
853
854 // break :blk tree.nextToken(colon1);
855 // } else blk: {
856 // try renderToken(ais, tree, colon1, Space.Space); // :
857
858 // ais.pushIndent();
859 // defer ais.popIndent();
860
861 // for (asm_node.outputs) |*asm_output, i| {
862 // if (i + 1 < asm_node.outputs.len) {
863 // const next_asm_output = asm_node.outputs[i + 1];
864 // try renderAsmOutput(allocator, ais, tree, asm_output, Space.None);
865
866 // const comma = tree.prevToken(next_asm_output.firstToken());
867 // try renderToken(ais, tree, comma, Space.Newline); // ,
868 // try renderExtraNewlineToken(ais, tree, next_asm_output.firstToken());
869 // } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
870 // try renderAsmOutput(allocator, ais, tree, asm_output, Space.Newline);
871 // break :asmblk;
872 // } else {
873 // try renderAsmOutput(allocator, ais, tree, asm_output, Space.Newline);
874 // const comma_or_colon = tree.nextToken(asm_output.lastToken());
875 // break :blk switch (tree.token_tags[comma_or_colon]) {
876 // .Comma => tree.nextToken(comma_or_colon),
877 // else => comma_or_colon,
878 // };
879 // }
880 // }
881 // unreachable;
882 // };
883
884 // const colon3 = if (asm_node.inputs.len == 0) blk: {
885 // try renderToken(ais, tree, colon2, Space.Newline); // :
886 // break :blk tree.nextToken(colon2);
887 // } else blk: {
888 // try renderToken(ais, tree, colon2, Space.Space); // :
889 // ais.pushIndent();
890 // defer ais.popIndent();
891 // for (asm_node.inputs) |*asm_input, i| {
892 // if (i + 1 < asm_node.inputs.len) {
893 // const next_asm_input = &asm_node.inputs[i + 1];
894 // try renderAsmInput(allocator, ais, tree, asm_input, Space.None);
895
896 // const comma = tree.prevToken(next_asm_input.firstToken());
897 // try renderToken(ais, tree, comma, Space.Newline); // ,
898 // try renderExtraNewlineToken(ais, tree, next_asm_input.firstToken());
899 // } else if (asm_node.clobbers.len == 0) {
900 // try renderAsmInput(allocator, ais, tree, asm_input, Space.Newline);
901 // break :asmblk;
902 // } else {
903 // try renderAsmInput(allocator, ais, tree, asm_input, Space.Newline);
904 // const comma_or_colon = tree.nextToken(asm_input.lastToken());
905 // break :blk switch (tree.token_tags[comma_or_colon]) {
906 // .Comma => tree.nextToken(comma_or_colon),
907 // else => comma_or_colon,
908 // };
909 // }
910 // }
911 // unreachable;
912 // };
913
914 // try renderToken(ais, tree, colon3, Space.Space); // :
915 // ais.pushIndent();
916 // defer ais.popIndent();
917 // for (asm_node.clobbers) |clobber_node, i| {
918 // if (i + 1 >= asm_node.clobbers.len) {
919 // try renderExpression(ais, tree, clobber_node, Space.Newline);
920 // break :asmblk;
921 // } else {
922 // try renderExpression(ais, tree, clobber_node, Space.None);
923 // const comma = tree.nextToken(clobber_node.lastToken());
924 // try renderToken(ais, tree, comma, Space.Space); // ,
925 // }
926 // }
927 // }
928
929 // return renderToken(ais, tree, asm_node.rparen, space);
930 //},
819 .AsmSimple => return renderAsm(ais, tree, tree.asmSimple(node), space),
820 .Asm => return renderAsm(ais, tree, tree.asmFull(node), space),
931821
932822 .EnumLiteral => {
933823 try renderToken(ais, tree, main_tokens[node] - 1, .None); // .
......@@ -945,6 +835,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
945835 .AlignedVarDecl => unreachable,
946836 .UsingNamespace => unreachable,
947837 .TestDecl => unreachable,
838 .AsmOutput => unreachable,
839 .AsmInput => unreachable,
948840 }
949841}
950842
......@@ -952,7 +844,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
952844fn renderArrayType(
953845 ais: *Ais,
954846 tree: ast.Tree,
955 array_type: ast.Full.ArrayType,
847 array_type: ast.full.ArrayType,
956848 space: Space,
957849) Error!void {
958850 try renderToken(ais, tree, array_type.ast.lbracket, .None); // lbracket
......@@ -968,7 +860,7 @@ fn renderArrayType(
968860fn renderPtrType(
969861 ais: *Ais,
970862 tree: ast.Tree,
971 ptr_type: ast.Full.PtrType,
863 ptr_type: ast.full.PtrType,
972864 space: Space,
973865) Error!void {
974866 switch (ptr_type.kind) {
......@@ -1040,7 +932,7 @@ fn renderPtrType(
1040932fn renderSlice(
1041933 ais: *Ais,
1042934 tree: ast.Tree,
1043 slice: ast.Full.Slice,
935 slice: ast.full.Slice,
1044936 space: Space,
1045937) Error!void {
1046938 const node_tags = tree.nodes.items(.tag);
......@@ -1072,48 +964,56 @@ fn renderSlice(
1072964}
1073965
1074966fn renderAsmOutput(
1075 allocator: *mem.Allocator,
1076967 ais: *Ais,
1077968 tree: ast.Tree,
1078 asm_output: *const ast.Node.Asm.Output,
969 asm_output: ast.Node.Index,
1079970 space: Space,
1080971) Error!void {
1081 try ais.writer().writeAll("[");
1082 try renderExpression(ais, tree, asm_output.symbolic_name, Space.None);
1083 try ais.writer().writeAll("] ");
1084 try renderExpression(ais, tree, asm_output.constraint, Space.None);
1085 try ais.writer().writeAll(" (");
1086
1087 switch (asm_output.kind) {
1088 .Variable => |variable_name| {
1089 try renderExpression(ais, tree, &variable_name.base, Space.None);
1090 },
1091 .Return => |return_type| {
1092 try ais.writer().writeAll("-> ");
1093 try renderExpression(ais, tree, return_type, Space.None);
1094 },
972 const token_tags = tree.tokens.items(.tag);
973 const node_tags = tree.nodes.items(.tag);
974 const main_tokens = tree.nodes.items(.main_token);
975 const datas = tree.nodes.items(.data);
976 assert(node_tags[asm_output] == .AsmOutput);
977 const symbolic_name = main_tokens[asm_output];
978
979 try renderToken(ais, tree, symbolic_name - 1, .None); // lbracket
980 try renderToken(ais, tree, symbolic_name, .None); // ident
981 try renderToken(ais, tree, symbolic_name + 1, .Space); // rbracket
982 try renderToken(ais, tree, symbolic_name + 2, .Space); // "constraint"
983 try renderToken(ais, tree, symbolic_name + 3, .None); // lparen
984
985 if (token_tags[symbolic_name + 4] == .Arrow) {
986 try renderToken(ais, tree, symbolic_name + 4, .Space); // ->
987 try renderExpression(ais, tree, datas[asm_output].lhs, Space.None);
988 return renderToken(ais, tree, datas[asm_output].rhs, space); // rparen
989 } else {
990 try renderToken(ais, tree, symbolic_name + 4, .None); // ident
991 return renderToken(ais, tree, symbolic_name + 5, space); // rparen
1095992 }
1096
1097 return renderToken(ais, tree, asm_output.lastToken(), space); // )
1098993}
1099994
1100995fn renderAsmInput(
1101 allocator: *mem.Allocator,
1102996 ais: *Ais,
1103997 tree: ast.Tree,
1104 asm_input: *const ast.Node.Asm.Input,
998 asm_input: ast.Node.Index,
1105999 space: Space,
11061000) Error!void {
1107 try ais.writer().writeAll("[");
1108 try renderExpression(ais, tree, asm_input.symbolic_name, Space.None);
1109 try ais.writer().writeAll("] ");
1110 try renderExpression(ais, tree, asm_input.constraint, Space.None);
1111 try ais.writer().writeAll(" (");
1112 try renderExpression(ais, tree, asm_input.expr, Space.None);
1113 return renderToken(ais, tree, asm_input.lastToken(), space); // )
1001 const node_tags = tree.nodes.items(.tag);
1002 const main_tokens = tree.nodes.items(.main_token);
1003 const datas = tree.nodes.items(.data);
1004 assert(node_tags[asm_input] == .AsmInput);
1005 const symbolic_name = main_tokens[asm_input];
1006
1007 try renderToken(ais, tree, symbolic_name - 1, .None); // lbracket
1008 try renderToken(ais, tree, symbolic_name, .None); // ident
1009 try renderToken(ais, tree, symbolic_name + 1, .Space); // rbracket
1010 try renderToken(ais, tree, symbolic_name + 2, .Space); // "constraint"
1011 try renderToken(ais, tree, symbolic_name + 3, .None); // lparen
1012 try renderExpression(ais, tree, datas[asm_input].lhs, Space.None);
1013 return renderToken(ais, tree, datas[asm_input].rhs, space); // rparen
11141014}
11151015
1116fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.Full.VarDecl) Error!void {
1016fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.full.VarDecl) Error!void {
11171017 if (var_decl.visib_token) |visib_token| {
11181018 try renderToken(ais, tree, visib_token, Space.Space); // pub
11191019 }
......@@ -1200,7 +1100,7 @@ fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.Full.VarDecl) Error!vo
12001100 try renderExpression(ais, tree, var_decl.ast.init_node, .Semicolon);
12011101}
12021102
1203fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.Full.If, space: Space) Error!void {
1103fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.full.If, space: Space) Error!void {
12041104 const node_tags = tree.nodes.items(.tag);
12051105 const token_tags = tree.tokens.items(.tag);
12061106
......@@ -1334,7 +1234,7 @@ fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.Full.If, space: Space) Error
13341234fn renderContainerField(
13351235 ais: *Ais,
13361236 tree: ast.Tree,
1337 field: ast.Full.ContainerField,
1237 field: ast.full.ContainerField,
13381238 space: Space,
13391239) Error!void {
13401240 const main_tokens = tree.nodes.items(.main_token);
......@@ -1430,7 +1330,7 @@ fn renderBuiltinCall(
14301330 }
14311331}
14321332
1433fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.Full.FnProto, space: Space) Error!void {
1333fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: Space) Error!void {
14341334 const token_tags = tree.tokens.items(.tag);
14351335 const token_starts = tree.tokens.items(.start);
14361336
......@@ -1618,7 +1518,7 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.Full.FnProto, space: S
16181518fn renderSwitchCase(
16191519 ais: *Ais,
16201520 tree: ast.Tree,
1621 switch_case: ast.Full.SwitchCase,
1521 switch_case: ast.full.SwitchCase,
16221522 space: Space,
16231523) Error!void {
16241524 const token_tags = tree.tokens.items(.tag);
......@@ -1709,7 +1609,7 @@ fn renderBlock(
17091609fn renderStructInit(
17101610 ais: *Ais,
17111611 tree: ast.Tree,
1712 struct_init: ast.Full.StructInit,
1612 struct_init: ast.full.StructInit,
17131613 space: Space,
17141614) Error!void {
17151615 const token_tags = tree.tokens.items(.tag);
......@@ -1763,7 +1663,7 @@ fn renderStructInit(
17631663fn renderArrayInit(
17641664 ais: *Ais,
17651665 tree: ast.Tree,
1766 array_init: ast.Full.ArrayInit,
1666 array_init: ast.full.ArrayInit,
17671667 space: Space,
17681668) Error!void {
17691669 const token_tags = tree.tokens.items(.tag);
......@@ -1809,7 +1709,7 @@ fn renderArrayInit(
18091709fn renderContainerDecl(
18101710 ais: *Ais,
18111711 tree: ast.Tree,
1812 container_decl: ast.Full.ContainerDecl,
1712 container_decl: ast.full.ContainerDecl,
18131713 space: Space,
18141714) Error!void {
18151715 const token_tags = tree.tokens.items(.tag);
......@@ -1894,6 +1794,135 @@ fn renderContainerDecl(
18941794 return renderToken(ais, tree, rbrace, space); // rbrace
18951795}
18961796
1797fn renderAsm(
1798 ais: *Ais,
1799 tree: ast.Tree,
1800 asm_node: ast.full.Asm,
1801 space: Space,
1802) Error!void {
1803 const token_tags = tree.tokens.items(.tag);
1804
1805 try renderToken(ais, tree, asm_node.ast.asm_token, .Space); // asm
1806
1807 if (asm_node.volatile_token) |volatile_token| {
1808 try renderToken(ais, tree, volatile_token, .Space); // volatile
1809 try renderToken(ais, tree, volatile_token + 1, .None); // lparen
1810 } else {
1811 try renderToken(ais, tree, asm_node.ast.asm_token + 1, .None); // lparen
1812 }
1813
1814 if (asm_node.ast.items.len == 0) {
1815 try renderExpression(ais, tree, asm_node.ast.template, .None);
1816 if (asm_node.first_clobber) |first_clobber| {
1817 // asm ("foo" ::: "a", "b")
1818 var tok_i = first_clobber;
1819 while (true) : (tok_i += 1) {
1820 try renderToken(ais, tree, tok_i, .None);
1821 tok_i += 1;
1822 switch (token_tags[tok_i]) {
1823 .RParen => return renderToken(ais, tree, tok_i, space),
1824 .Comma => try renderToken(ais, tree, tok_i, .Space),
1825 else => unreachable,
1826 }
1827 }
1828 } else {
1829 // asm ("foo")
1830 return renderToken(ais, tree, asm_node.ast.rparen, space); // rparen
1831 }
1832 }
1833
1834 ais.pushIndent();
1835 try renderExpression(ais, tree, asm_node.ast.template, .Newline);
1836 ais.setIndentDelta(asm_indent_delta);
1837 const colon1 = tree.lastToken(asm_node.ast.template) + 1;
1838
1839 const colon2 = if (asm_node.outputs.len == 0) colon2: {
1840 try renderToken(ais, tree, colon1, .Newline); // :
1841 break :colon2 colon1 + 1;
1842 } else colon2: {
1843 try renderToken(ais, tree, colon1, .Space); // :
1844
1845 ais.pushIndent();
1846 for (asm_node.outputs) |asm_output, i| {
1847 if (i + 1 < asm_node.outputs.len) {
1848 const next_asm_output = asm_node.outputs[i + 1];
1849 try renderAsmOutput(ais, tree, asm_output, .None);
1850
1851 const comma = tree.firstToken(next_asm_output) - 1;
1852 try renderToken(ais, tree, comma, .Newline); // ,
1853 try renderExtraNewlineToken(ais, tree, tree.firstToken(next_asm_output));
1854 } else if (asm_node.inputs.len == 0 and asm_node.first_clobber == null) {
1855 try renderAsmOutput(ais, tree, asm_output, .Newline);
1856 ais.popIndent();
1857 ais.setIndentDelta(indent_delta);
1858 ais.popIndent();
1859 return renderToken(ais, tree, asm_node.ast.rparen, space); // rparen
1860 } else {
1861 try renderAsmOutput(ais, tree, asm_output, .Newline);
1862 const comma_or_colon = tree.lastToken(asm_output) + 1;
1863 ais.popIndent();
1864 break :colon2 switch (token_tags[comma_or_colon]) {
1865 .Comma => comma_or_colon + 1,
1866 else => comma_or_colon,
1867 };
1868 }
1869 } else unreachable;
1870 };
1871
1872 const colon3 = if (asm_node.inputs.len == 0) colon3: {
1873 try renderToken(ais, tree, colon2, .Newline); // :
1874 break :colon3 colon2 + 1;
1875 } else colon3: {
1876 try renderToken(ais, tree, colon2, .Space); // :
1877 ais.pushIndent();
1878 for (asm_node.inputs) |asm_input, i| {
1879 if (i + 1 < asm_node.inputs.len) {
1880 const next_asm_input = asm_node.inputs[i + 1];
1881 try renderAsmInput(ais, tree, asm_input, .None);
1882
1883 const first_token = tree.firstToken(next_asm_input);
1884 try renderToken(ais, tree, first_token - 1, .Newline); // ,
1885 try renderExtraNewlineToken(ais, tree, first_token);
1886 } else if (asm_node.first_clobber == null) {
1887 try renderAsmInput(ais, tree, asm_input, .Newline);
1888 ais.popIndent();
1889 ais.setIndentDelta(indent_delta);
1890 ais.popIndent();
1891 return renderToken(ais, tree, asm_node.ast.rparen, space); // rparen
1892 } else {
1893 try renderAsmInput(ais, tree, asm_input, .Newline);
1894 const comma_or_colon = tree.lastToken(asm_input) + 1;
1895 ais.popIndent();
1896 break :colon3 switch (token_tags[comma_or_colon]) {
1897 .Comma => comma_or_colon + 1,
1898 else => comma_or_colon,
1899 };
1900 }
1901 }
1902 unreachable;
1903 };
1904
1905 try renderToken(ais, tree, colon3, .Space); // :
1906 const first_clobber = asm_node.first_clobber.?;
1907 var tok_i = first_clobber;
1908 while (true) {
1909 switch (token_tags[tok_i + 1]) {
1910 .RParen => {
1911 ais.setIndentDelta(indent_delta);
1912 ais.popIndent();
1913 try renderToken(ais, tree, tok_i, .Newline);
1914 return renderToken(ais, tree, tok_i + 1, space);
1915 },
1916 .Comma => {
1917 try renderToken(ais, tree, tok_i, .None);
1918 try renderToken(ais, tree, tok_i + 1, .Space);
1919 tok_i += 2;
1920 },
1921 else => unreachable,
1922 }
1923 } else unreachable; // TODO shouldn't need this on while(true)
1924}
1925
18971926/// Render an expression, and the comma that follows it, if it is present in the source.
18981927fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
18991928 const token_tags = tree.tokens.items(.tag);