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 {...@@ -419,13 +419,16 @@ pub const Tree = struct {
419 n = extra.start;419 n = extra.start;
420 },420 },
421421
422 .AsmOutput, .AsmInput => {
423 assert(token_tags[main_tokens[n] - 1] == .LBracket);
424 return main_tokens[n] - 1;
425 },
426
422 .WhileSimple => unreachable, // TODO427 .WhileSimple => unreachable, // TODO
423 .WhileCont => unreachable, // TODO428 .WhileCont => unreachable, // TODO
424 .While => unreachable, // TODO429 .While => unreachable, // TODO
425 .ForSimple => unreachable, // TODO430 .ForSimple => unreachable, // TODO
426 .For => unreachable, // TODO431 .For => unreachable, // TODO
427 .AsmOutput => unreachable, // TODO
428 .AsmInput => unreachable, // TODO
429 .ErrorValue => unreachable, // TODO432 .ErrorValue => unreachable, // TODO
430 };433 };
431 }434 }
...@@ -515,6 +518,9 @@ pub const Tree = struct {...@@ -515,6 +518,9 @@ pub const Tree = struct {
515 .GroupedExpression,518 .GroupedExpression,
516 .StringLiteral,519 .StringLiteral,
517 .ErrorSetDecl,520 .ErrorSetDecl,
521 .AsmSimple,
522 .AsmOutput,
523 .AsmInput,
518 => return datas[n].rhs + end_offset,524 => return datas[n].rhs + end_offset,
519525
520 .AnyType,526 .AnyType,
...@@ -566,6 +572,10 @@ pub const Tree = struct {...@@ -566,6 +572,10 @@ pub const Tree = struct {
566 n = tree.extra_data[members.end - 1]; // last parameter572 n = tree.extra_data[members.end - 1]; // last parameter
567 }573 }
568 },574 },
575 .Asm => {
576 const extra = tree.extraData(datas[n].rhs, Node.Asm);
577 return extra.rparen + end_offset;
578 },
569 .ContainerDeclArgComma,579 .ContainerDeclArgComma,
570 .SwitchComma,580 .SwitchComma,
571 => {581 => {
...@@ -765,8 +775,6 @@ pub const Tree = struct {...@@ -765,8 +775,6 @@ pub const Tree = struct {
765 .TaggedUnionEnumTagComma => unreachable, // TODO775 .TaggedUnionEnumTagComma => unreachable, // TODO
766 .If => unreachable, // TODO776 .If => unreachable, // TODO
767 .Continue => unreachable, // TODO777 .Continue => unreachable, // TODO
768 .AsmSimple => unreachable, // TODO
769 .Asm => unreachable, // TODO
770 .SwitchRange => unreachable, // TODO778 .SwitchRange => unreachable, // TODO
771 .ArrayType => unreachable, // TODO779 .ArrayType => unreachable, // TODO
772 .ArrayTypeSentinel => unreachable, // TODO780 .ArrayTypeSentinel => unreachable, // TODO
...@@ -778,8 +786,6 @@ pub const Tree = struct {...@@ -778,8 +786,6 @@ pub const Tree = struct {
778 .FnProtoMulti => unreachable, // TODO786 .FnProtoMulti => unreachable, // TODO
779 .FnProtoOne => unreachable, // TODO787 .FnProtoOne => unreachable, // TODO
780 .FnProto => unreachable, // TODO788 .FnProto => unreachable, // TODO
781 .AsmOutput => unreachable, // TODO
782 .AsmInput => unreachable, // TODO
783 .ErrorValue => unreachable, // TODO789 .ErrorValue => unreachable, // TODO
784 };790 };
785 }791 }
...@@ -790,7 +796,7 @@ pub const Tree = struct {...@@ -790,7 +796,7 @@ pub const Tree = struct {
790 return mem.indexOfScalar(u8, source, '\n') == null;796 return mem.indexOfScalar(u8, source, '\n') == null;
791 }797 }
792798
793 pub fn globalVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {799 pub fn globalVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
794 assert(tree.nodes.items(.tag)[node] == .GlobalVarDecl);800 assert(tree.nodes.items(.tag)[node] == .GlobalVarDecl);
795 const data = tree.nodes.items(.data)[node];801 const data = tree.nodes.items(.data)[node];
796 const extra = tree.extraData(data.lhs, Node.GlobalVarDecl);802 const extra = tree.extraData(data.lhs, Node.GlobalVarDecl);
...@@ -803,7 +809,7 @@ pub const Tree = struct {...@@ -803,7 +809,7 @@ pub const Tree = struct {
803 });809 });
804 }810 }
805811
806 pub fn localVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {812 pub fn localVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
807 assert(tree.nodes.items(.tag)[node] == .LocalVarDecl);813 assert(tree.nodes.items(.tag)[node] == .LocalVarDecl);
808 const data = tree.nodes.items(.data)[node];814 const data = tree.nodes.items(.data)[node];
809 const extra = tree.extraData(data.lhs, Node.LocalVarDecl);815 const extra = tree.extraData(data.lhs, Node.LocalVarDecl);
...@@ -816,7 +822,7 @@ pub const Tree = struct {...@@ -816,7 +822,7 @@ pub const Tree = struct {
816 });822 });
817 }823 }
818824
819 pub fn simpleVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {825 pub fn simpleVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
820 assert(tree.nodes.items(.tag)[node] == .SimpleVarDecl);826 assert(tree.nodes.items(.tag)[node] == .SimpleVarDecl);
821 const data = tree.nodes.items(.data)[node];827 const data = tree.nodes.items(.data)[node];
822 return tree.fullVarDecl(.{828 return tree.fullVarDecl(.{
...@@ -828,7 +834,7 @@ pub const Tree = struct {...@@ -828,7 +834,7 @@ pub const Tree = struct {
828 });834 });
829 }835 }
830836
831 pub fn alignedVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {837 pub fn alignedVarDecl(tree: Tree, node: Node.Index) full.VarDecl {
832 assert(tree.nodes.items(.tag)[node] == .AlignedVarDecl);838 assert(tree.nodes.items(.tag)[node] == .AlignedVarDecl);
833 const data = tree.nodes.items(.data)[node];839 const data = tree.nodes.items(.data)[node];
834 return tree.fullVarDecl(.{840 return tree.fullVarDecl(.{
...@@ -840,7 +846,7 @@ pub const Tree = struct {...@@ -840,7 +846,7 @@ pub const Tree = struct {
840 });846 });
841 }847 }
842848
843 pub fn ifSimple(tree: Tree, node: Node.Index) Full.If {849 pub fn ifSimple(tree: Tree, node: Node.Index) full.If {
844 assert(tree.nodes.items(.tag)[node] == .IfSimple);850 assert(tree.nodes.items(.tag)[node] == .IfSimple);
845 const data = tree.nodes.items(.data)[node];851 const data = tree.nodes.items(.data)[node];
846 return tree.fullIf(.{852 return tree.fullIf(.{
...@@ -851,7 +857,7 @@ pub const Tree = struct {...@@ -851,7 +857,7 @@ pub const Tree = struct {
851 });857 });
852 }858 }
853859
854 pub fn ifFull(tree: Tree, node: Node.Index) Full.If {860 pub fn ifFull(tree: Tree, node: Node.Index) full.If {
855 assert(tree.nodes.items(.tag)[node] == .If);861 assert(tree.nodes.items(.tag)[node] == .If);
856 const data = tree.nodes.items(.data)[node];862 const data = tree.nodes.items(.data)[node];
857 const extra = tree.extraData(data.rhs, Node.If);863 const extra = tree.extraData(data.rhs, Node.If);
...@@ -863,7 +869,7 @@ pub const Tree = struct {...@@ -863,7 +869,7 @@ pub const Tree = struct {
863 });869 });
864 }870 }
865871
866 pub fn containerField(tree: Tree, node: Node.Index) Full.ContainerField {872 pub fn containerField(tree: Tree, node: Node.Index) full.ContainerField {
867 assert(tree.nodes.items(.tag)[node] == .ContainerField);873 assert(tree.nodes.items(.tag)[node] == .ContainerField);
868 const data = tree.nodes.items(.data)[node];874 const data = tree.nodes.items(.data)[node];
869 const extra = tree.extraData(data.rhs, Node.ContainerField);875 const extra = tree.extraData(data.rhs, Node.ContainerField);
...@@ -875,7 +881,7 @@ pub const Tree = struct {...@@ -875,7 +881,7 @@ pub const Tree = struct {
875 });881 });
876 }882 }
877883
878 pub fn containerFieldInit(tree: Tree, node: Node.Index) Full.ContainerField {884 pub fn containerFieldInit(tree: Tree, node: Node.Index) full.ContainerField {
879 assert(tree.nodes.items(.tag)[node] == .ContainerFieldInit);885 assert(tree.nodes.items(.tag)[node] == .ContainerFieldInit);
880 const data = tree.nodes.items(.data)[node];886 const data = tree.nodes.items(.data)[node];
881 return tree.fullContainerField(.{887 return tree.fullContainerField(.{
...@@ -886,7 +892,7 @@ pub const Tree = struct {...@@ -886,7 +892,7 @@ pub const Tree = struct {
886 });892 });
887 }893 }
888894
889 pub fn containerFieldAlign(tree: Tree, node: Node.Index) Full.ContainerField {895 pub fn containerFieldAlign(tree: Tree, node: Node.Index) full.ContainerField {
890 assert(tree.nodes.items(.tag)[node] == .ContainerFieldAlign);896 assert(tree.nodes.items(.tag)[node] == .ContainerFieldAlign);
891 const data = tree.nodes.items(.data)[node];897 const data = tree.nodes.items(.data)[node];
892 return tree.fullContainerField(.{898 return tree.fullContainerField(.{
...@@ -897,7 +903,7 @@ pub const Tree = struct {...@@ -897,7 +903,7 @@ pub const Tree = struct {
897 });903 });
898 }904 }
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 {
901 assert(tree.nodes.items(.tag)[node] == .FnProtoSimple);907 assert(tree.nodes.items(.tag)[node] == .FnProtoSimple);
902 const data = tree.nodes.items(.data)[node];908 const data = tree.nodes.items(.data)[node];
903 buffer[0] = data.lhs;909 buffer[0] = data.lhs;
...@@ -912,7 +918,7 @@ pub const Tree = struct {...@@ -912,7 +918,7 @@ pub const Tree = struct {
912 });918 });
913 }919 }
914920
915 pub fn fnProtoMulti(tree: Tree, node: Node.Index) Full.FnProto {921 pub fn fnProtoMulti(tree: Tree, node: Node.Index) full.FnProto {
916 assert(tree.nodes.items(.tag)[node] == .FnProtoMulti);922 assert(tree.nodes.items(.tag)[node] == .FnProtoMulti);
917 const data = tree.nodes.items(.data)[node];923 const data = tree.nodes.items(.data)[node];
918 const params_range = tree.extraData(data.lhs, Node.SubRange);924 const params_range = tree.extraData(data.lhs, Node.SubRange);
...@@ -927,7 +933,7 @@ pub const Tree = struct {...@@ -927,7 +933,7 @@ pub const Tree = struct {
927 });933 });
928 }934 }
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 {
931 assert(tree.nodes.items(.tag)[node] == .FnProtoOne);937 assert(tree.nodes.items(.tag)[node] == .FnProtoOne);
932 const data = tree.nodes.items(.data)[node];938 const data = tree.nodes.items(.data)[node];
933 const extra = tree.extraData(data.lhs, Node.FnProtoOne);939 const extra = tree.extraData(data.lhs, Node.FnProtoOne);
...@@ -943,7 +949,7 @@ pub const Tree = struct {...@@ -943,7 +949,7 @@ pub const Tree = struct {
943 });949 });
944 }950 }
945951
946 pub fn fnProto(tree: Tree, node: Node.Index) Full.FnProto {952 pub fn fnProto(tree: Tree, node: Node.Index) full.FnProto {
947 assert(tree.nodes.items(.tag)[node] == .FnProto);953 assert(tree.nodes.items(.tag)[node] == .FnProto);
948 const data = tree.nodes.items(.data)[node];954 const data = tree.nodes.items(.data)[node];
949 const extra = tree.extraData(data.lhs, Node.FnProto);955 const extra = tree.extraData(data.lhs, Node.FnProto);
...@@ -958,7 +964,7 @@ pub const Tree = struct {...@@ -958,7 +964,7 @@ pub const Tree = struct {
958 });964 });
959 }965 }
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 {
962 assert(tree.nodes.items(.tag)[node] == .StructInitOne);968 assert(tree.nodes.items(.tag)[node] == .StructInitOne);
963 const data = tree.nodes.items(.data)[node];969 const data = tree.nodes.items(.data)[node];
964 buffer[0] = data.rhs;970 buffer[0] = data.rhs;
...@@ -970,7 +976,7 @@ pub const Tree = struct {...@@ -970,7 +976,7 @@ pub const Tree = struct {
970 });976 });
971 }977 }
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 {
974 assert(tree.nodes.items(.tag)[node] == .StructInitDotTwo or980 assert(tree.nodes.items(.tag)[node] == .StructInitDotTwo or
975 tree.nodes.items(.tag)[node] == .StructInitDotTwoComma);981 tree.nodes.items(.tag)[node] == .StructInitDotTwoComma);
976 const data = tree.nodes.items(.data)[node];982 const data = tree.nodes.items(.data)[node];
...@@ -988,7 +994,7 @@ pub const Tree = struct {...@@ -988,7 +994,7 @@ pub const Tree = struct {
988 });994 });
989 }995 }
990996
991 pub fn structInitDot(tree: Tree, node: Node.Index) Full.StructInit {997 pub fn structInitDot(tree: Tree, node: Node.Index) full.StructInit {
992 assert(tree.nodes.items(.tag)[node] == .StructInitDot);998 assert(tree.nodes.items(.tag)[node] == .StructInitDot);
993 const data = tree.nodes.items(.data)[node];999 const data = tree.nodes.items(.data)[node];
994 return tree.fullStructInit(.{1000 return tree.fullStructInit(.{
...@@ -998,7 +1004,7 @@ pub const Tree = struct {...@@ -998,7 +1004,7 @@ pub const Tree = struct {
998 });1004 });
999 }1005 }
10001006
1001 pub fn structInit(tree: Tree, node: Node.Index) Full.StructInit {1007 pub fn structInit(tree: Tree, node: Node.Index) full.StructInit {
1002 assert(tree.nodes.items(.tag)[node] == .StructInit);1008 assert(tree.nodes.items(.tag)[node] == .StructInit);
1003 const data = tree.nodes.items(.data)[node];1009 const data = tree.nodes.items(.data)[node];
1004 const fields_range = tree.extraData(data.rhs, Node.SubRange);1010 const fields_range = tree.extraData(data.rhs, Node.SubRange);
...@@ -1009,7 +1015,7 @@ pub const Tree = struct {...@@ -1009,7 +1015,7 @@ pub const Tree = struct {
1009 });1015 });
1010 }1016 }
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 {
1013 assert(tree.nodes.items(.tag)[node] == .ArrayInitOne);1019 assert(tree.nodes.items(.tag)[node] == .ArrayInitOne);
1014 const data = tree.nodes.items(.data)[node];1020 const data = tree.nodes.items(.data)[node];
1015 buffer[0] = data.rhs;1021 buffer[0] = data.rhs;
...@@ -1023,7 +1029,7 @@ pub const Tree = struct {...@@ -1023,7 +1029,7 @@ pub const Tree = struct {
1023 };1029 };
1024 }1030 }
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 {
1027 assert(tree.nodes.items(.tag)[node] == .ArrayInitDotTwo or1033 assert(tree.nodes.items(.tag)[node] == .ArrayInitDotTwo or
1028 tree.nodes.items(.tag)[node] == .ArrayInitDotTwoComma);1034 tree.nodes.items(.tag)[node] == .ArrayInitDotTwoComma);
1029 const data = tree.nodes.items(.data)[node];1035 const data = tree.nodes.items(.data)[node];
...@@ -1043,7 +1049,7 @@ pub const Tree = struct {...@@ -1043,7 +1049,7 @@ pub const Tree = struct {
1043 };1049 };
1044 }1050 }
10451051
1046 pub fn arrayInitDot(tree: Tree, node: Node.Index) Full.ArrayInit {1052 pub fn arrayInitDot(tree: Tree, node: Node.Index) full.ArrayInit {
1047 assert(tree.nodes.items(.tag)[node] == .ArrayInitDot);1053 assert(tree.nodes.items(.tag)[node] == .ArrayInitDot);
1048 const data = tree.nodes.items(.data)[node];1054 const data = tree.nodes.items(.data)[node];
1049 return .{1055 return .{
...@@ -1055,7 +1061,7 @@ pub const Tree = struct {...@@ -1055,7 +1061,7 @@ pub const Tree = struct {
1055 };1061 };
1056 }1062 }
10571063
1058 pub fn arrayInit(tree: Tree, node: Node.Index) Full.ArrayInit {1064 pub fn arrayInit(tree: Tree, node: Node.Index) full.ArrayInit {
1059 assert(tree.nodes.items(.tag)[node] == .ArrayInit);1065 assert(tree.nodes.items(.tag)[node] == .ArrayInit);
1060 const data = tree.nodes.items(.data)[node];1066 const data = tree.nodes.items(.data)[node];
1061 const elem_range = tree.extraData(data.rhs, Node.SubRange);1067 const elem_range = tree.extraData(data.rhs, Node.SubRange);
...@@ -1068,7 +1074,7 @@ pub const Tree = struct {...@@ -1068,7 +1074,7 @@ pub const Tree = struct {
1068 };1074 };
1069 }1075 }
10701076
1071 pub fn arrayType(tree: Tree, node: Node.Index) Full.ArrayType {1077 pub fn arrayType(tree: Tree, node: Node.Index) full.ArrayType {
1072 assert(tree.nodes.items(.tag)[node] == .ArrayType);1078 assert(tree.nodes.items(.tag)[node] == .ArrayType);
1073 const data = tree.nodes.items(.data)[node];1079 const data = tree.nodes.items(.data)[node];
1074 return .{1080 return .{
...@@ -1081,7 +1087,7 @@ pub const Tree = struct {...@@ -1081,7 +1087,7 @@ pub const Tree = struct {
1081 };1087 };
1082 }1088 }
10831089
1084 pub fn arrayTypeSentinel(tree: Tree, node: Node.Index) Full.ArrayType {1090 pub fn arrayTypeSentinel(tree: Tree, node: Node.Index) full.ArrayType {
1085 assert(tree.nodes.items(.tag)[node] == .ArrayTypeSentinel);1091 assert(tree.nodes.items(.tag)[node] == .ArrayTypeSentinel);
1086 const data = tree.nodes.items(.data)[node];1092 const data = tree.nodes.items(.data)[node];
1087 const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel);1093 const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel);
...@@ -1095,7 +1101,7 @@ pub const Tree = struct {...@@ -1095,7 +1101,7 @@ pub const Tree = struct {
1095 };1101 };
1096 }1102 }
10971103
1098 pub fn ptrTypeAligned(tree: Tree, node: Node.Index) Full.PtrType {1104 pub fn ptrTypeAligned(tree: Tree, node: Node.Index) full.PtrType {
1099 assert(tree.nodes.items(.tag)[node] == .PtrTypeAligned);1105 assert(tree.nodes.items(.tag)[node] == .PtrTypeAligned);
1100 const data = tree.nodes.items(.data)[node];1106 const data = tree.nodes.items(.data)[node];
1101 return tree.fullPtrType(.{1107 return tree.fullPtrType(.{
...@@ -1108,7 +1114,7 @@ pub const Tree = struct {...@@ -1108,7 +1114,7 @@ pub const Tree = struct {
1108 });1114 });
1109 }1115 }
11101116
1111 pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) Full.PtrType {1117 pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) full.PtrType {
1112 assert(tree.nodes.items(.tag)[node] == .PtrTypeSentinel);1118 assert(tree.nodes.items(.tag)[node] == .PtrTypeSentinel);
1113 const data = tree.nodes.items(.data)[node];1119 const data = tree.nodes.items(.data)[node];
1114 return tree.fullPtrType(.{1120 return tree.fullPtrType(.{
...@@ -1121,7 +1127,7 @@ pub const Tree = struct {...@@ -1121,7 +1127,7 @@ pub const Tree = struct {
1121 });1127 });
1122 }1128 }
11231129
1124 pub fn ptrType(tree: Tree, node: Node.Index) Full.PtrType {1130 pub fn ptrType(tree: Tree, node: Node.Index) full.PtrType {
1125 assert(tree.nodes.items(.tag)[node] == .PtrType);1131 assert(tree.nodes.items(.tag)[node] == .PtrType);
1126 const data = tree.nodes.items(.data)[node];1132 const data = tree.nodes.items(.data)[node];
1127 const extra = tree.extraData(data.lhs, Node.PtrType);1133 const extra = tree.extraData(data.lhs, Node.PtrType);
...@@ -1135,7 +1141,7 @@ pub const Tree = struct {...@@ -1135,7 +1141,7 @@ pub const Tree = struct {
1135 });1141 });
1136 }1142 }
11371143
1138 pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) Full.PtrType {1144 pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) full.PtrType {
1139 assert(tree.nodes.items(.tag)[node] == .PtrTypeBitRange);1145 assert(tree.nodes.items(.tag)[node] == .PtrTypeBitRange);
1140 const data = tree.nodes.items(.data)[node];1146 const data = tree.nodes.items(.data)[node];
1141 const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange);1147 const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange);
...@@ -1149,7 +1155,7 @@ pub const Tree = struct {...@@ -1149,7 +1155,7 @@ pub const Tree = struct {
1149 });1155 });
1150 }1156 }
11511157
1152 pub fn sliceOpen(tree: Tree, node: Node.Index) Full.Slice {1158 pub fn sliceOpen(tree: Tree, node: Node.Index) full.Slice {
1153 assert(tree.nodes.items(.tag)[node] == .SliceOpen);1159 assert(tree.nodes.items(.tag)[node] == .SliceOpen);
1154 const data = tree.nodes.items(.data)[node];1160 const data = tree.nodes.items(.data)[node];
1155 return .{1161 return .{
...@@ -1163,7 +1169,7 @@ pub const Tree = struct {...@@ -1163,7 +1169,7 @@ pub const Tree = struct {
1163 };1169 };
1164 }1170 }
11651171
1166 pub fn slice(tree: Tree, node: Node.Index) Full.Slice {1172 pub fn slice(tree: Tree, node: Node.Index) full.Slice {
1167 assert(tree.nodes.items(.tag)[node] == .Slice);1173 assert(tree.nodes.items(.tag)[node] == .Slice);
1168 const data = tree.nodes.items(.data)[node];1174 const data = tree.nodes.items(.data)[node];
1169 const extra = tree.extraData(data.rhs, Node.Slice);1175 const extra = tree.extraData(data.rhs, Node.Slice);
...@@ -1178,7 +1184,7 @@ pub const Tree = struct {...@@ -1178,7 +1184,7 @@ pub const Tree = struct {
1178 };1184 };
1179 }1185 }
11801186
1181 pub fn sliceSentinel(tree: Tree, node: Node.Index) Full.Slice {1187 pub fn sliceSentinel(tree: Tree, node: Node.Index) full.Slice {
1182 assert(tree.nodes.items(.tag)[node] == .SliceSentinel);1188 assert(tree.nodes.items(.tag)[node] == .SliceSentinel);
1183 const data = tree.nodes.items(.data)[node];1189 const data = tree.nodes.items(.data)[node];
1184 const extra = tree.extraData(data.rhs, Node.SliceSentinel);1190 const extra = tree.extraData(data.rhs, Node.SliceSentinel);
...@@ -1193,7 +1199,7 @@ pub const Tree = struct {...@@ -1193,7 +1199,7 @@ pub const Tree = struct {
1193 };1199 };
1194 }1200 }
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 {
1197 assert(tree.nodes.items(.tag)[node] == .ContainerDeclTwo or1203 assert(tree.nodes.items(.tag)[node] == .ContainerDeclTwo or
1198 tree.nodes.items(.tag)[node] == .ContainerDeclTwoComma);1204 tree.nodes.items(.tag)[node] == .ContainerDeclTwoComma);
1199 const data = tree.nodes.items(.data)[node];1205 const data = tree.nodes.items(.data)[node];
...@@ -1212,7 +1218,7 @@ pub const Tree = struct {...@@ -1212,7 +1218,7 @@ pub const Tree = struct {
1212 });1218 });
1213 }1219 }
12141220
1215 pub fn containerDecl(tree: Tree, node: Node.Index) Full.ContainerDecl {1221 pub fn containerDecl(tree: Tree, node: Node.Index) full.ContainerDecl {
1216 assert(tree.nodes.items(.tag)[node] == .ContainerDecl or1222 assert(tree.nodes.items(.tag)[node] == .ContainerDecl or
1217 tree.nodes.items(.tag)[node] == .ContainerDeclComma);1223 tree.nodes.items(.tag)[node] == .ContainerDeclComma);
1218 const data = tree.nodes.items(.data)[node];1224 const data = tree.nodes.items(.data)[node];
...@@ -1224,7 +1230,7 @@ pub const Tree = struct {...@@ -1224,7 +1230,7 @@ pub const Tree = struct {
1224 });1230 });
1225 }1231 }
12261232
1227 pub fn containerDeclArg(tree: Tree, node: Node.Index) Full.ContainerDecl {1233 pub fn containerDeclArg(tree: Tree, node: Node.Index) full.ContainerDecl {
1228 assert(tree.nodes.items(.tag)[node] == .ContainerDeclArg or1234 assert(tree.nodes.items(.tag)[node] == .ContainerDeclArg or
1229 tree.nodes.items(.tag)[node] == .ContainerDeclArgComma);1235 tree.nodes.items(.tag)[node] == .ContainerDeclArgComma);
1230 const data = tree.nodes.items(.data)[node];1236 const data = tree.nodes.items(.data)[node];
...@@ -1237,7 +1243,7 @@ pub const Tree = struct {...@@ -1237,7 +1243,7 @@ pub const Tree = struct {
1237 });1243 });
1238 }1244 }
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 {
1241 assert(tree.nodes.items(.tag)[node] == .TaggedUnionTwo or1247 assert(tree.nodes.items(.tag)[node] == .TaggedUnionTwo or
1242 tree.nodes.items(.tag)[node] == .TaggedUnionTwoComma);1248 tree.nodes.items(.tag)[node] == .TaggedUnionTwoComma);
1243 const data = tree.nodes.items(.data)[node];1249 const data = tree.nodes.items(.data)[node];
...@@ -1257,7 +1263,7 @@ pub const Tree = struct {...@@ -1257,7 +1263,7 @@ pub const Tree = struct {
1257 });1263 });
1258 }1264 }
12591265
1260 pub fn taggedUnion(tree: Tree, node: Node.Index) Full.ContainerDecl {1266 pub fn taggedUnion(tree: Tree, node: Node.Index) full.ContainerDecl {
1261 assert(tree.nodes.items(.tag)[node] == .TaggedUnion or1267 assert(tree.nodes.items(.tag)[node] == .TaggedUnion or
1262 tree.nodes.items(.tag)[node] == .TaggedUnionComma);1268 tree.nodes.items(.tag)[node] == .TaggedUnionComma);
1263 const data = tree.nodes.items(.data)[node];1269 const data = tree.nodes.items(.data)[node];
...@@ -1270,7 +1276,7 @@ pub const Tree = struct {...@@ -1270,7 +1276,7 @@ pub const Tree = struct {
1270 });1276 });
1271 }1277 }
12721278
1273 pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) Full.ContainerDecl {1279 pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) full.ContainerDecl {
1274 assert(tree.nodes.items(.tag)[node] == .TaggedUnionEnumTag or1280 assert(tree.nodes.items(.tag)[node] == .TaggedUnionEnumTag or
1275 tree.nodes.items(.tag)[node] == .TaggedUnionEnumTagComma);1281 tree.nodes.items(.tag)[node] == .TaggedUnionEnumTagComma);
1276 const data = tree.nodes.items(.data)[node];1282 const data = tree.nodes.items(.data)[node];
...@@ -1284,7 +1290,7 @@ pub const Tree = struct {...@@ -1284,7 +1290,7 @@ pub const Tree = struct {
1284 });1290 });
1285 }1291 }
12861292
1287 pub fn switchCaseOne(tree: Tree, node: Node.Index) Full.SwitchCase {1293 pub fn switchCaseOne(tree: Tree, node: Node.Index) full.SwitchCase {
1288 const data = &tree.nodes.items(.data)[node];1294 const data = &tree.nodes.items(.data)[node];
1289 return tree.fullSwitchCase(.{1295 return tree.fullSwitchCase(.{
1290 .values = if (data.lhs == 0) &.{} else @ptrCast([*]Node.Index, &data.lhs)[0..1],1296 .values = if (data.lhs == 0) &.{} else @ptrCast([*]Node.Index, &data.lhs)[0..1],
...@@ -1293,7 +1299,7 @@ pub const Tree = struct {...@@ -1293,7 +1299,7 @@ pub const Tree = struct {
1293 });1299 });
1294 }1300 }
12951301
1296 pub fn switchCase(tree: Tree, node: Node.Index) Full.SwitchCase {1302 pub fn switchCase(tree: Tree, node: Node.Index) full.SwitchCase {
1297 const data = tree.nodes.items(.data)[node];1303 const data = tree.nodes.items(.data)[node];
1298 const extra = tree.extraData(data.lhs, Node.SubRange);1304 const extra = tree.extraData(data.lhs, Node.SubRange);
1299 return tree.fullSwitchCase(.{1305 return tree.fullSwitchCase(.{
...@@ -1303,9 +1309,30 @@ pub const Tree = struct {...@@ -1303,9 +1309,30 @@ pub const Tree = struct {
1303 });1309 });
1304 }1310 }
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 {
1307 const token_tags = tree.tokens.items(.tag);1334 const token_tags = tree.tokens.items(.tag);
1308 var result: Full.VarDecl = .{1335 var result: full.VarDecl = .{
1309 .ast = info,1336 .ast = info,
1310 .visib_token = null,1337 .visib_token = null,
1311 .extern_export_token = null,1338 .extern_export_token = null,
...@@ -1328,9 +1355,9 @@ pub const Tree = struct {...@@ -1328,9 +1355,9 @@ pub const Tree = struct {
1328 return result;1355 return result;
1329 }1356 }
13301357
1331 fn fullIf(tree: Tree, info: Full.If.Ast) Full.If {1358 fn fullIf(tree: Tree, info: full.If.Ast) full.If {
1332 const token_tags = tree.tokens.items(.tag);1359 const token_tags = tree.tokens.items(.tag);
1333 var result: Full.If = .{1360 var result: full.If = .{
1334 .ast = info,1361 .ast = info,
1335 .payload_token = null,1362 .payload_token = null,
1336 .error_token = null,1363 .error_token = null,
...@@ -1353,9 +1380,9 @@ pub const Tree = struct {...@@ -1353,9 +1380,9 @@ pub const Tree = struct {
1353 return result;1380 return result;
1354 }1381 }
13551382
1356 fn fullContainerField(tree: Tree, info: Full.ContainerField.Ast) Full.ContainerField {1383 fn fullContainerField(tree: Tree, info: full.ContainerField.Ast) full.ContainerField {
1357 const token_tags = tree.tokens.items(.tag);1384 const token_tags = tree.tokens.items(.tag);
1358 var result: Full.ContainerField = .{1385 var result: full.ContainerField = .{
1359 .ast = info,1386 .ast = info,
1360 .comptime_token = null,1387 .comptime_token = null,
1361 };1388 };
...@@ -1367,27 +1394,27 @@ pub const Tree = struct {...@@ -1367,27 +1394,27 @@ pub const Tree = struct {
1367 return result;1394 return result;
1368 }1395 }
13691396
1370 fn fullFnProto(tree: Tree, info: Full.FnProto.Ast) Full.FnProto {1397 fn fullFnProto(tree: Tree, info: full.FnProto.Ast) full.FnProto {
1371 const token_tags = tree.tokens.items(.tag);1398 const token_tags = tree.tokens.items(.tag);
1372 var result: Full.FnProto = .{1399 var result: full.FnProto = .{
1373 .ast = info,1400 .ast = info,
1374 };1401 };
1375 return result;1402 return result;
1376 }1403 }
13771404
1378 fn fullStructInit(tree: Tree, info: Full.StructInit.Ast) Full.StructInit {1405 fn fullStructInit(tree: Tree, info: full.StructInit.Ast) full.StructInit {
1379 const token_tags = tree.tokens.items(.tag);1406 const token_tags = tree.tokens.items(.tag);
1380 var result: Full.StructInit = .{1407 var result: full.StructInit = .{
1381 .ast = info,1408 .ast = info,
1382 };1409 };
1383 return result;1410 return result;
1384 }1411 }
13851412
1386 fn fullPtrType(tree: Tree, info: Full.PtrType.Ast) Full.PtrType {1413 fn fullPtrType(tree: Tree, info: full.PtrType.Ast) full.PtrType {
1387 const token_tags = tree.tokens.items(.tag);1414 const token_tags = tree.tokens.items(.tag);
1388 // TODO: looks like stage1 isn't quite smart enough to handle enum1415 // TODO: looks like stage1 isn't quite smart enough to handle enum
1389 // literals in some places here1416 // literals in some places here
1390 const Kind = Full.PtrType.Kind;1417 const Kind = full.PtrType.Kind;
1391 const kind: Kind = switch (token_tags[info.main_token]) {1418 const kind: Kind = switch (token_tags[info.main_token]) {
1392 .Asterisk => switch (token_tags[info.main_token + 1]) {1419 .Asterisk => switch (token_tags[info.main_token + 1]) {
1393 .RBracket => .many,1420 .RBracket => .many,
...@@ -1402,7 +1429,7 @@ pub const Tree = struct {...@@ -1402,7 +1429,7 @@ pub const Tree = struct {
1402 },1429 },
1403 else => unreachable,1430 else => unreachable,
1404 };1431 };
1405 var result: Full.PtrType = .{1432 var result: full.PtrType = .{
1406 .kind = kind,1433 .kind = kind,
1407 .allowzero_token = null,1434 .allowzero_token = null,
1408 .const_token = null,1435 .const_token = null,
...@@ -1441,9 +1468,9 @@ pub const Tree = struct {...@@ -1441,9 +1468,9 @@ pub const Tree = struct {
1441 return result;1468 return result;
1442 }1469 }
14431470
1444 fn fullContainerDecl(tree: Tree, info: Full.ContainerDecl.Ast) Full.ContainerDecl {1471 fn fullContainerDecl(tree: Tree, info: full.ContainerDecl.Ast) full.ContainerDecl {
1445 const token_tags = tree.tokens.items(.tag);1472 const token_tags = tree.tokens.items(.tag);
1446 var result: Full.ContainerDecl = .{1473 var result: full.ContainerDecl = .{
1447 .ast = info,1474 .ast = info,
1448 .layout_token = null,1475 .layout_token = null,
1449 };1476 };
...@@ -1454,9 +1481,9 @@ pub const Tree = struct {...@@ -1454,9 +1481,9 @@ pub const Tree = struct {
1454 return result;1481 return result;
1455 }1482 }
14561483
1457 fn fullSwitchCase(tree: Tree, info: Full.SwitchCase.Ast) Full.SwitchCase {1484 fn fullSwitchCase(tree: Tree, info: full.SwitchCase.Ast) full.SwitchCase {
1458 const token_tags = tree.tokens.items(.tag);1485 const token_tags = tree.tokens.items(.tag);
1459 var result: Full.SwitchCase = .{1486 var result: full.SwitchCase = .{
1460 .ast = info,1487 .ast = info,
1461 .payload_token = null,1488 .payload_token = null,
1462 };1489 };
...@@ -1465,10 +1492,67 @@ pub const Tree = struct {...@@ -1465,10 +1492,67 @@ pub const Tree = struct {
1465 }1492 }
1466 return result;1493 return result;
1467 }1494 }
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 }
1468};1552};
14691553
1470/// Fully assembled AST node information.1554/// Fully assembled AST node information.
1471pub const Full = struct {1555pub const full = struct {
1472 pub const VarDecl = struct {1556 pub const VarDecl = struct {
1473 visib_token: ?TokenIndex,1557 visib_token: ?TokenIndex,
1474 extern_export_token: ?TokenIndex,1558 extern_export_token: ?TokenIndex,
...@@ -1624,6 +1708,21 @@ pub const Full = struct {...@@ -1624,6 +1708,21 @@ pub const Full = struct {
1624 target_expr: Node.Index,1708 target_expr: Node.Index,
1625 };1709 };
1626 };1710 };
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 };
1627};1726};
16281727
1629pub const Error = union(enum) {1728pub const Error = union(enum) {
...@@ -2234,15 +2333,15 @@ pub const Node = struct {...@@ -2234,15 +2333,15 @@ pub const Node = struct {
2234 Block,2333 Block,
2235 /// Same as BlockTwo but there is known to be a semicolon before the rbrace.2334 /// Same as BlockTwo but there is known to be a semicolon before the rbrace.
2236 BlockSemicolon,2335 BlockSemicolon,
2237 /// `asm(lhs)`. rhs unused.2336 /// `asm(lhs)`. rhs is the token index of the rparen.
2238 AsmSimple,2337 AsmSimple,
2239 /// `asm(lhs, a)`. `sub_range_list[rhs]`.2338 /// `asm(lhs, a)`. `Asm[rhs]`.
2240 Asm,2339 Asm,
2241 /// `[a] "b" (c)`. lhs is string literal token index, rhs is 0.2340 /// `[a] "b" (c)`. lhs is 0, rhs is token index of the rparen.
2242 /// `[a] "b" (-> rhs)`. lhs is the string literal token index, rhs is type expr.2341 /// `[a] "b" (-> lhs)`. rhs is token index of the rparen.
2243 /// main_token is `a`.2342 /// main_token is `a`.
2244 AsmOutput,2343 AsmOutput,
2245 /// `[a] "b" (rhs)`. lhs is string literal token index.2344 /// `[a] "b" (lhs)`. rhs is token index of the rparen.
2246 /// main_token is `a`.2345 /// main_token is `a`.
2247 AsmInput,2346 AsmInput,
2248 /// `error.a`. lhs is token index of `.`. rhs is token index of `a`.2347 /// `error.a`. lhs is token index of `.`. rhs is token index of `a`.
...@@ -2355,4 +2454,11 @@ pub const Node = struct {...@@ -2355,4 +2454,11 @@ pub const Node = struct {
2355 /// Populated if callconv(A) is present.2454 /// Populated if callconv(A) is present.
2356 callconv_expr: Index,2455 callconv_expr: Index,
2357 };2456 };
2457
2458 pub const Asm = struct {
2459 items_start: Index,
2460 items_end: Index,
2461 /// Needed to make lastToken() work.
2462 rparen: TokenIndex,
2463 };
2358};2464};
lib/std/zig/parse.zig+27-19
...@@ -472,7 +472,7 @@ const Parser = struct {...@@ -472,7 +472,7 @@ const Parser = struct {
472472
473 /// TestDecl <- KEYWORD_test STRINGLITERALSINGLE? Block473 /// TestDecl <- KEYWORD_test STRINGLITERALSINGLE? Block
474 fn expectTestDecl(p: *Parser) !Node.Index {474 fn expectTestDecl(p: *Parser) !Node.Index {
475 const test_token = try p.expectToken(.Keyword_test);475 const test_token = p.assertToken(.Keyword_test);
476 const name_token = p.eatToken(.StringLiteral);476 const name_token = p.eatToken(.StringLiteral);
477 const block_node = try p.parseBlock();477 const block_node = try p.parseBlock();
478 if (block_node == 0) return p.fail(.{ .ExpectedLBrace = .{ .token = p.tok_i } });478 if (block_node == 0) return p.fail(.{ .ExpectedLBrace = .{ .token = p.tok_i } });
...@@ -739,7 +739,7 @@ const Parser = struct {...@@ -739,7 +739,7 @@ const Parser = struct {
739 /// ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?739 /// ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
740 fn expectContainerField(p: *Parser) !Node.Index {740 fn expectContainerField(p: *Parser) !Node.Index {
741 const comptime_token = p.eatToken(.Keyword_comptime);741 const comptime_token = p.eatToken(.Keyword_comptime);
742 const name_token = try p.expectToken(.Identifier);742 const name_token = p.assertToken(.Identifier);
743743
744 var align_expr: Node.Index = 0;744 var align_expr: Node.Index = 0;
745 var type_expr: Node.Index = 0;745 var type_expr: Node.Index = 0;
...@@ -1846,7 +1846,7 @@ const Parser = struct {...@@ -1846,7 +1846,7 @@ const Parser = struct {
1846 /// / CurlySuffixExpr1846 /// / CurlySuffixExpr
1847 fn parsePrimaryExpr(p: *Parser) !Node.Index {1847 fn parsePrimaryExpr(p: *Parser) !Node.Index {
1848 switch (p.token_tags[p.tok_i]) {1848 switch (p.token_tags[p.tok_i]) {
1849 .Keyword_asm => return p.parseAsmExpr(),1849 .Keyword_asm => return p.expectAsmExpr(),
1850 .Keyword_if => return p.parseIfExpr(),1850 .Keyword_if => return p.parseIfExpr(),
1851 .Keyword_break => {1851 .Keyword_break => {
1852 p.tok_i += 1;1852 p.tok_i += 1;
...@@ -2910,19 +2910,19 @@ const Parser = struct {...@@ -2910,19 +2910,19 @@ const Parser = struct {
2910 /// StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL?2910 /// StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL?
2911 /// AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem?2911 /// AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem?
2912 /// AsmInputList <- (AsmInputItem COMMA)* AsmInputItem?2912 /// AsmInputList <- (AsmInputItem COMMA)* AsmInputItem?
2913 fn parseAsmExpr(p: *Parser) !Node.Index {2913 fn expectAsmExpr(p: *Parser) !Node.Index {
2914 const asm_token = p.assertToken(.Keyword_asm);2914 const asm_token = p.assertToken(.Keyword_asm);
2915 _ = p.eatToken(.Keyword_volatile);2915 _ = p.eatToken(.Keyword_volatile);
2916 _ = try p.expectToken(.LParen);2916 _ = try p.expectToken(.LParen);
2917 const template = try p.expectExpr();2917 const template = try p.expectExpr();
29182918
2919 if (p.eatToken(.RParen)) |_| {2919 if (p.eatToken(.RParen)) |rparen| {
2920 return p.addNode(.{2920 return p.addNode(.{
2921 .tag = .AsmSimple,2921 .tag = .AsmSimple,
2922 .main_token = asm_token,2922 .main_token = asm_token,
2923 .data = .{2923 .data = .{
2924 .lhs = template,2924 .lhs = template,
2925 .rhs = undefined,2925 .rhs = rparen,
2926 },2926 },
2927 });2927 });
2928 }2928 }
...@@ -2981,16 +2981,17 @@ const Parser = struct {...@@ -2981,16 +2981,17 @@ const Parser = struct {
2981 }2981 }
2982 }2982 }
2983 }2983 }
2984 _ = try p.expectToken(.RParen);2984 const rparen = try p.expectToken(.RParen);
2985 const span = try p.listToSpan(list.items);2985 const span = try p.listToSpan(list.items);
2986 return p.addNode(.{2986 return p.addNode(.{
2987 .tag = .Asm,2987 .tag = .Asm,
2988 .main_token = asm_token,2988 .main_token = asm_token,
2989 .data = .{2989 .data = .{
2990 .lhs = template,2990 .lhs = template,
2991 .rhs = try p.addExtra(Node.SubRange{2991 .rhs = try p.addExtra(Node.Asm{
2992 .start = span.start,2992 .items_start = span.start,
2993 .end = span.end,2993 .items_end = span.end,
2994 .rparen = rparen,
2994 }),2995 }),
2995 },2996 },
2996 });2997 });
...@@ -3001,16 +3002,23 @@ const Parser = struct {...@@ -3001,16 +3002,23 @@ const Parser = struct {
3001 _ = p.eatToken(.LBracket) orelse return null_node;3002 _ = p.eatToken(.LBracket) orelse return null_node;
3002 const identifier = try p.expectToken(.Identifier);3003 const identifier = try p.expectToken(.Identifier);
3003 _ = try p.expectToken(.RBracket);3004 _ = try p.expectToken(.RBracket);
3004 const constraint = try p.expectToken(.StringLiteral);3005 _ = try p.expectToken(.StringLiteral);
3005 _ = try p.expectToken(.LParen);3006 _ = try p.expectToken(.LParen);
3006 const rhs: Node.Index = if (p.eatToken(.Arrow)) |_| try p.expectTypeExpr() else null_node;3007 const type_expr: Node.Index = blk: {
3007 _ = try p.expectToken(.RParen);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);
3008 return p.addNode(.{3016 return p.addNode(.{
3009 .tag = .AsmOutput,3017 .tag = .AsmOutput,
3010 .main_token = identifier,3018 .main_token = identifier,
3011 .data = .{3019 .data = .{
3012 .lhs = constraint,3020 .lhs = type_expr,
3013 .rhs = rhs,3021 .rhs = rparen,
3014 },3022 },
3015 });3023 });
3016 }3024 }
...@@ -3020,16 +3028,16 @@ const Parser = struct {...@@ -3020,16 +3028,16 @@ const Parser = struct {
3020 _ = p.eatToken(.LBracket) orelse return null_node;3028 _ = p.eatToken(.LBracket) orelse return null_node;
3021 const identifier = try p.expectToken(.Identifier);3029 const identifier = try p.expectToken(.Identifier);
3022 _ = try p.expectToken(.RBracket);3030 _ = try p.expectToken(.RBracket);
3023 const constraint = try p.expectToken(.StringLiteral);3031 _ = try p.expectToken(.StringLiteral);
3024 _ = try p.expectToken(.LParen);3032 _ = try p.expectToken(.LParen);
3025 const expr = try p.expectExpr();3033 const expr = try p.expectExpr();
3026 _ = try p.expectToken(.RParen);3034 const rparen = try p.expectToken(.RParen);
3027 return p.addNode(.{3035 return p.addNode(.{
3028 .tag = .AsmInput,3036 .tag = .AsmInput,
3029 .main_token = identifier,3037 .main_token = identifier,
3030 .data = .{3038 .data = .{
3031 .lhs = constraint,3039 .lhs = expr,
3032 .rhs = expr,3040 .rhs = rparen,
3033 },3041 },
3034 });3042 });
3035 }3043 }
lib/std/zig/parser_test.zig+24-24
...@@ -313,30 +313,30 @@ test "zig fmt: builtin call with trailing comma" {...@@ -313,30 +313,30 @@ test "zig fmt: builtin call with trailing comma" {
313 );313 );
314}314}
315315
316//test "zig fmt: asm expression with comptime content" {316test "zig fmt: asm expression with comptime content" {
317// try testCanonical(317 try testCanonical(
318// \\comptime {318 \\comptime {
319// \\ asm ("foo" ++ "bar");319 \\ asm ("foo" ++ "bar");
320// \\}320 \\}
321// \\pub fn main() void {321 \\pub fn main() void {
322// \\ asm volatile ("foo" ++ "bar");322 \\ asm volatile ("foo" ++ "bar");
323// \\ asm volatile ("foo" ++ "bar"323 \\ asm volatile ("foo" ++ "bar"
324// \\ : [_] "" (x)324 \\ : [_] "" (x)
325// \\ );325 \\ );
326// \\ asm volatile ("foo" ++ "bar"326 \\ asm volatile ("foo" ++ "bar"
327// \\ : [_] "" (x)327 \\ : [_] "" (x)
328// \\ : [_] "" (y)328 \\ : [_] "" (y)
329// \\ );329 \\ );
330// \\ asm volatile ("foo" ++ "bar"330 \\ asm volatile ("foo" ++ "bar"
331// \\ : [_] "" (x)331 \\ : [_] "" (x)
332// \\ : [_] "" (y)332 \\ : [_] "" (y)
333// \\ : "h", "e", "l", "l", "o"333 \\ : "h", "e", "l", "l", "o"
334// \\ );334 \\ );
335// \\}335 \\}
336// \\336 \\
337// );337 );
338//}338}
339//339
340//test "zig fmt: anytype struct field" {340//test "zig fmt: anytype struct field" {
341// try testCanonical(341// try testCanonical(
342// \\pub const Pointer = struct {342// \\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...@@ -816,118 +816,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
816 .IfSimple => return renderIf(ais, tree, tree.ifSimple(node), space),816 .IfSimple => return renderIf(ais, tree, tree.ifSimple(node), space),
817 .If => return renderIf(ais, tree, tree.ifFull(node), space),817 .If => return renderIf(ais, tree, tree.ifFull(node), space),
818818
819 .Asm => unreachable, // TODO819 .AsmSimple => return renderAsm(ais, tree, tree.asmSimple(node), space),
820 .AsmSimple => unreachable, // TODO820 .Asm => return renderAsm(ais, tree, tree.asmFull(node), space),
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 //},
931821
932 .EnumLiteral => {822 .EnumLiteral => {
933 try renderToken(ais, tree, main_tokens[node] - 1, .None); // .823 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...@@ -945,6 +835,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
945 .AlignedVarDecl => unreachable,835 .AlignedVarDecl => unreachable,
946 .UsingNamespace => unreachable,836 .UsingNamespace => unreachable,
947 .TestDecl => unreachable,837 .TestDecl => unreachable,
838 .AsmOutput => unreachable,
839 .AsmInput => unreachable,
948 }840 }
949}841}
950842
...@@ -952,7 +844,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -952,7 +844,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
952fn renderArrayType(844fn renderArrayType(
953 ais: *Ais,845 ais: *Ais,
954 tree: ast.Tree,846 tree: ast.Tree,
955 array_type: ast.Full.ArrayType,847 array_type: ast.full.ArrayType,
956 space: Space,848 space: Space,
957) Error!void {849) Error!void {
958 try renderToken(ais, tree, array_type.ast.lbracket, .None); // lbracket850 try renderToken(ais, tree, array_type.ast.lbracket, .None); // lbracket
...@@ -968,7 +860,7 @@ fn renderArrayType(...@@ -968,7 +860,7 @@ fn renderArrayType(
968fn renderPtrType(860fn renderPtrType(
969 ais: *Ais,861 ais: *Ais,
970 tree: ast.Tree,862 tree: ast.Tree,
971 ptr_type: ast.Full.PtrType,863 ptr_type: ast.full.PtrType,
972 space: Space,864 space: Space,
973) Error!void {865) Error!void {
974 switch (ptr_type.kind) {866 switch (ptr_type.kind) {
...@@ -1040,7 +932,7 @@ fn renderPtrType(...@@ -1040,7 +932,7 @@ fn renderPtrType(
1040fn renderSlice(932fn renderSlice(
1041 ais: *Ais,933 ais: *Ais,
1042 tree: ast.Tree,934 tree: ast.Tree,
1043 slice: ast.Full.Slice,935 slice: ast.full.Slice,
1044 space: Space,936 space: Space,
1045) Error!void {937) Error!void {
1046 const node_tags = tree.nodes.items(.tag);938 const node_tags = tree.nodes.items(.tag);
...@@ -1072,48 +964,56 @@ fn renderSlice(...@@ -1072,48 +964,56 @@ fn renderSlice(
1072}964}
1073965
1074fn renderAsmOutput(966fn renderAsmOutput(
1075 allocator: *mem.Allocator,
1076 ais: *Ais,967 ais: *Ais,
1077 tree: ast.Tree,968 tree: ast.Tree,
1078 asm_output: *const ast.Node.Asm.Output,969 asm_output: ast.Node.Index,
1079 space: Space,970 space: Space,
1080) Error!void {971) Error!void {
1081 try ais.writer().writeAll("[");972 const token_tags = tree.tokens.items(.tag);
1082 try renderExpression(ais, tree, asm_output.symbolic_name, Space.None);973 const node_tags = tree.nodes.items(.tag);
1083 try ais.writer().writeAll("] ");974 const main_tokens = tree.nodes.items(.main_token);
1084 try renderExpression(ais, tree, asm_output.constraint, Space.None);975 const datas = tree.nodes.items(.data);
1085 try ais.writer().writeAll(" (");976 assert(node_tags[asm_output] == .AsmOutput);
1086977 const symbolic_name = main_tokens[asm_output];
1087 switch (asm_output.kind) {978
1088 .Variable => |variable_name| {979 try renderToken(ais, tree, symbolic_name - 1, .None); // lbracket
1089 try renderExpression(ais, tree, &variable_name.base, Space.None);980 try renderToken(ais, tree, symbolic_name, .None); // ident
1090 },981 try renderToken(ais, tree, symbolic_name + 1, .Space); // rbracket
1091 .Return => |return_type| {982 try renderToken(ais, tree, symbolic_name + 2, .Space); // "constraint"
1092 try ais.writer().writeAll("-> ");983 try renderToken(ais, tree, symbolic_name + 3, .None); // lparen
1093 try renderExpression(ais, tree, return_type, Space.None);984
1094 },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
1095 }992 }
1096
1097 return renderToken(ais, tree, asm_output.lastToken(), space); // )
1098}993}
1099994
1100fn renderAsmInput(995fn renderAsmInput(
1101 allocator: *mem.Allocator,
1102 ais: *Ais,996 ais: *Ais,
1103 tree: ast.Tree,997 tree: ast.Tree,
1104 asm_input: *const ast.Node.Asm.Input,998 asm_input: ast.Node.Index,
1105 space: Space,999 space: Space,
1106) Error!void {1000) Error!void {
1107 try ais.writer().writeAll("[");1001 const node_tags = tree.nodes.items(.tag);
1108 try renderExpression(ais, tree, asm_input.symbolic_name, Space.None);1002 const main_tokens = tree.nodes.items(.main_token);
1109 try ais.writer().writeAll("] ");1003 const datas = tree.nodes.items(.data);
1110 try renderExpression(ais, tree, asm_input.constraint, Space.None);1004 assert(node_tags[asm_input] == .AsmInput);
1111 try ais.writer().writeAll(" (");1005 const symbolic_name = main_tokens[asm_input];
1112 try renderExpression(ais, tree, asm_input.expr, Space.None);1006
1113 return renderToken(ais, tree, asm_input.lastToken(), space); // )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
1114}1014}
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 {
1117 if (var_decl.visib_token) |visib_token| {1017 if (var_decl.visib_token) |visib_token| {
1118 try renderToken(ais, tree, visib_token, Space.Space); // pub1018 try renderToken(ais, tree, visib_token, Space.Space); // pub
1119 }1019 }
...@@ -1200,7 +1100,7 @@ fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.Full.VarDecl) Error!vo...@@ -1200,7 +1100,7 @@ fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.Full.VarDecl) Error!vo
1200 try renderExpression(ais, tree, var_decl.ast.init_node, .Semicolon);1100 try renderExpression(ais, tree, var_decl.ast.init_node, .Semicolon);
1201}1101}
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 {
1204 const node_tags = tree.nodes.items(.tag);1104 const node_tags = tree.nodes.items(.tag);
1205 const token_tags = tree.tokens.items(.tag);1105 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...@@ -1334,7 +1234,7 @@ fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.Full.If, space: Space) Error
1334fn renderContainerField(1234fn renderContainerField(
1335 ais: *Ais,1235 ais: *Ais,
1336 tree: ast.Tree,1236 tree: ast.Tree,
1337 field: ast.Full.ContainerField,1237 field: ast.full.ContainerField,
1338 space: Space,1238 space: Space,
1339) Error!void {1239) Error!void {
1340 const main_tokens = tree.nodes.items(.main_token);1240 const main_tokens = tree.nodes.items(.main_token);
...@@ -1430,7 +1330,7 @@ fn renderBuiltinCall(...@@ -1430,7 +1330,7 @@ fn renderBuiltinCall(
1430 }1330 }
1431}1331}
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 {
1434 const token_tags = tree.tokens.items(.tag);1334 const token_tags = tree.tokens.items(.tag);
1435 const token_starts = tree.tokens.items(.start);1335 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...@@ -1618,7 +1518,7 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.Full.FnProto, space: S
1618fn renderSwitchCase(1518fn renderSwitchCase(
1619 ais: *Ais,1519 ais: *Ais,
1620 tree: ast.Tree,1520 tree: ast.Tree,
1621 switch_case: ast.Full.SwitchCase,1521 switch_case: ast.full.SwitchCase,
1622 space: Space,1522 space: Space,
1623) Error!void {1523) Error!void {
1624 const token_tags = tree.tokens.items(.tag);1524 const token_tags = tree.tokens.items(.tag);
...@@ -1709,7 +1609,7 @@ fn renderBlock(...@@ -1709,7 +1609,7 @@ fn renderBlock(
1709fn renderStructInit(1609fn renderStructInit(
1710 ais: *Ais,1610 ais: *Ais,
1711 tree: ast.Tree,1611 tree: ast.Tree,
1712 struct_init: ast.Full.StructInit,1612 struct_init: ast.full.StructInit,
1713 space: Space,1613 space: Space,
1714) Error!void {1614) Error!void {
1715 const token_tags = tree.tokens.items(.tag);1615 const token_tags = tree.tokens.items(.tag);
...@@ -1763,7 +1663,7 @@ fn renderStructInit(...@@ -1763,7 +1663,7 @@ fn renderStructInit(
1763fn renderArrayInit(1663fn renderArrayInit(
1764 ais: *Ais,1664 ais: *Ais,
1765 tree: ast.Tree,1665 tree: ast.Tree,
1766 array_init: ast.Full.ArrayInit,1666 array_init: ast.full.ArrayInit,
1767 space: Space,1667 space: Space,
1768) Error!void {1668) Error!void {
1769 const token_tags = tree.tokens.items(.tag);1669 const token_tags = tree.tokens.items(.tag);
...@@ -1809,7 +1709,7 @@ fn renderArrayInit(...@@ -1809,7 +1709,7 @@ fn renderArrayInit(
1809fn renderContainerDecl(1709fn renderContainerDecl(
1810 ais: *Ais,1710 ais: *Ais,
1811 tree: ast.Tree,1711 tree: ast.Tree,
1812 container_decl: ast.Full.ContainerDecl,1712 container_decl: ast.full.ContainerDecl,
1813 space: Space,1713 space: Space,
1814) Error!void {1714) Error!void {
1815 const token_tags = tree.tokens.items(.tag);1715 const token_tags = tree.tokens.items(.tag);
...@@ -1894,6 +1794,135 @@ fn renderContainerDecl(...@@ -1894,6 +1794,135 @@ fn renderContainerDecl(
1894 return renderToken(ais, tree, rbrace, space); // rbrace1794 return renderToken(ais, tree, rbrace, space); // rbrace
1895}1795}
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
1897/// Render an expression, and the comma that follows it, if it is present in the source.1926/// Render an expression, and the comma that follows it, if it is present in the source.
1898fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {1927fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
1899 const token_tags = tree.tokens.items(.tag);1928 const token_tags = tree.tokens.items(.tag);