authorgravatar for mrpaul@aestheticwisdom.comMr. Paul <mrpaul@aestheticwisdom.com> 2021-08-11 16:01:03+07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-10 14:23:32-04:00
log0c091feb5ae52caf1ebf885c0de55b3159207001
tree6619f5d03bbccd5a500035947cf50f2118b4dc46
parent9e24727062624ec51eadb833d3c434b15889a9c3

Improve HTML semantics and a11y of language reference

The language reference's HTML has been updated to be more semantically correct. This also helps to improve the document's accessibility concerns. * Document structure has single h1, other header sections start at h2, nav sections w/ aria labels, main section * Zig's homepage is linked, Zig Standard Library section link to it * Tables have caption and scoping rows and columns * Code blocks are figures with figure captions citing source files * Change line height 1.5 to include table of contents as well * Luminosity contrast ratios have been adjusted to 7:1 * Dark mode colors adjusted to reduce eye strain * Links have default browser underline with hover and focus effects * Asides, definition lists, keyboard inputs, program outputs are represented semantically Tools used to check: WAVE plugin https://wave.webaim.org/ Firefox Accessibility Developer Tool Lighthouse Accessibility Tool

2 files changed, 1142 insertions(+), 726 deletions(-)

doc/docgen.zig+391-65
...@@ -280,7 +280,7 @@ const Code = struct {...@@ -280,7 +280,7 @@ const Code = struct {
280 id: Id,280 id: Id,
281 name: []const u8,281 name: []const u8,
282 source_token: Token,282 source_token: Token,
283 is_inline: bool,283 just_check_syntax: bool,
284 mode: std.builtin.Mode,284 mode: std.builtin.Mode,
285 link_objects: []const []const u8,285 link_objects: []const []const u8,
286 target_str: ?[]const u8,286 target_str: ?[]const u8,
...@@ -305,6 +305,18 @@ const Link = struct {...@@ -305,6 +305,18 @@ const Link = struct {
305 token: Token,305 token: Token,
306};306};
307307
308const SyntaxBlock = struct {
309 source_type: SourceType,
310 name: []const u8,
311 source_token: Token,
312
313 const SourceType = enum {
314 zig,
315 c,
316 javascript,
317 };
318};
319
308const Node = union(enum) {320const Node = union(enum) {
309 Content: []const u8,321 Content: []const u8,
310 Nav,322 Nav,
...@@ -313,7 +325,9 @@ const Node = union(enum) {...@@ -313,7 +325,9 @@ const Node = union(enum) {
313 SeeAlso: []const SeeAlsoItem,325 SeeAlso: []const SeeAlsoItem,
314 Code: Code,326 Code: Code,
315 Link: Link,327 Link: Link,
316 Syntax: Token,328 InlineSyntax: Token,
329 Shell: Token,
330 SyntaxBlock: SyntaxBlock,
317};331};
318332
319const Toc = struct {333const Toc = struct {
...@@ -403,7 +417,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -403,7 +417,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
403 .HeaderOpen = HeaderOpen{417 .HeaderOpen = HeaderOpen{
404 .name = content,418 .name = content,
405 .url = urlized,419 .url = urlized,
406 .n = header_stack_size,420 .n = header_stack_size + 1, // highest-level section headers start at h2
407 },421 },
408 });422 });
409 if (try urls.fetchPut(urlized, tag_token)) |kv| {423 if (try urls.fetchPut(urlized, tag_token)) |kv| {
...@@ -502,7 +516,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -502,7 +516,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
502 }516 }
503 const code_kind_str = tokenizer.buffer[code_kind_tok.start..code_kind_tok.end];517 const code_kind_str = tokenizer.buffer[code_kind_tok.start..code_kind_tok.end];
504 var code_kind_id: Code.Id = undefined;518 var code_kind_id: Code.Id = undefined;
505 var is_inline = false;519 var just_check_syntax = false;
506 if (mem.eql(u8, code_kind_str, "exe")) {520 if (mem.eql(u8, code_kind_str, "exe")) {
507 code_kind_id = Code.Id{ .Exe = ExpectedOutcome.Succeed };521 code_kind_id = Code.Id{ .Exe = ExpectedOutcome.Succeed };
508 } else if (mem.eql(u8, code_kind_str, "exe_err")) {522 } else if (mem.eql(u8, code_kind_str, "exe_err")) {
...@@ -526,7 +540,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -526,7 +540,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
526 code_kind_id = Code.Id.Lib;540 code_kind_id = Code.Id.Lib;
527 } else if (mem.eql(u8, code_kind_str, "syntax")) {541 } else if (mem.eql(u8, code_kind_str, "syntax")) {
528 code_kind_id = Code.Id{ .Obj = null };542 code_kind_id = Code.Id{ .Obj = null };
529 is_inline = true;543 just_check_syntax = true;
530 } else {544 } else {
531 return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {s}", .{code_kind_str});545 return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {s}", .{code_kind_str});
532 }546 }
...@@ -589,7 +603,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -589,7 +603,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
589 .id = code_kind_id,603 .id = code_kind_id,
590 .name = name,604 .name = name,
591 .source_token = source_token,605 .source_token = source_token,
592 .is_inline = is_inline,606 .just_check_syntax = just_check_syntax,
593 .mode = mode,607 .mode = mode,
594 .link_objects = link_objects.toOwnedSlice(),608 .link_objects = link_objects.toOwnedSlice(),
595 .target_str = target_str,609 .target_str = target_str,
...@@ -615,7 +629,67 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {...@@ -615,7 +629,67 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
615 );629 );
616 }630 }
617 _ = try eatToken(tokenizer, Token.Id.BracketClose);631 _ = try eatToken(tokenizer, Token.Id.BracketClose);
618 try nodes.append(Node{ .Syntax = content_tok });632 try nodes.append(Node{ .InlineSyntax = content_tok });
633 } else if (mem.eql(u8, tag_name, "shell_samp")) {
634 _ = try eatToken(tokenizer, Token.Id.BracketClose);
635 const content_tok = try eatToken(tokenizer, Token.Id.Content);
636 _ = try eatToken(tokenizer, Token.Id.BracketOpen);
637 const end_syntax_tag = try eatToken(tokenizer, Token.Id.TagContent);
638 const end_tag_name = tokenizer.buffer[end_syntax_tag.start..end_syntax_tag.end];
639 if (!mem.eql(u8, end_tag_name, "end_shell_samp")) {
640 return parseError(
641 tokenizer,
642 end_syntax_tag,
643 "invalid token inside syntax: {s}",
644 .{end_tag_name},
645 );
646 }
647 _ = try eatToken(tokenizer, Token.Id.BracketClose);
648 try nodes.append(Node{ .Shell = content_tok });
649 } else if (mem.eql(u8, tag_name, "syntax_block")) {
650 _ = try eatToken(tokenizer, Token.Id.Separator);
651 const source_type_tok = try eatToken(tokenizer, Token.Id.TagContent);
652 var name: []const u8 = "sample_code";
653 const maybe_sep = tokenizer.next();
654 switch (maybe_sep.id) {
655 Token.Id.Separator => {
656 const name_tok = try eatToken(tokenizer, Token.Id.TagContent);
657 name = tokenizer.buffer[name_tok.start..name_tok.end];
658 _ = try eatToken(tokenizer, Token.Id.BracketClose);
659 },
660 Token.Id.BracketClose => {},
661 else => return parseError(tokenizer, token, "invalid token", .{}),
662 }
663 const source_type_str = tokenizer.buffer[source_type_tok.start..source_type_tok.end];
664 var source_type: SyntaxBlock.SourceType = undefined;
665 if (mem.eql(u8, source_type_str, "zig")) {
666 source_type = SyntaxBlock.SourceType.zig;
667 } else if (mem.eql(u8, source_type_str, "c")) {
668 source_type = SyntaxBlock.SourceType.c;
669 } else if (mem.eql(u8, source_type_str, "javascript")) {
670 source_type = SyntaxBlock.SourceType.javascript;
671 } else {
672 return parseError(tokenizer, source_type_tok, "unrecognized code kind: {s}", .{source_type_str});
673 }
674 const source_token = while (true) {
675 const content_tok = try eatToken(tokenizer, Token.Id.Content);
676 _ = try eatToken(tokenizer, Token.Id.BracketOpen);
677 const end_code_tag = try eatToken(tokenizer, Token.Id.TagContent);
678 const end_tag_name = tokenizer.buffer[end_code_tag.start..end_code_tag.end];
679 if (mem.eql(u8, end_tag_name, "end_syntax_block")) {
680 _ = try eatToken(tokenizer, Token.Id.BracketClose);
681 break content_tok;
682 } else {
683 return parseError(
684 tokenizer,
685 end_code_tag,
686 "invalid token inside code_begin: {s}",
687 .{end_tag_name},
688 );
689 }
690 _ = try eatToken(tokenizer, Token.Id.BracketClose);
691 } else unreachable; // TODO issue #707
692 try nodes.append(Node{ .SyntaxBlock = SyntaxBlock{ .source_type = source_type, .name = name, .source_token = source_token } });
619 } else {693 } else {
620 return parseError(tokenizer, tag_token, "unrecognized tag name: {s}", .{tag_name});694 return parseError(tokenizer, tag_token, "unrecognized tag name: {s}", .{tag_name});
621 }695 }
...@@ -693,7 +767,7 @@ test "term color" {...@@ -693,7 +767,7 @@ test "term color" {
693 const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";767 const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";
694 const result = try termColor(std.testing.allocator, input_bytes);768 const result = try termColor(std.testing.allocator, input_bytes);
695 defer std.testing.allocator.free(result);769 defer std.testing.allocator.free(result);
696 testing.expectEqualSlices(u8, "A<span class=\"t32\">green</span>B", result);770 try testing.expectEqualSlices(u8, "A<span class=\"t32_1\">green</span>B", result);
697}771}
698772
699fn termColor(allocator: *Allocator, input: []const u8) ![]u8 {773fn termColor(allocator: *Allocator, input: []const u8) ![]u8 {
...@@ -799,7 +873,7 @@ fn tokenizeAndPrintRaw(...@@ -799,7 +873,7 @@ fn tokenizeAndPrintRaw(
799) !void {873) !void {
800 const src_non_terminated = mem.trim(u8, raw_src, " \n");874 const src_non_terminated = mem.trim(u8, raw_src, " \n");
801 const src = try allocator.dupeZ(u8, src_non_terminated);875 const src = try allocator.dupeZ(u8, src_non_terminated);
802 try out.writeAll("<code class=\"zig\">");876 try out.writeAll("<code>");
803 var tokenizer = std.zig.Tokenizer.init(src);877 var tokenizer = std.zig.Tokenizer.init(src);
804 var index: usize = 0;878 var index: usize = 0;
805 var next_tok_is_fn = false;879 var next_tok_is_fn = false;
...@@ -1033,6 +1107,47 @@ fn tokenizeAndPrint(...@@ -1033,6 +1107,47 @@ fn tokenizeAndPrint(
1033 return tokenizeAndPrintRaw(allocator, docgen_tokenizer, out, source_token, raw_src);1107 return tokenizeAndPrintRaw(allocator, docgen_tokenizer, out, source_token, raw_src);
1034}1108}
10351109
1110fn printSourceBlock(allocator: *Allocator, docgen_tokenizer: *Tokenizer, out: anytype, syntax_block: SyntaxBlock) !void {
1111 const source_type = @tagName(syntax_block.source_type);
1112
1113 try out.print("<figure><figcaption class=\"{s}-cap\"><cite class=\"file\">{s}</cite></figcaption><pre>", .{ source_type, syntax_block.name });
1114 switch (syntax_block.source_type) {
1115 .zig => try tokenizeAndPrint(allocator, docgen_tokenizer, out, syntax_block.source_token),
1116 else => {
1117 const raw_source = docgen_tokenizer.buffer[syntax_block.source_token.start..syntax_block.source_token.end];
1118 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
1119
1120 try out.writeAll("<code>");
1121 try writeEscaped(out, trimmed_raw_source);
1122 try out.writeAll("</code>");
1123 },
1124 }
1125 try out.writeAll("</pre></figure>");
1126}
1127
1128fn printShell(out: anytype, shell_content: []const u8) !void {
1129 const trimmed_shell_content = mem.trim(u8, shell_content, " \n");
1130 try out.writeAll("<figure><figcaption class=\"shell-cap\">Shell</figcaption><pre><samp>");
1131 var cmd_cont: bool = false;
1132 var iter = std.mem.split(u8, trimmed_shell_content, "\n");
1133 while (iter.next()) |orig_line| {
1134 const line = mem.trimRight(u8, orig_line, " ");
1135 if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] != '\\') {
1136 try out.print("$ <kbd>{s}</kbd>\n", .{std.mem.trimLeft(u8, line[1..], " ")});
1137 } else if (!cmd_cont and line.len > 1 and mem.eql(u8, line[0..2], "$ ") and line[line.len - 1] == '\\') {
1138 try out.print("$ <kbd>{s}\n", .{std.mem.trimLeft(u8, line[1..], " ")});
1139 cmd_cont = true;
1140 } else if (line.len > 0 and line[line.len - 1] != '\\' and cmd_cont) {
1141 try out.print("{s}</kbd>\n", .{line});
1142 cmd_cont = false;
1143 } else {
1144 try out.print("{s}\n", .{line});
1145 }
1146 }
1147
1148 try out.writeAll("</samp></pre></figure>");
1149}
1150
1036fn genHtml(1151fn genHtml(
1037 allocator: *Allocator,1152 allocator: *Allocator,
1038 tokenizer: *Tokenizer,1153 tokenizer: *Tokenizer,
...@@ -1066,9 +1181,9 @@ fn genHtml(...@@ -1066,9 +1181,9 @@ fn genHtml(
1066 try out.writeAll(toc.toc);1181 try out.writeAll(toc.toc);
1067 },1182 },
1068 .Builtin => |tok| {1183 .Builtin => |tok| {
1069 try out.writeAll("<pre>");1184 try out.writeAll("<figure><figcaption class=\"zig-cap\"><cite>@import(\"builtin\")</cite></figcaption><pre>");
1070 try tokenizeAndPrintRaw(allocator, tokenizer, out, tok, builtin_code);1185 try tokenizeAndPrintRaw(allocator, tokenizer, out, tok, builtin_code);
1071 try out.writeAll("</pre>");1186 try out.writeAll("</pre></figure>");
1072 },1187 },
1073 .HeaderOpen => |info| {1188 .HeaderOpen => |info| {
1074 try out.print(1189 try out.print(
...@@ -1087,30 +1202,44 @@ fn genHtml(...@@ -1087,30 +1202,44 @@ fn genHtml(
1087 }1202 }
1088 try out.writeAll("</ul>\n");1203 try out.writeAll("</ul>\n");
1089 },1204 },
1090 .Syntax => |content_tok| {1205 .InlineSyntax => |content_tok| {
1091 try tokenizeAndPrint(allocator, tokenizer, out, content_tok);1206 try tokenizeAndPrint(allocator, tokenizer, out, content_tok);
1092 },1207 },
1208 .Shell => |content_tok| {
1209 const raw_shell_content = tokenizer.buffer[content_tok.start..content_tok.end];
1210 try printShell(out, raw_shell_content);
1211 },
1212 .SyntaxBlock => |syntax_block| {
1213 try printSourceBlock(allocator, tokenizer, out, syntax_block);
1214 },
1093 .Code => |code| {1215 .Code => |code| {
1094 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];1216 const name_plus_ext = try std.fmt.allocPrint(allocator, "{s}.zig", .{code.name});
1095 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");1217 const syntax_block = SyntaxBlock{
1096 if (!code.is_inline) {1218 .source_type = .zig,
1097 try out.print("<p class=\"file\">{s}.zig</p>", .{code.name});1219 .name = name_plus_ext,
1098 }1220 .source_token = code.source_token,
1099 try out.writeAll("<pre>");1221 };
1100 try tokenizeAndPrint(allocator, tokenizer, out, code.source_token);1222
1101 try out.writeAll("</pre>");1223 try printSourceBlock(allocator, tokenizer, out, syntax_block);
11021224
1103 if (!do_code_tests or code.is_inline) {1225 // TODO: remove code.just_check_syntax after updating code samples
1226 // that have stopped working due to a change in the compiler.
1227 if (!do_code_tests or code.just_check_syntax) {
1104 continue;1228 continue;
1105 }1229 }
11061230
1107 const name_plus_ext = try std.fmt.allocPrint(allocator, "{s}.zig", .{code.name});1231 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];
1232 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
1108 const tmp_source_file_name = try fs.path.join(1233 const tmp_source_file_name = try fs.path.join(
1109 allocator,1234 allocator,
1110 &[_][]const u8{ tmp_dir_name, name_plus_ext },1235 &[_][]const u8{ tmp_dir_name, name_plus_ext },
1111 );1236 );
1112 try fs.cwd().writeFile(tmp_source_file_name, trimmed_raw_source);1237 try fs.cwd().writeFile(tmp_source_file_name, trimmed_raw_source);
11131238
1239 var shell_buffer = std.ArrayList(u8).init(allocator);
1240 defer shell_buffer.deinit();
1241 var shell_out = shell_buffer.writer();
1242
1114 switch (code.id) {1243 switch (code.id) {
1115 Code.Id.Exe => |expected_outcome| code_block: {1244 Code.Id.Exe => |expected_outcome| code_block: {
1116 var build_args = std.ArrayList([]const u8).init(allocator);1245 var build_args = std.ArrayList([]const u8).init(allocator);
...@@ -1121,12 +1250,14 @@ fn genHtml(...@@ -1121,12 +1250,14 @@ fn genHtml(
1121 "--color", "on",1250 "--color", "on",
1122 "--enable-cache", tmp_source_file_name,1251 "--enable-cache", tmp_source_file_name,
1123 });1252 });
1124 try out.print("<pre><code class=\"shell\">$ zig build-exe {s}.zig", .{code.name});1253
1254 try shell_out.print("$ zig build-exe {s} ", .{name_plus_ext});
1255
1125 switch (code.mode) {1256 switch (code.mode) {
1126 .Debug => {},1257 .Debug => {},
1127 else => {1258 else => {
1128 try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });1259 try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1129 try out.print(" -O {s}", .{@tagName(code.mode)});1260 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
1130 },1261 },
1131 }1262 }
1132 for (code.link_objects) |link_object| {1263 for (code.link_objects) |link_object| {
...@@ -1136,25 +1267,26 @@ fn genHtml(...@@ -1136,25 +1267,26 @@ fn genHtml(
1136 &[_][]const u8{ tmp_dir_name, name_with_ext },1267 &[_][]const u8{ tmp_dir_name, name_with_ext },
1137 );1268 );
1138 try build_args.append(full_path_object);1269 try build_args.append(full_path_object);
1139 try out.print(" {s}", .{name_with_ext});1270 try shell_out.print("{s} ", .{name_with_ext});
1140 }1271 }
1141 if (code.link_libc) {1272 if (code.link_libc) {
1142 try build_args.append("-lc");1273 try build_args.append("-lc");
1143 try out.print(" -lc", .{});1274 try shell_out.print("-lc ", .{});
1144 }1275 }
1145 const target = try std.zig.CrossTarget.parse(.{1276 const target = try std.zig.CrossTarget.parse(.{
1146 .arch_os_abi = code.target_str orelse "native",1277 .arch_os_abi = code.target_str orelse "native",
1147 });1278 });
1148 if (code.target_str) |triple| {1279 if (code.target_str) |triple| {
1149 try build_args.appendSlice(&[_][]const u8{ "-target", triple });1280 try build_args.appendSlice(&[_][]const u8{ "-target", triple });
1150 if (!code.is_inline) {1281 try shell_out.print("-target {s} ", .{triple});
1151 try out.print(" -target {s}", .{triple});
1152 }
1153 }1282 }
1154 if (code.verbose_cimport) {1283 if (code.verbose_cimport) {
1155 try build_args.append("--verbose-cimport");1284 try build_args.append("--verbose-cimport");
1156 try out.print(" --verbose-cimport", .{});1285 try shell_out.print("--verbose-cimport ", .{});
1157 }1286 }
1287
1288 try shell_out.print("\n", .{});
1289
1158 if (expected_outcome == .BuildFail) {1290 if (expected_outcome == .BuildFail) {
1159 const result = try ChildProcess.exec(.{1291 const result = try ChildProcess.exec(.{
1160 .allocator = allocator,1292 .allocator = allocator,
...@@ -1180,12 +1312,17 @@ fn genHtml(...@@ -1180,12 +1312,17 @@ fn genHtml(
1180 }1312 }
1181 const escaped_stderr = try escapeHtml(allocator, result.stderr);1313 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1182 const colored_stderr = try termColor(allocator, escaped_stderr);1314 const colored_stderr = try termColor(allocator, escaped_stderr);
1183 try out.print("\n{s}</code></pre>\n", .{colored_stderr});1315 try shell_out.writeAll(colored_stderr);
1184 break :code_block;1316 break :code_block;
1185 }1317 }
1186 const exec_result = exec(allocator, &env_map, build_args.items) catch1318 const exec_result = exec(allocator, &env_map, build_args.items) catch
1187 return parseError(tokenizer, code.source_token, "example failed to compile", .{});1319 return parseError(tokenizer, code.source_token, "example failed to compile", .{});
11881320
1321 if (code.verbose_cimport) {
1322 const escaped_build_stderr = try escapeHtml(allocator, exec_result.stderr);
1323 try shell_out.writeAll(escaped_build_stderr);
1324 }
1325
1189 if (code.target_str) |triple| {1326 if (code.target_str) |triple| {
1190 if (mem.startsWith(u8, triple, "wasm32") or1327 if (mem.startsWith(u8, triple, "wasm32") or
1191 mem.startsWith(u8, triple, "riscv64-linux") or1328 mem.startsWith(u8, triple, "riscv64-linux") or
...@@ -1193,7 +1330,6 @@ fn genHtml(...@@ -1193,7 +1330,6 @@ fn genHtml(
1193 std.Target.current.os.tag != .linux or std.Target.current.cpu.arch != .x86_64))1330 std.Target.current.os.tag != .linux or std.Target.current.cpu.arch != .x86_64))
1194 {1331 {
1195 // skip execution1332 // skip execution
1196 try out.print("</code></pre>\n", .{});
1197 break :code_block;1333 break :code_block;
1198 }1334 }
1199 }1335 }
...@@ -1241,41 +1377,38 @@ fn genHtml(...@@ -1241,41 +1377,38 @@ fn genHtml(
1241 const colored_stderr = try termColor(allocator, escaped_stderr);1377 const colored_stderr = try termColor(allocator, escaped_stderr);
1242 const colored_stdout = try termColor(allocator, escaped_stdout);1378 const colored_stdout = try termColor(allocator, escaped_stdout);
12431379
1244 if (code.verbose_cimport) {1380 try shell_out.print("\n$ ./{s}\n{s}{s}", .{ code.name, colored_stdout, colored_stderr });
1245 const escaped_build_stderr = try escapeHtml(allocator, exec_result.stderr);
1246 try out.print("\n{s}", .{escaped_build_stderr});
1247 }
1248 try out.print("\n$ ./{s}\n{s}{s}", .{ code.name, colored_stdout, colored_stderr });
1249 if (exited_with_signal) {1381 if (exited_with_signal) {
1250 try out.print("(process terminated by signal)", .{});1382 try shell_out.print("(process terminated by signal)", .{});
1251 }1383 }
1252 try out.print("</code></pre>\n", .{});1384 try shell_out.writeAll("\n");
1253 },1385 },
1254 Code.Id.Test => {1386 Code.Id.Test => {
1255 var test_args = std.ArrayList([]const u8).init(allocator);1387 var test_args = std.ArrayList([]const u8).init(allocator);
1256 defer test_args.deinit();1388 defer test_args.deinit();
12571389
1258 try test_args.appendSlice(&[_][]const u8{ zig_exe, "test", tmp_source_file_name });1390 try test_args.appendSlice(&[_][]const u8{ zig_exe, "test", tmp_source_file_name });
1259 try out.print("<pre><code class=\"shell\">$ zig test {s}.zig", .{code.name});1391 try shell_out.print("$ zig test {s}.zig ", .{code.name});
1392
1260 switch (code.mode) {1393 switch (code.mode) {
1261 .Debug => {},1394 .Debug => {},
1262 else => {1395 else => {
1263 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });1396 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1264 try out.print(" -O {s}", .{@tagName(code.mode)});1397 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
1265 },1398 },
1266 }1399 }
1267 if (code.link_libc) {1400 if (code.link_libc) {
1268 try test_args.append("-lc");1401 try test_args.append("-lc");
1269 try out.print(" -lc", .{});1402 try shell_out.print("-lc ", .{});
1270 }1403 }
1271 if (code.target_str) |triple| {1404 if (code.target_str) |triple| {
1272 try test_args.appendSlice(&[_][]const u8{ "-target", triple });1405 try test_args.appendSlice(&[_][]const u8{ "-target", triple });
1273 try out.print(" -target {s}", .{triple});1406 try shell_out.print("-target {s} ", .{triple});
1274 }1407 }
1275 const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});1408 const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});
1276 const escaped_stderr = try escapeHtml(allocator, result.stderr);1409 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1277 const escaped_stdout = try escapeHtml(allocator, result.stdout);1410 const escaped_stdout = try escapeHtml(allocator, result.stdout);
1278 try out.print("\n{s}{s}</code></pre>\n", .{ escaped_stderr, escaped_stdout });1411 try shell_out.print("\n{s}{s}\n", .{ escaped_stderr, escaped_stdout });
1279 },1412 },
1280 Code.Id.TestError => |error_match| {1413 Code.Id.TestError => |error_match| {
1281 var test_args = std.ArrayList([]const u8).init(allocator);1414 var test_args = std.ArrayList([]const u8).init(allocator);
...@@ -1288,12 +1421,13 @@ fn genHtml(...@@ -1288,12 +1421,13 @@ fn genHtml(
1288 "on",1421 "on",
1289 tmp_source_file_name,1422 tmp_source_file_name,
1290 });1423 });
1291 try out.print("<pre><code class=\"shell\">$ zig test {s}.zig", .{code.name});1424 try shell_out.print("$ zig test {s}.zig ", .{code.name});
1425
1292 switch (code.mode) {1426 switch (code.mode) {
1293 .Debug => {},1427 .Debug => {},
1294 else => {1428 else => {
1295 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });1429 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1296 try out.print(" -O {s}", .{@tagName(code.mode)});1430 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
1297 },1431 },
1298 }1432 }
1299 const result = try ChildProcess.exec(.{1433 const result = try ChildProcess.exec(.{
...@@ -1325,7 +1459,7 @@ fn genHtml(...@@ -1325,7 +1459,7 @@ fn genHtml(
1325 }1459 }
1326 const escaped_stderr = try escapeHtml(allocator, result.stderr);1460 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1327 const colored_stderr = try termColor(allocator, escaped_stderr);1461 const colored_stderr = try termColor(allocator, escaped_stderr);
1328 try out.print("\n{s}</code></pre>\n", .{colored_stderr});1462 try shell_out.print("\n{s}\n", .{colored_stderr});
1329 },1463 },
13301464
1331 Code.Id.TestSafety => |error_match| {1465 Code.Id.TestSafety => |error_match| {
...@@ -1383,7 +1517,7 @@ fn genHtml(...@@ -1383,7 +1517,7 @@ fn genHtml(
1383 }1517 }
1384 const escaped_stderr = try escapeHtml(allocator, result.stderr);1518 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1385 const colored_stderr = try termColor(allocator, escaped_stderr);1519 const colored_stderr = try termColor(allocator, escaped_stderr);
1386 try out.print("<pre><code class=\"shell\">$ zig test {s}.zig {s}\n{s}</code></pre>\n", .{1520 try shell_out.print("$ zig test {s}.zig {s}\n{s}\n", .{
1387 code.name,1521 code.name,
1388 mode_arg,1522 mode_arg,
1389 colored_stderr,1523 colored_stderr,
...@@ -1406,23 +1540,20 @@ fn genHtml(...@@ -1406,23 +1540,20 @@ fn genHtml(
1406 tmp_dir_name, fs.path.sep, name_plus_obj_ext,1540 tmp_dir_name, fs.path.sep, name_plus_obj_ext,
1407 }),1541 }),
1408 });1542 });
1409 if (!code.is_inline) {1543
1410 try out.print("<pre><code class=\"shell\">$ zig build-obj {s}.zig", .{code.name});1544 try shell_out.print("$ zig build-obj {s}.zig ", .{code.name});
1411 }
14121545
1413 switch (code.mode) {1546 switch (code.mode) {
1414 .Debug => {},1547 .Debug => {},
1415 else => {1548 else => {
1416 try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });1549 try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1417 if (!code.is_inline) {1550 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
1418 try out.print(" -O {s}", .{@tagName(code.mode)});
1419 }
1420 },1551 },
1421 }1552 }
14221553
1423 if (code.target_str) |triple| {1554 if (code.target_str) |triple| {
1424 try build_args.appendSlice(&[_][]const u8{ "-target", triple });1555 try build_args.appendSlice(&[_][]const u8{ "-target", triple });
1425 try out.print(" -target {s}", .{triple});1556 try shell_out.print("-target {s} ", .{triple});
1426 }1557 }
14271558
1428 if (maybe_error_match) |error_match| {1559 if (maybe_error_match) |error_match| {
...@@ -1455,13 +1586,11 @@ fn genHtml(...@@ -1455,13 +1586,11 @@ fn genHtml(
1455 }1586 }
1456 const escaped_stderr = try escapeHtml(allocator, result.stderr);1587 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1457 const colored_stderr = try termColor(allocator, escaped_stderr);1588 const colored_stderr = try termColor(allocator, escaped_stderr);
1458 try out.print("\n{s}", .{colored_stderr});1589 try shell_out.print("\n{s} ", .{colored_stderr});
1459 } else {1590 } else {
1460 _ = exec(allocator, &env_map, build_args.items) catch return parseError(tokenizer, code.source_token, "example failed to compile", .{});1591 _ = exec(allocator, &env_map, build_args.items) catch return parseError(tokenizer, code.source_token, "example failed to compile", .{});
1461 }1592 }
1462 if (!code.is_inline) {1593 try shell_out.writeAll("\n");
1463 try out.print("</code></pre>\n", .{});
1464 }
1465 },1594 },
1466 Code.Id.Lib => {1595 Code.Id.Lib => {
1467 const bin_basename = try std.zig.binNameAlloc(allocator, .{1596 const bin_basename = try std.zig.binNameAlloc(allocator, .{
...@@ -1481,36 +1610,41 @@ fn genHtml(...@@ -1481,36 +1610,41 @@ fn genHtml(
1481 tmp_dir_name, fs.path.sep_str, bin_basename,1610 tmp_dir_name, fs.path.sep_str, bin_basename,
1482 }),1611 }),
1483 });1612 });
1484 try out.print("<pre><code class=\"shell\">$ zig build-lib {s}.zig", .{code.name});1613 try shell_out.print("$ zig build-lib {s}.zig ", .{code.name});
1614
1485 switch (code.mode) {1615 switch (code.mode) {
1486 .Debug => {},1616 .Debug => {},
1487 else => {1617 else => {
1488 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });1618 try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1489 try out.print(" -O {s}", .{@tagName(code.mode)});1619 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
1490 },1620 },
1491 }1621 }
1492 if (code.target_str) |triple| {1622 if (code.target_str) |triple| {
1493 try test_args.appendSlice(&[_][]const u8{ "-target", triple });1623 try test_args.appendSlice(&[_][]const u8{ "-target", triple });
1494 try out.print(" -target {s}", .{triple});1624 try shell_out.print("-target {s} ", .{triple});
1495 }1625 }
1496 if (code.link_mode) |link_mode| {1626 if (code.link_mode) |link_mode| {
1497 switch (link_mode) {1627 switch (link_mode) {
1498 .Static => {1628 .Static => {
1499 try test_args.append("-static");1629 try test_args.append("-static");
1500 try out.print(" -static", .{});1630 try shell_out.print("-static ", .{});
1501 },1631 },
1502 .Dynamic => {1632 .Dynamic => {
1503 try test_args.append("-dynamic");1633 try test_args.append("-dynamic");
1504 try out.print(" -dynamic", .{});1634 try shell_out.print("-dynamic ", .{});
1505 },1635 },
1506 }1636 }
1507 }1637 }
1508 const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});1638 const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});
1509 const escaped_stderr = try escapeHtml(allocator, result.stderr);1639 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1510 const escaped_stdout = try escapeHtml(allocator, result.stdout);1640 const escaped_stdout = try escapeHtml(allocator, result.stdout);
1511 try out.print("\n{s}{s}</code></pre>\n", .{ escaped_stderr, escaped_stdout });1641 try shell_out.print("\n{s}{s}\n", .{ escaped_stderr, escaped_stdout });
1512 },1642 },
1513 }1643 }
1644
1645 if (!code.just_check_syntax) {
1646 try printShell(out, shell_buffer.items);
1647 }
1514 },1648 },
1515 }1649 }
1516 }1650 }
...@@ -1551,3 +1685,195 @@ fn dumpArgs(args: []const []const u8) void {...@@ -1551,3 +1685,195 @@ fn dumpArgs(args: []const []const u8) void {
1551 else1685 else
1552 print("\n", .{});1686 print("\n", .{});
1553}1687}
1688
1689test "shell parsed" {
1690 const test_allocator = std.testing.allocator;
1691
1692 {
1693 const shell_out =
1694 \\$ zig build test.zig
1695 ;
1696 const expected =
1697 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1698 \\</samp></pre></figure>
1699 ;
1700
1701 var buffer = std.ArrayList(u8).init(test_allocator);
1702 defer buffer.deinit();
1703
1704 try printShell(buffer.writer(), shell_out);
1705 try testing.expectEqualSlices(u8, expected, buffer.items);
1706 }
1707 {
1708 const shell_out =
1709 \\$ zig build test.zig
1710 \\build output
1711 ;
1712 const expected =
1713 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1714 \\build output
1715 \\</samp></pre></figure>
1716 ;
1717
1718 var buffer = std.ArrayList(u8).init(test_allocator);
1719 defer buffer.deinit();
1720
1721 try printShell(buffer.writer(), shell_out);
1722 try testing.expectEqualSlices(u8, expected, buffer.items);
1723 }
1724 {
1725 const shell_out =
1726 \\$ zig build test.zig
1727 \\build output
1728 \\$ ./test
1729 ;
1730 const expected =
1731 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1732 \\build output
1733 \\$ <kbd>./test</kbd>
1734 \\</samp></pre></figure>
1735 ;
1736
1737 var buffer = std.ArrayList(u8).init(test_allocator);
1738 defer buffer.deinit();
1739
1740 try printShell(buffer.writer(), shell_out);
1741 try testing.expectEqualSlices(u8, expected, buffer.items);
1742 }
1743 {
1744 const shell_out =
1745 \\$ zig build test.zig
1746 \\
1747 \\$ ./test
1748 \\output
1749 ;
1750 const expected =
1751 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1752 \\
1753 \\$ <kbd>./test</kbd>
1754 \\output
1755 \\</samp></pre></figure>
1756 ;
1757
1758 var buffer = std.ArrayList(u8).init(test_allocator);
1759 defer buffer.deinit();
1760
1761 try printShell(buffer.writer(), shell_out);
1762 try testing.expectEqualSlices(u8, expected, buffer.items);
1763 }
1764 {
1765 const shell_out =
1766 \\$ zig build test.zig
1767 \\$ ./test
1768 \\output
1769 ;
1770 const expected =
1771 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1772 \\$ <kbd>./test</kbd>
1773 \\output
1774 \\</samp></pre></figure>
1775 ;
1776
1777 var buffer = std.ArrayList(u8).init(test_allocator);
1778 defer buffer.deinit();
1779
1780 try printShell(buffer.writer(), shell_out);
1781 try testing.expectEqualSlices(u8, expected, buffer.items);
1782 }
1783 {
1784 const shell_out =
1785 \\$ zig build test.zig \
1786 \\ --build-option
1787 \\build output
1788 \\$ ./test
1789 \\output
1790 ;
1791 const expected =
1792 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \
1793 \\ --build-option</kbd>
1794 \\build output
1795 \\$ <kbd>./test</kbd>
1796 \\output
1797 \\</samp></pre></figure>
1798 ;
1799
1800 var buffer = std.ArrayList(u8).init(test_allocator);
1801 defer buffer.deinit();
1802
1803 try printShell(buffer.writer(), shell_out);
1804 try testing.expectEqualSlices(u8, expected, buffer.items);
1805 }
1806 {
1807 // intentional space after "--build-option1 \"
1808 const shell_out =
1809 \\$ zig build test.zig \
1810 \\ --build-option1 \
1811 \\ --build-option2
1812 \\$ ./test
1813 ;
1814 const expected =
1815 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \
1816 \\ --build-option1 \
1817 \\ --build-option2</kbd>
1818 \\$ <kbd>./test</kbd>
1819 \\</samp></pre></figure>
1820 ;
1821
1822 var buffer = std.ArrayList(u8).init(test_allocator);
1823 defer buffer.deinit();
1824
1825 try printShell(buffer.writer(), shell_out);
1826 try testing.expectEqualSlices(u8, expected, buffer.items);
1827 }
1828 {
1829 const shell_out =
1830 \\$ zig build test.zig \
1831 \\$ ./test
1832 ;
1833 const expected =
1834 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig \
1835 \\$ ./test</kbd>
1836 \\</samp></pre></figure>
1837 ;
1838
1839 var buffer = std.ArrayList(u8).init(test_allocator);
1840 defer buffer.deinit();
1841
1842 try printShell(buffer.writer(), shell_out);
1843 try testing.expectEqualSlices(u8, expected, buffer.items);
1844 }
1845 {
1846 const shell_out =
1847 \\$ zig build test.zig
1848 \\$ ./test
1849 \\$1
1850 ;
1851 const expected =
1852 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$ <kbd>zig build test.zig</kbd>
1853 \\$ <kbd>./test</kbd>
1854 \\$1
1855 \\</samp></pre></figure>
1856 ;
1857
1858 var buffer = std.ArrayList(u8).init(test_allocator);
1859 defer buffer.deinit();
1860
1861 try printShell(buffer.writer(), shell_out);
1862 try testing.expectEqualSlices(u8, expected, buffer.items);
1863 }
1864 {
1865 const shell_out =
1866 \\$zig build test.zig
1867 ;
1868 const expected =
1869 \\<figure><figcaption class="shell-cap">Shell</figcaption><pre><samp>$zig build test.zig
1870 \\</samp></pre></figure>
1871 ;
1872
1873 var buffer = std.ArrayList(u8).init(test_allocator);
1874 defer buffer.deinit();
1875
1876 try printShell(buffer.writer(), shell_out);
1877 try testing.expectEqualSlices(u8, expected, buffer.items);
1878 }
1879}
doc/langref.html.in+751-661
...@@ -6,225 +6,312 @@...@@ -6,225 +6,312 @@
6 <title>Documentation - The Zig Programming Language</title>6 <title>Documentation - The Zig Programming Language</title>
7 <link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg=="/>7 <link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg=="/>
8 <style>8 <style>
9 :root{
10 --nav-width: 24em;
11 --nav-margin-l: 1em;
12 }
9 body{13 body{
10 font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;14 font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
11 margin: 0;15 margin: 0;
16 line-height: 1.5;
12 }17 }
13 a:not(:hover) {18 header {
14 text-decoration: none;19 padding: 0 1em;
15 }20 }
16 table, th, td {21 #contents {
17 border-collapse: collapse;22 max-width: 60em;
18 border: 1px solid grey;23 margin: auto;
24 padding: 0 1em;
19 }25 }
20 th, td {26 #navigation {
21 padding: 0.1em;27 padding: 0 1em;
22 }28 }
23 .t0_1, .t37, .t37_1 {29
30 @media screen and (min-width: 1025px) {
31 header {
32 margin-left: calc(var(--nav-width) + var(--nav-margin-l));
33 }
34 header h1 {
35 margin: auto;
36 max-width: 30em;
37 }
38 #navigation {
39 overflow: auto;
40 width: var(--nav-width);
41 height: 100vh;
42 position: fixed;
43 top:0;
44 left:0;
45 bottom:0;
46 padding: unset;
47 margin-left: var(--nav-margin-l);
48 }
49 #navigation nav ul {
50 padding-left: 1em;
51 }
52 #contents-wrapper {
53 margin-left: calc(var(--nav-width) + var(--nav-margin-l));
54 }
55 }
56
57 a:hover,a:focus {
58 background: #fff2a8;
59 }
60 dt {
61 font-weight: bold;
62 }
63 table, th, td {
64 border-collapse: collapse;
65 border: 1px solid grey;
66 }
67 th, td {
68 padding: 0.1em;
69 }
70 th[scope=row] {
71 text-align: left;
72 font-weight: normal;
73 }
74 .t0_1, .t37, .t37_1 {
75 font-weight: bold;
76 }
77 .t2_0 {
78 color: #575757;
79 }
80 .t31_1 {
81 color: #b40000;
82 }
83 .t32_1 {
84 color: green;
85 }
86 .t36_1 {
87 color: #005C7A;
88 }
89 .file {
90 font-weight: bold;
91 border: unset;
92 }
93 code {
94 background: #f8f8f8;
95 border: 1px dotted silver;
96 padding-left: 0.3em;
97 padding-right: 0.3em;
98 }
99 pre > code {
100 display: block;
101 overflow: auto;
102 padding: 0.5em;
103 border: 1px solid #eee;
104 line-height: normal;
105 }
106 samp {
107 background: #fafafa;
108 }
109 pre > samp {
110 display: block;
111 overflow: auto;
112 padding: 0.5em;
113 border: 1px solid #eee;
114 line-height: normal;
115 }
116 kbd {
117 font-weight: bold;
118 }
119 .table-wrapper {
120 width: 100%;
121 overflow-x: auto;
122 }
123
124 .tok-kw {
125 color: #333;
24 font-weight: bold;126 font-weight: bold;
127 }
128 .tok-str {
129 color: #d14;
130 }
131 .tok-builtin {
132 color: #005C7A;
133 }
134 .tok-comment {
135 color: #545454;
136 font-style: italic;
137 }
138 .tok-fn {
139 color: #900;
140 font-weight: bold;
141 }
142 .tok-null {
143 color: #005C5C;
144 }
145 .tok-number {
146 color: #005C5C;
147 }
148 .tok-type {
149 color: #458;
150 font-weight: bold;
151 }
152
153 figure {
154 margin: auto 0;
155 }
156 figure pre {
157 margin-top: 0;
158 }
159
160 figcaption {
161 padding-left: 0.5em;
162 font-size: small;
163 border-top-left-radius: 5px;
164 border-top-right-radius: 5px;
165 }
166 figcaption.zig-cap {
167 background: #fcdba5;
168 }
169 figcaption.c-cap {
170 background: #a8b9cc;
171 color: #000;
172 }
173 figcaption.javascript-cap {
174 background: #365d95;
175 color: #fff;
176 }
177 figcaption.shell-cap {
178 background: #ccc;
179 color: #000;
180 }
181
182 aside {
183 border-left: 0.25em solid #f7a41d;
184 padding: 0 1em 0 1em;
185 }
186
187 h1 a, h2 a, h3 a, h4 a, h5 a {
188 text-decoration: none;
189 color: #333;
190 }
191
192 a.hdr {
193 visibility: hidden;
194 }
195 h1:hover > a.hdr, h2:hover > a.hdr, h3:hover > a.hdr, h4:hover > a.hdr, h5:hover > a.hdr {
196 visibility: visible;
197 }
198
199 @media (prefers-color-scheme: dark) {
200 body{
201 background:#121212;
202 color: #ccc;
203 }
204 a {
205 color: #88f;
206 }
207 a:hover,a:focus {
208 color: #000;
209 }
210 table, th, td {
211 border-color: grey;
25 }212 }
26 .t2_0 {213 .t2_0 {
27 color: grey;214 color: grey;
28 }215 }
29 .t31_1 {216 .t31_1 {
30 color: red;217 color: red;
31 }218 }
32 .t32_1 {219 .t32_1 {
33 color: green;220 color: #00B800;
34 }221 }
35 .t36_1 {222 .t36_1 {
36 color: #0086b3;223 color: #0086b3;
37 }224 }
38 .file {225 code {
39 text-decoration: underline;226 background: #222;
227 border-color: #444;
40 }228 }
41 pre > code {229 pre > code {
42 display: block;230 color: #ccc;
43 overflow: auto;231 background: #222;
44 padding: 0.5em;232 border: unset;
45 color: #333;
46 background: #f8f8f8;
47 border: 1px dotted silver;
48 line-height: normal;
49 }233 }
50 code {234 samp {
51 background-color: #f8f8f8;235 background: #000;
52 border: 1px dotted silver;236 color: #ccc;
53 padding-left: 0.3em;
54 padding-right: 0.3em;
55 }237 }
56 .table-wrapper {238 pre > samp {
57 width: 100%;239 border: unset;
58 overflow-y: auto;
59 }240 }
60
61 .tok-kw {241 .tok-kw {
62 color: #333;242 color: #eee;
63 font-weight: bold;
64 }243 }
65 .tok-str {244 .tok-str {
66 color: #d14;245 color: #2e5;
67 }246 }
68 .tok-builtin {247 .tok-builtin {
69 color: #0086b3;248 color: #ff894c;
70 }249 }
71 .tok-comment {250 .tok-comment {
72 color: #777;251 color: #aa7;
73 font-style: italic;
74 }252 }
75 .tok-fn {253 .tok-fn {
76 color: #900;254 color: #B1A0F8;
77 font-weight: bold;
78 }255 }
79 .tok-null {256 .tok-null {
80 color: #008080;257 color: #ff8080;
81 }258 }
82 .tok-number {259 .tok-number {
83 color: #008080;260 color: #ff8080;
84 }261 }
85 .tok-type {262 .tok-type {
86 color: #458;263 color: #68f;
87 font-weight: bold;
88 }
89
90 #main-wrapper {
91 display: flex;
92 flex-direction: column;
93 }
94
95 #contents-wrapper {
96 flex-grow: 1;
97 padding: 0 2em;
98 }264 }
99
100 #contents {
101 max-width: 60em;
102 margin: auto;
103 line-height: 1.5;
104 }
105
106 #toc {
107 padding: 0 1em;
108 }
109
110 @media screen and (min-width: 1025px) {
111 #main-wrapper {
112 flex-direction: row;
113 }
114 #toc {
115 height: 100vh;
116 position: sticky;
117 top: 0;
118 }
119 #contents-wrapper, #toc {
120 overflow: auto;
121 }
122 }
123
124 h1 a, h2 a, h3 a, h4 a, h5 a {265 h1 a, h2 a, h3 a, h4 a, h5 a {
125 text-decoration: none;266 color: #aaa;
126 color: #333;
127 }267 }
128268 figcaption.zig-cap {
129 a.hdr {269 background-color: #b27306;
130 visibility: hidden;270 color: #000;
131 }
132 h1:hover > a.hdr, h2:hover > a.hdr, h3:hover > a.hdr, h4:hover > a.hdr, h5:hover > a.hdr {
133 visibility: visible;
134 }271 }
135272 figcaption.shell-cap {
136 @media (prefers-color-scheme: dark) {273 background: #2a2a2a;
137 body{274 color: #fff;
138 background-color:#111;
139 color: #bbb;
140 }
141 a {
142 color: #f7a31d;
143 }
144 table, th, td {
145 border-color: grey;
146 }
147 .t2_0 {
148 color: grey;
149 }
150 .t31_1 {
151 color: red;
152 }
153 .t32_1 {
154 color: green;
155 }
156 .t36_1 {
157 color: #0086b3;
158 }
159 pre > code {
160 color: #ccc;
161 background: #222;
162 border-color: #444;
163 }
164 code {
165 background-color: #222;
166 border-color: #444;
167 }
168 .tok-kw {
169 color: #eee;
170 }
171 .tok-str {
172 color: #2e5;
173 }
174 .tok-builtin {
175 color: #ff894c;
176 }
177 .tok-comment {
178 color: #aa7;
179 }
180 .tok-fn {
181 color: #e33;
182 }
183 .tok-null {
184 color: #ff8080;
185 }
186 .tok-number {
187 color: #ff8080;
188 }
189 .tok-type {
190 color: #68f;
191 }
192 h1 a, h2 a, h3 a, h4 a, h5 a {
193 color: #aaa;
194 }
195 }275 }
196 </style>276 }
197 </head>277 </style>
198 <body>278</head>
199 <div id="main-wrapper">279<body>
200 <div id="toc">280 <header><h1>Zig Language Reference</h1></header>
201 <a href="https://ziglang.org/documentation/0.1.1/">0.1.1</a> |281 <div id="main-wrapper">
202 <a href="https://ziglang.org/documentation/0.2.0/">0.2.0</a> |282 <div id="navigation">
203 <a href="https://ziglang.org/documentation/0.3.0/">0.3.0</a> |283 <nav aria-labelledby="zig-version">
204 <a href="https://ziglang.org/documentation/0.4.0/">0.4.0</a> |284 <h2 id="zig-version">Zig Version</h2>
205 <a href="https://ziglang.org/documentation/0.5.0/">0.5.0</a> |285 <a href="https://ziglang.org/documentation/0.1.1/">0.1.1</a> |
206 <a href="https://ziglang.org/documentation/0.6.0/">0.6.0</a> |286 <a href="https://ziglang.org/documentation/0.2.0/">0.2.0</a> |
207 <a href="https://ziglang.org/documentation/0.7.1/">0.7.1</a> |287 <a href="https://ziglang.org/documentation/0.3.0/">0.3.0</a> |
208 <a href="https://ziglang.org/documentation/0.8.1/">0.8.1</a> |288 <a href="https://ziglang.org/documentation/0.4.0/">0.4.0</a> |
209 master289 <a href="https://ziglang.org/documentation/0.5.0/">0.5.0</a> |
210 <h1>Contents</h1>290 <a href="https://ziglang.org/documentation/0.6.0/">0.6.0</a> |
211 {#nav#}291 <a href="https://ziglang.org/documentation/0.7.1/">0.7.1</a> |
292 <a href="https://ziglang.org/documentation/0.8.1/">0.8.1</a> |
293 master
294 </nav>
295 <nav aria-labelledby="table-of-contents">
296 <h2 id="table-of-contents">Table of Contents</h2>
297 {#nav#}
298 </nav>
212 </div>299 </div>
213 <div id="contents-wrapper"><div id="contents">300 <div id="contents-wrapper"><main id="contents">
214 {#header_open|Introduction#}301 {#header_open|Introduction#}
215 <p>302 <p>
216 Zig is a general-purpose programming language and toolchain for maintaining303 <a href="https://ziglang.org">Zig</a> is a general-purpose programming language and toolchain for maintaining
217 <strong>robust</strong>, <strong>optimal</strong>, and <strong>reusable</strong> software.304 <strong>robust</strong>, <strong>optimal</strong>, and <strong>reusable</strong> software.
218 </p>305 </p>
219 <ul>306 <dl>
220 <li><strong>Robust</strong> - behavior is correct even for edge cases such as out of memory.</li>307 <dt>Robust</dt><dd>Behavior is correct even for edge cases such as out of memory.</dd>
221 <li><strong>Optimal</strong> - write programs the best way they can behave and perform.</li>308 <dt>Optimal</dt><dd>Write programs the best way they can behave and perform.</dd>
222 <li><strong>Reusable</strong> - the same code works in many environments which have different309 <dt>Reusable</dt><dd>The same code works in many environments which have different
223 constraints.</li>310 constraints.</dd>
224 <li><strong>Maintainable</strong> - precisely communicate intent to the compiler and311 <dt>Maintainable</dt><dd>Precisely communicate intent to the compiler and
225 other programmers. The language imposes a low overhead to reading code and is312 other programmers. The language imposes a low overhead to reading code and is
226 resilient to changing requirements and environments.</li>313 resilient to changing requirements and environments.</dd>
227 </ul>314 </dl>
228 <p>315 <p>
229 Often the most efficient way to learn something new is to see examples, so316 Often the most efficient way to learn something new is to see examples, so
230 this documentation shows how to use each of Zig's features. It is317 this documentation shows how to use each of Zig's features. It is
...@@ -236,8 +323,16 @@...@@ -236,8 +323,16 @@
236 <p>323 <p>
237 This HTML document depends on no external files, so you can use it offline.324 This HTML document depends on no external files, so you can use it offline.
238 </p>325 </p>
326 {#header_close#}
327
328 {#header_open|Zig Standard Library#}
329 <p>
330 The <a href="https://ziglang.org/documentation/master/std/">Zig Standard Library</a> has its own documentation.
331 </p>
239 <p>332 <p>
240 <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Where is the documentation for the Zig standard library?</a>333 Zig's Standard Library contains commonly used algorithms, data structures, and definitions to help you build programs or libraries.
334 You will see many examples of Zig's Standard Library used in this documentation. To learn more about the Zig Standard Library,
335 visit the link above.
241 </p>336 </p>
242 {#header_close#}337 {#header_close#}
243338
...@@ -252,96 +347,102 @@ pub fn main() !void {...@@ -252,96 +347,102 @@ pub fn main() !void {
252}347}
253 {#code_end#}348 {#code_end#}
254 <p>349 <p>
255 The Zig code sample above demonstrates one way to create a program that will output <code>Hello, world!</code>.350 The Zig code sample above demonstrates one way to create a program that will output: <samp>Hello, world!</samp>.
256 </p>351 </p>
257 <p>352 <p>
258 The code sample shows the contents of a file named <code>hello.zig</code>. Files storing Zig353 The code sample shows the contents of a file named <code class="file">hello.zig</code>. Files storing Zig
259 source code are {#link|UTF-8 encoded|Source Encoding#} text files. The files storing354 source code are {#link|UTF-8 encoded|Source Encoding#} text files. The files storing
260 Zig source code are usually named with the <code>.zig</code> extension.355 Zig source code are usually named with the <code class="file"><em>.zig</em></code> extension.
261 </p>356 </p>
262 <p>357 <p>
263 Following the <code>hello.zig</code> Zig code sample, the {#link|Zig Build System#} is used358 Following the <code class="file">hello.zig</code> Zig code sample, the {#link|Zig Build System#} is used
264 to build an executable program from the <code>hello.zig</code> source code. Then, the359 to build an executable program from the <code class="file">hello.zig</code> source code. Then, the
265 <code>hello</code> program is executed showing its output <code>Hello, world!</code>. The360 <code class="file">hello</code> program is executed showing its output <samp>Hello, world!</samp>. The
266 lines beginning with <code>$</code> represent command line prompts and a command.361 lines beginning with <samp>$</samp> represent command line prompts and a command.
267 Everything else is program output.362 Everything else is program output.
268 </p>363 </p>
269 <p>364 <p>
270 The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function.365 The code sample begins by adding the {#link|Zig Standard Library#} to the build using the {#link|@import#} builtin function.
271 The {#syntax#}@import("std"){#endsyntax#} function call creates a structure to represent the Standard Library.366 The {#syntax#}@import("std"){#endsyntax#} function call creates a structure that represents the Zig Standard Library.
272 The code then {#link|declares|Container Level Variables#} a367 The code then {#link|declares|Container Level Variables#} a
273 {#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to368 {#link|constant identifier|Assignment#}, named {#syntax#}std{#endsyntax#}, that gives access the features of the Zig Standard Library.
274 <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>.
275 </p>369 </p>
276 <p>370 <p>
277 Next, a {#link|public function|Functions#}, {#syntax#}pub fn{#endsyntax#}, named <code>main</code>371 Next, a {#link|public function|Functions#}, {#syntax#}pub fn{#endsyntax#}, named {#syntax#}main{#endsyntax#}
278 is declared. The <code>main</code> function is necessary because it tells the Zig compiler where the start of372 is declared. The {#syntax#}main{#endsyntax#} function is necessary because it tells the Zig compiler where the start of
279 the program exists. Programs designed to be executed will need a {#syntax#}pub fn main{#endsyntax#} function.373 the program exists. Programs designed to be executed will need a {#syntax#}pub fn main{#endsyntax#} function.
280 For more advanced use cases, Zig offers other features to inform the compiler where the start of
281 the program exists. Libraries, on the other hand, do not need a <code>main</code> function because
282 library code is usually called by other programs.
283 </p>374 </p>
375 <aside role="note" aria-label="Note about main function">
376 <p>
377 For more advanced use cases, Zig offers other features to inform the compiler where the start of
378 the program exists. Also, libraries do not need a {#syntax#}pub fn main{#endsyntax#} function because
379 library code is called by other programs or libraries.
380 </p>
381 </aside>
284 <p>382 <p>
285 A function is a block of any number of statements and expressions that, as a whole, perform a task.383 A function is a block of any number of statements and expressions that, as a whole, perform a task.
286 Functions may or may not return data after they are done performing their task. If a function384 Functions may or may not return data after they are done performing their task. If a function
287 cannot perform its task, it might return an error. Zig makes all of this explicit.385 cannot perform its task, it might return an error. Zig makes all of this explicit.
288 </p>386 </p>
289 <p>387 <p>
290 In the <code>hello.zig</code> code sample, the <code>main</code> function is declared388 In the <code class="file">hello.zig</code> code sample, the <code>main</code> function is declared
291 with the {#syntax#}!void{#endsyntax#} return type. This return type is known as an {#link|Error Union Type#}.389 with the {#syntax#}!void{#endsyntax#} return type. This return type is known as an {#link|Error Union Type#}.
292 This syntax tells the Zig compiler that the function will either return an390 This syntax tells the Zig compiler that the function will either return an
293 error or a value. An error union type combines an {#link|Error Set Type#} and a {#link|Primitive Type|Primitive Types#}.391 error or a value. An error union type combines an {#link|Error Set Type#} and any other data type
392 (e.g. a {#link|Primitive Type|Primitive Types#} or a user-defined type such as a {#link|struct#}, {#link|enum#}, or {#link|union#}).
294 The full form of an error union type is393 The full form of an error union type is
295 <code>&lt;error set type&gt;</code>{#syntax#}!{#endsyntax#}<code>&lt;primitive type&gt;</code>. In the code394 <code>&lt;error set type&gt;</code>{#syntax#}!{#endsyntax#}<code>&lt;any data type&gt;</code>. In the code
296 sample, the error set type is not explicitly written on the left side of the {#syntax#}!{#endsyntax#} operator.395 sample, the error set type is not explicitly written on the left side of the {#syntax#}!{#endsyntax#} operator.
297 When written this way, the error set type is a special kind of error union type that has an396 When written this way, the error set type is an {#link|inferred error set type|Inferred Error Sets#}. The
298 {#link|inferred error set type|Inferred Error Sets#}. The {#syntax#}void{#endsyntax#} after the {#syntax#}!{#endsyntax#} operator397 {#syntax#}void{#endsyntax#} after the {#syntax#}!{#endsyntax#} operator
299 tells the compiler that the function will not return a value under normal circumstances (i.e. no errors occur).398 tells the compiler that the function will not return a value under normal circumstances (i.e. when no errors occur).
300 </p>
301 <p>
302 Note to experienced programmers: Zig also has the boolean {#link|operator|Operators#} {#syntax#}!a{#endsyntax#}
303 where {#syntax#}a{#endsyntax#} is a value of type {#syntax#}bool{#endsyntax#}. Error union types contain the
304 name of the type in the syntax: {#syntax#}!{#endsyntax#}<code>&lt;primitive type&gt;</code>.
305 </p>399 </p>
400 <aside role="note" aria-label="Note to disambiguate exclamation mark operator">
401 <p>
402 Note to experienced programmers: Zig also has the boolean {#link|operator|Operators#} {#syntax#}!a{#endsyntax#}
403 where {#syntax#}a{#endsyntax#} is a value of type {#syntax#}bool{#endsyntax#}. Error union types contain the
404 name of the type in the syntax: {#syntax#}!{#endsyntax#}<code>&lt;any data type&gt;</code>.
405 </p>
406 </aside>
306 <p>407 <p>
307 In Zig, a function's block of statements and expressions are surrounded by <code>{</code> and408 In Zig, a function's block of statements and expressions are surrounded by an open curly-brace <code>{</code> and
308 <code>}</code> curly-braces. Inside of the <code>main</code> function are expressions that perform409 close curly-brace <code>}</code>. Inside of the {#syntax#}main{#endsyntax#} function are expressions that perform
309 the task of outputting <code>Hello, world!</code> to standard output.410 the task of outputting <samp>Hello, world!</samp> to standard output.
310 </p>411 </p>
311 <p>412 <p>
312 First, a constant identifier, <code>stdout</code>, is initialized to represent standard output's413 First, a constant identifier, {#syntax#}stdout{#endsyntax#}, is initialized to represent standard output's
313 writer. Then, the program tries to print the <code>Hello, world!</code>414 writer. Then, the program tries to print the <samp>Hello, world!</samp>
314 message to standard output.415 message to standard output.
315 </p>416 </p>
316 <p>417 <p>
317 Functions sometimes need information to perform their task. In Zig, information is passed418 Functions sometimes need information to perform their task. In Zig, information is passed
318 to functions between open <code>(</code> and close <code>)</code> parenthesis placed after419 to functions between an open parenthesis {#syntax#}({#endsyntax#} and a close parenthesis {#syntax#}){#endsyntax#} placed after
319 the function's name. This information is also known as arguments. When there are420 the function's name. This information is also known as arguments. When there are
320 multiple arguments passed to a function, they are separated by commas <code>,</code>.421 multiple arguments passed to a function, they are separated by commas {#syntax#},{#endsyntax#}.
321 </p>422 </p>
322 <p>423 <p>
323 The two arguments passed to the <code>stdout.print()</code> function, <code>"Hello, {s}!\n"</code>424 The two arguments passed to the {#syntax#}stdout.print(){#endsyntax#} function, {#syntax#}"Hello, {s}!\n"{#endsyntax#}
324 and <code>.{"world"}</code>, are evaluated at {#link|compile-time|comptime#}. The code sample is425 and {#syntax#}.{"world"}{#endsyntax#}, are evaluated at {#link|compile-time|comptime#}. The code sample is
325 purposely written to show how to perform {#link|string|String Literals and Unicode Code Point Literals#}426 purposely written to show how to perform {#link|string|String Literals and Unicode Code Point Literals#}
326 substitution in the <code>print</code> function. The curly-braces inside of the first argument427 substitution in the {#syntax#}print{#endsyntax#} function. The curly-braces inside of the first argument
327 are substituted with the compile-time known value inside of the second argument428 are substituted with the compile-time known value inside of the second argument
328 (known as an {#link|anonymous struct literal|Anonymous Struct Literals#}). The <code>\n</code>429 (known as an {#link|anonymous struct literal|Anonymous Struct Literals#}). The <code>\n</code>
329 inside of the double-quotes of the first argument is the {#link|escape sequence|Escape Sequences#} for the430 inside of the double-quotes of the first argument is the {#link|escape sequence|Escape Sequences#} for the
330 newline character. The {#link|try#} expression evaluates the result of <code>stdout.print</code>.431 newline character. The {#link|try#} expression evaluates the result of {#syntax#}stdout.print{#endsyntax#}.
331 If the result is an error, then the {#syntax#}try{#endsyntax#} expression will return from432 If the result is an error, then the {#syntax#}try{#endsyntax#} expression will return from
332 <code>main</code> with the error. Otherwise, the program will continue. In this case, there are no433 {#syntax#}main{#endsyntax#} with the error. Otherwise, the program will continue. In this case, there are no
333 more statements or expressions left to execute in the <code>main</code> function, so the program exits.434 more statements or expressions left to execute in the {#syntax#}main{#endsyntax#} function, so the program exits.
334 </p>435 </p>
335 <p>436 <p>
336 In Zig, the standard output writer's <code>print</code> function is allowed to fail because437 In Zig, the standard output writer's {#syntax#}print{#endsyntax#} function is allowed to fail because
337 it is actually a function defined as part of a generic Writer. Consider a generic Writer that438 it is actually a function defined as part of a generic Writer. Consider a generic Writer that
338 represents writing data to a file. When the disk is full, a write to the file will fail.439 represents writing data to a file. When the disk is full, a write to the file will fail.
339 However, we typically do not expect writing text to the standard output to fail. To avoid having440 However, we typically do not expect writing text to the standard output to fail. To avoid having
340 to handle the failure case of printing to standard output, you can use alternate functions: the441 to handle the failure case of printing to standard output, you can use alternate functions: the
341 functions in <code>std.log</code> for proper logging or the <code>std.debug.print</code> function.442 functions in {#syntax#}std.log{#endsyntax#} for proper logging or the {#syntax#}std.debug.print{#endsyntax#} function.
342 This documentation will use the latter option to print to standard error (stderr) and silently return443 This documentation will use the latter option to print to standard error (stderr) and silently return
343 on failure. The next code sample, <code>hello_again.zig</code> demonstrates the use of444 on failure. The next code sample, <code class="file">hello_again.zig</code> demonstrates the use of
344 <code>std.debug.print</code>.445 {#syntax#}std.debug.print{#endsyntax#}.
345 </p>446 </p>
346 {#code_begin|exe|hello_again#}447 {#code_begin|exe|hello_again#}
347const print = @import("std").debug.print;448const print = @import("std").debug.print;
...@@ -351,13 +452,13 @@ pub fn main() void {...@@ -351,13 +452,13 @@ pub fn main() void {
351}452}
352 {#code_end#}453 {#code_end#}
353 <p>454 <p>
354 Note that you can leave off the {#syntax#}!{#endsyntax#} from the return type because <code>std.debug.print</code> cannot fail.455 Note that you can leave off the {#syntax#}!{#endsyntax#} from the return type because {#syntax#}std.debug.print{#endsyntax#} cannot fail.
355 </p>456 </p>
356 {#see_also|Values|@import|Errors|Root Source File|Source Encoding#}457 {#see_also|Values|@import|Errors|Root Source File|Source Encoding#}
357 {#header_close#}458 {#header_close#}
358 {#header_open|Zig Test#}459 {#header_open|Zig Test#}
359 <p>460 <p>
360 <code>zig test</code> is a tool that can be used to quickly build and run Zig code461 <kbd>zig test</kbd> is a tool that can be used to quickly build and run Zig code
361 to make sure behavior meets expectations. {#syntax#}@import("builtin").is_test{#endsyntax#}462 to make sure behavior meets expectations. {#syntax#}@import("builtin").is_test{#endsyntax#}
362 is available for code to detect whether the current build is a test build.463 is available for code to detect whether the current build is a test build.
363 </p>464 </p>
...@@ -387,7 +488,7 @@ test "unused function" { }...@@ -387,7 +488,7 @@ test "unused function" { }
387 undefined behavior. The implementation of {#syntax#}std.debug.assert{#endsyntax#} is as488 undefined behavior. The implementation of {#syntax#}std.debug.assert{#endsyntax#} is as
388 simple as:489 simple as:
389 </p>490 </p>
390 {#code_begin|syntax#}491 {#code_begin|syntax|assert#}
391pub fn assert(ok: bool) void {492pub fn assert(ok: bool) void {
392 if (!ok) unreachable;493 if (!ok) unreachable;
393}494}
...@@ -396,7 +497,7 @@ pub fn assert(ok: bool) void {...@@ -396,7 +497,7 @@ pub fn assert(ok: bool) void {
396 This means that when testing in ReleaseFast or ReleaseSmall mode, {#syntax#}assert{#endsyntax#}497 This means that when testing in ReleaseFast or ReleaseSmall mode, {#syntax#}assert{#endsyntax#}
397 is not sufficient to check the result of a computation:498 is not sufficient to check the result of a computation:
398 </p>499 </p>
399 {#code_begin|syntax#}500 {#code_begin|syntax|assert_release_fast_mode#}
400const std = @import("std");501const std = @import("std");
401const assert = std.debug.assert;502const assert = std.debug.assert;
402503
...@@ -423,14 +524,13 @@ test "expect in release fast mode" {...@@ -423,14 +524,13 @@ test "expect in release fast mode" {
423 {#code_end#}524 {#code_end#}
424 <p>See the rest of the {#syntax#}std.testing{#endsyntax#} namespace for more available functions.</p>525 <p>See the rest of the {#syntax#}std.testing{#endsyntax#} namespace for more available functions.</p>
425 <p>526 <p>
426 <code>zig test</code> has a few command line parameters which affect the compilation. See527 <kbd>zig test</kbd> has a few command line parameters which affect the compilation. See
427 <code>zig --help</code> for a full list. The most interesting one is <code>--test-filter [text]</code>.528 <kbd>zig --help</kbd> for a full list. The most interesting one is <kbd>--test-filter [text]</kbd>.
428 This makes the test build only include tests whose name contains the supplied filter text.529 This makes the test build only include tests whose name contains the supplied filter text.
429 Again, thanks to lazy analysis, this can allow you to narrow a build to only a few functions in530 Again, thanks to lazy analysis, this can allow you to narrow a build to only a few functions in
430 isolation.531 isolation.
431 </p>532 </p>
432 {#header_close#}533 {#header_close#}
433
434 {#header_open|Comments#}534 {#header_open|Comments#}
435 {#code_begin|test|comments#}535 {#code_begin|test|comments#}
436const expect = @import("std").testing.expect;536const expect = @import("std").testing.expect;
...@@ -555,184 +655,183 @@ pub fn main() void {...@@ -555,184 +655,183 @@ pub fn main() void {
555 {#header_open|Primitive Types#}655 {#header_open|Primitive Types#}
556 <div class="table-wrapper">656 <div class="table-wrapper">
557 <table>657 <table>
558 <tr>658 <caption>Primitive Types</caption>
559 <th>659 <thead>
560 Name660 <tr>
561 </th>661 <th scope="col">Type</th>
562 <th>662 <th scope="col">C Equivalent</th>
563 C Equivalent663 <th scope="col">Description</th>
564 </th>
565 <th>
566 Description
567 </th>
568 </tr>664 </tr>
665 </thead>
666 <tbody>
569 <tr>667 <tr>
570 <td>{#syntax#}i8{#endsyntax#}</td>668 <th scope="row">{#syntax#}i8{#endsyntax#}</th>
571 <td><code class="c">int8_t</code></td>669 <td><code class="c">int8_t</code></td>
572 <td>signed 8-bit integer</td>670 <td>signed 8-bit integer</td>
573 </tr>671 </tr>
574 <tr>672 <tr>
575 <td>{#syntax#}u8{#endsyntax#}</td>673 <th scope="row">{#syntax#}u8{#endsyntax#}</th>
576 <td><code class="c">uint8_t</code></td>674 <td><code class="c">uint8_t</code></td>
577 <td>unsigned 8-bit integer</td>675 <td>unsigned 8-bit integer</td>
578 </tr>676 </tr>
579 <tr>677 <tr>
580 <td>{#syntax#}i16{#endsyntax#}</td>678 <th scope="row">{#syntax#}i16{#endsyntax#}</th>
581 <td><code class="c">int16_t</code></td>679 <td><code class="c">int16_t</code></td>
582 <td>signed 16-bit integer</td>680 <td>signed 16-bit integer</td>
583 </tr>681 </tr>
584 <tr>682 <tr>
585 <td>{#syntax#}u16{#endsyntax#}</td>683 <th scope="row">{#syntax#}u16{#endsyntax#}</th>
586 <td><code class="c">uint16_t</code></td>684 <td><code class="c">uint16_t</code></td>
587 <td>unsigned 16-bit integer</td>685 <td>unsigned 16-bit integer</td>
588 </tr>686 </tr>
589 <tr>687 <tr>
590 <td>{#syntax#}i32{#endsyntax#}</td>688 <th scope="row">{#syntax#}i32{#endsyntax#}</th>
591 <td><code class="c">int32_t</code></td>689 <td><code class="c">int32_t</code></td>
592 <td>signed 32-bit integer</td>690 <td>signed 32-bit integer</td>
593 </tr>691 </tr>
594 <tr>692 <tr>
595 <td>{#syntax#}u32{#endsyntax#}</td>693 <th scope="row">{#syntax#}u32{#endsyntax#}</th>
596 <td><code class="c">uint32_t</code></td>694 <td><code class="c">uint32_t</code></td>
597 <td>unsigned 32-bit integer</td>695 <td>unsigned 32-bit integer</td>
598 </tr>696 </tr>
599 <tr>697 <tr>
600 <td>{#syntax#}i64{#endsyntax#}</td>698 <th scope="row">{#syntax#}i64{#endsyntax#}</th>
601 <td><code class="c">int64_t</code></td>699 <td><code class="c">int64_t</code></td>
602 <td>signed 64-bit integer</td>700 <td>signed 64-bit integer</td>
603 </tr>701 </tr>
604 <tr>702 <tr>
605 <td>{#syntax#}u64{#endsyntax#}</td>703 <th scope="row">{#syntax#}u64{#endsyntax#}</th>
606 <td><code class="c">uint64_t</code></td>704 <td><code class="c">uint64_t</code></td>
607 <td>unsigned 64-bit integer</td>705 <td>unsigned 64-bit integer</td>
608 </tr>706 </tr>
609 <tr>707 <tr>
610 <td>{#syntax#}i128{#endsyntax#}</td>708 <th scope="row">{#syntax#}i128{#endsyntax#}</th>
611 <td><code class="c">__int128</code></td>709 <td><code class="c">__int128</code></td>
612 <td>signed 128-bit integer</td>710 <td>signed 128-bit integer</td>
613 </tr>711 </tr>
614 <tr>712 <tr>
615 <td>{#syntax#}u128{#endsyntax#}</td>713 <th scope="row">{#syntax#}u128{#endsyntax#}</th>
616 <td><code class="c">unsigned __int128</code></td>714 <td><code class="c">unsigned __int128</code></td>
617 <td>unsigned 128-bit integer</td>715 <td>unsigned 128-bit integer</td>
618 </tr>716 </tr>
619 <tr>717 <tr>
620 <td>{#syntax#}isize{#endsyntax#}</td>718 <th scope="row">{#syntax#}isize{#endsyntax#}</th>
621 <td><code class="c">intptr_t</code></td>719 <td><code class="c">intptr_t</code></td>
622 <td>signed pointer sized integer</td>720 <td>signed pointer sized integer</td>
623 </tr>721 </tr>
624 <tr>722 <tr>
625 <td>{#syntax#}usize{#endsyntax#}</td>723 <th scope="row">{#syntax#}usize{#endsyntax#}</th>
626 <td><code class="c">uintptr_t</code></td>724 <td><code class="c">uintptr_t</code></td>
627 <td>unsigned pointer sized integer</td>725 <td>unsigned pointer sized integer</td>
628 </tr>726 </tr>
629727
630 <tr>728 <tr>
631 <td>{#syntax#}c_short{#endsyntax#}</td>729 <th scope="row">{#syntax#}c_short{#endsyntax#}</th>
632 <td><code class="c">short</code></td>730 <td><code class="c">short</code></td>
633 <td>for ABI compatibility with C</td>731 <td>for ABI compatibility with C</td>
634 </tr>732 </tr>
635 <tr>733 <tr>
636 <td>{#syntax#}c_ushort{#endsyntax#}</td>734 <th scope="row">{#syntax#}c_ushort{#endsyntax#}</th>
637 <td><code class="c">unsigned short</code></td>735 <td><code class="c">unsigned short</code></td>
638 <td>for ABI compatibility with C</td>736 <td>for ABI compatibility with C</td>
639 </tr>737 </tr>
640 <tr>738 <tr>
641 <td>{#syntax#}c_int{#endsyntax#}</td>739 <th scope="row">{#syntax#}c_int{#endsyntax#}</th>
642 <td><code class="c">int</code></td>740 <td><code class="c">int</code></td>
643 <td>for ABI compatibility with C</td>741 <td>for ABI compatibility with C</td>
644 </tr>742 </tr>
645 <tr>743 <tr>
646 <td>{#syntax#}c_uint{#endsyntax#}</td>744 <th scope="row">{#syntax#}c_uint{#endsyntax#}</th>
647 <td><code class="c">unsigned int</code></td>745 <td><code class="c">unsigned int</code></td>
648 <td>for ABI compatibility with C</td>746 <td>for ABI compatibility with C</td>
649 </tr>747 </tr>
650 <tr>748 <tr>
651 <td>{#syntax#}c_long{#endsyntax#}</td>749 <th scope="row">{#syntax#}c_long{#endsyntax#}</th>
652 <td><code class="c">long</code></td>750 <td><code class="c">long</code></td>
653 <td>for ABI compatibility with C</td>751 <td>for ABI compatibility with C</td>
654 </tr>752 </tr>
655 <tr>753 <tr>
656 <td>{#syntax#}c_ulong{#endsyntax#}</td>754 <th scope="row">{#syntax#}c_ulong{#endsyntax#}</th>
657 <td><code class="c">unsigned long</code></td>755 <td><code class="c">unsigned long</code></td>
658 <td>for ABI compatibility with C</td>756 <td>for ABI compatibility with C</td>
659 </tr>757 </tr>
660 <tr>758 <tr>
661 <td>{#syntax#}c_longlong{#endsyntax#}</td>759 <th scope="row">{#syntax#}c_longlong{#endsyntax#}</th>
662 <td><code class="c">long long</code></td>760 <td><code class="c">long long</code></td>
663 <td>for ABI compatibility with C</td>761 <td>for ABI compatibility with C</td>
664 </tr>762 </tr>
665 <tr>763 <tr>
666 <td>{#syntax#}c_ulonglong{#endsyntax#}</td>764 <th scope="row">{#syntax#}c_ulonglong{#endsyntax#}</th>
667 <td><code class="c">unsigned long long</code></td>765 <td><code class="c">unsigned long long</code></td>
668 <td>for ABI compatibility with C</td>766 <td>for ABI compatibility with C</td>
669 </tr>767 </tr>
670 <tr>768 <tr>
671 <td>{#syntax#}c_longdouble{#endsyntax#}</td>769 <th scope="row">{#syntax#}c_longdouble{#endsyntax#}</th>
672 <td><code class="c">long double</code></td>770 <td><code class="c">long double</code></td>
673 <td>for ABI compatibility with C</td>771 <td>for ABI compatibility with C</td>
674 </tr>772 </tr>
675 <tr>773 <tr>
676 <td>{#syntax#}c_void{#endsyntax#}</td>774 <th scope="row">{#syntax#}c_void{#endsyntax#}</th>
677 <td><code class="c">void</code></td>775 <td><code class="c">void</code></td>
678 <td>for ABI compatibility with C</td>776 <td>for ABI compatibility with C</td>
679 </tr>777 </tr>
680778
681 <tr>779 <tr>
682 <td>{#syntax#}f16{#endsyntax#}</td>780 <th scope="row">{#syntax#}f16{#endsyntax#}</th>
683 <td><code class="c">_Float16</code></td>781 <td><code class="c">_Float16</code></td>
684 <td>16-bit floating point (10-bit mantissa) IEEE-754-2008 binary16</td>782 <td>16-bit floating point (10-bit mantissa) IEEE-754-2008 binary16</td>
685 </tr>783 </tr>
686 <tr>784 <tr>
687 <td>{#syntax#}f32{#endsyntax#}</td>785 <th scope="row">{#syntax#}f32{#endsyntax#}</th>
688 <td><code class="c">float</code></td>786 <td><code class="c">float</code></td>
689 <td>32-bit floating point (23-bit mantissa) IEEE-754-2008 binary32</td>787 <td>32-bit floating point (23-bit mantissa) IEEE-754-2008 binary32</td>
690 </tr>788 </tr>
691 <tr>789 <tr>
692 <td>{#syntax#}f64{#endsyntax#}</td>790 <th scope="row">{#syntax#}f64{#endsyntax#}</th>
693 <td><code class="c">double</code></td>791 <td><code class="c">double</code></td>
694 <td>64-bit floating point (52-bit mantissa) IEEE-754-2008 binary64</td>792 <td>64-bit floating point (52-bit mantissa) IEEE-754-2008 binary64</td>
695 </tr>793 </tr>
696 <tr>794 <tr>
697 <td>{#syntax#}f128{#endsyntax#}</td>795 <th scope="row">{#syntax#}f128{#endsyntax#}</th>
698 <td><code class="c">_Float128</code></td>796 <td><code class="c">_Float128</code></td>
699 <td>128-bit floating point (112-bit mantissa) IEEE-754-2008 binary128</td>797 <td>128-bit floating point (112-bit mantissa) IEEE-754-2008 binary128</td>
700 </tr>798 </tr>
701 <tr>799 <tr>
702 <td>{#syntax#}bool{#endsyntax#}</td>800 <th scope="row">{#syntax#}bool{#endsyntax#}</th>
703 <td><code class="c">bool</code></td>801 <td><code class="c">bool</code></td>
704 <td>{#syntax#}true{#endsyntax#} or {#syntax#}false{#endsyntax#}</td>802 <td>{#syntax#}true{#endsyntax#} or {#syntax#}false{#endsyntax#}</td>
705 </tr>803 </tr>
706 <tr>804 <tr>
707 <td>{#syntax#}void{#endsyntax#}</td>805 <th scope="row">{#syntax#}void{#endsyntax#}</th>
708 <td>(none)</td>806 <td>(none)</td>
709 <td>0 bit type</td>807 <td>0 bit type</td>
710 </tr>808 </tr>
711 <tr>809 <tr>
712 <td>{#syntax#}noreturn{#endsyntax#}</td>810 <th scope="row">{#syntax#}noreturn{#endsyntax#}</th>
713 <td>(none)</td>811 <td>(none)</td>
714 <td>the type of {#syntax#}break{#endsyntax#}, {#syntax#}continue{#endsyntax#}, {#syntax#}return{#endsyntax#}, {#syntax#}unreachable{#endsyntax#}, and {#syntax#}while (true) {}{#endsyntax#}</td>812 <td>the type of {#syntax#}break{#endsyntax#}, {#syntax#}continue{#endsyntax#}, {#syntax#}return{#endsyntax#}, {#syntax#}unreachable{#endsyntax#}, and {#syntax#}while (true) {}{#endsyntax#}</td>
715 </tr>813 </tr>
716 <tr>814 <tr>
717 <td>{#syntax#}type{#endsyntax#}</td>815 <th scope="row">{#syntax#}type{#endsyntax#}</th>
718 <td>(none)</td>816 <td>(none)</td>
719 <td>the type of types</td>817 <td>the type of types</td>
720 </tr>818 </tr>
721 <tr>819 <tr>
722 <td>{#syntax#}anyerror{#endsyntax#}</td>820 <th scope="row">{#syntax#}anyerror{#endsyntax#}</th>
723 <td>(none)</td>821 <td>(none)</td>
724 <td>an error code</td>822 <td>an error code</td>
725 </tr>823 </tr>
726 <tr>824 <tr>
727 <td>{#syntax#}comptime_int{#endsyntax#}</td>825 <th scope="row">{#syntax#}comptime_int{#endsyntax#}</th>
728 <td>(none)</td>826 <td>(none)</td>
729 <td>Only allowed for {#link|comptime#}-known values. The type of integer literals.</td>827 <td>Only allowed for {#link|comptime#}-known values. The type of integer literals.</td>
730 </tr>828 </tr>
731 <tr>829 <tr>
732 <td>{#syntax#}comptime_float{#endsyntax#}</td>830 <th scope="row">{#syntax#}comptime_float{#endsyntax#}</th>
733 <td>(none)</td>831 <td>(none)</td>
734 <td>Only allowed for {#link|comptime#}-known values. The type of float literals.</td>832 <td>Only allowed for {#link|comptime#}-known values. The type of float literals.</td>
735 </tr>833 </tr>
834 </tbody>
736 </table>835 </table>
737 </div>836 </div>
738 <p>837 <p>
...@@ -746,26 +845,27 @@ pub fn main() void {...@@ -746,26 +845,27 @@ pub fn main() void {
746 {#header_open|Primitive Values#}845 {#header_open|Primitive Values#}
747 <div class="table-wrapper">846 <div class="table-wrapper">
748 <table>847 <table>
848 <caption>Primitive Values</caption>
849 <thead>
749 <tr>850 <tr>
750 <th>851 <th scope="col">Name</th>
751 Name852 <th scope="col">Description</th>
752 </th>
753 <th>
754 Description
755 </th>
756 </tr>853 </tr>
854 </thead>
855 <tbody>
757 <tr>856 <tr>
758 <td>{#syntax#}true{#endsyntax#} and {#syntax#}false{#endsyntax#}</td>857 <th scope="row">{#syntax#}true{#endsyntax#} and {#syntax#}false{#endsyntax#}</th>
759 <td>{#syntax#}bool{#endsyntax#} values</td>858 <td>{#syntax#}bool{#endsyntax#} values</td>
760 </tr>859 </tr>
761 <tr>860 <tr>
762 <td>{#syntax#}null{#endsyntax#}</td>861 <th scope="row">{#syntax#}null{#endsyntax#}</th>
763 <td>used to set an optional type to {#syntax#}null{#endsyntax#}</td>862 <td>used to set an optional type to {#syntax#}null{#endsyntax#}</td>
764 </tr>863 </tr>
765 <tr>864 <tr>
766 <td>{#syntax#}undefined{#endsyntax#}</td>865 <th scope="row">{#syntax#}undefined{#endsyntax#}</th>
767 <td>used to leave a value unspecified</td>866 <td>used to leave a value unspecified</td>
768 </tr>867 </tr>
868 </tbody>
769 </table>869 </table>
770 </div>870 </div>
771 {#see_also|Optionals|undefined#}871 {#see_also|Optionals|undefined#}
...@@ -796,7 +896,7 @@ pub fn main() void {...@@ -796,7 +896,7 @@ pub fn main() void {
796 in recent versions of the Unicode specification (as of Unicode 13.0).896 in recent versions of the Unicode specification (as of Unicode 13.0).
797 In Zig, a Unicode code point literal corresponds to the Unicode definition of a code point.897 In Zig, a Unicode code point literal corresponds to the Unicode definition of a code point.
798 </p>898 </p>
799 {#code_begin|test#}899 {#code_begin|test|string_literals_test#}
800const expect = @import("std").testing.expect;900const expect = @import("std").testing.expect;
801const mem = @import("std").mem;901const mem = @import("std").mem;
802902
...@@ -817,46 +917,47 @@ test "string literals" {...@@ -817,46 +917,47 @@ test "string literals" {
817 {#header_open|Escape Sequences#}917 {#header_open|Escape Sequences#}
818 <div class="table-wrapper">918 <div class="table-wrapper">
819 <table>919 <table>
920 <caption>Escape Sequences</caption>
921 <thead>
820 <tr>922 <tr>
821 <th>923 <th scope="col">Escape Sequence</th>
822 Escape Sequence924 <th scope="col">Name</th>
823 </th>
824 <th>
825 Name
826 </th>
827 </tr>925 </tr>
926 </thead>
927 <tbody>
828 <tr>928 <tr>
829 <td><code>\n</code></td>929 <th scope="row"><code>\n</code></th>
830 <td>Newline</td>930 <td>Newline</td>
831 </tr>931 </tr>
832 <tr>932 <tr>
833 <td><code>\r</code></td>933 <th scope="row"><code>\r</code></th>
834 <td>Carriage Return</td>934 <td>Carriage Return</td>
835 </tr>935 </tr>
836 <tr>936 <tr>
837 <td><code>\t</code></td>937 <th scope="row"><code>\t</code></th>
838 <td>Tab</td>938 <td>Tab</td>
839 </tr>939 </tr>
840 <tr>940 <tr>
841 <td><code>\\</code></td>941 <th scope="row"><code>\\</code></th>
842 <td>Backslash</td>942 <td>Backslash</td>
843 </tr>943 </tr>
844 <tr>944 <tr>
845 <td><code>\'</code></td>945 <th scope="row"><code>\'</code></th>
846 <td>Single Quote</td>946 <td>Single Quote</td>
847 </tr>947 </tr>
848 <tr>948 <tr>
849 <td><code>\"</code></td>949 <th scope="row"><code>\"</code></th>
850 <td>Double Quote</td>950 <td>Double Quote</td>
851 </tr>951 </tr>
852 <tr>952 <tr>
853 <td><code>\xNN</code></td>953 <th scope="row"><code>\xNN</code></th>
854 <td>hexadecimal 8-bit byte value (2 digits)</td>954 <td>hexadecimal 8-bit byte value (2 digits)</td>
855 </tr>955 </tr>
856 <tr>956 <tr>
857 <td><code>\u{NNNNNN}</code></td>957 <th scope="row"><code>\u{NNNNNN}</code></th>
858 <td>hexadecimal Unicode code point UTF-8 encoded (1 or more digits)</td>958 <td>hexadecimal Unicode code point UTF-8 encoded (1 or more digits)</td>
859 </tr>959 </tr>
960 </tbody>
860 </table>961 </table>
861 </div>962 </div>
862 <p>Note that the maximum valid Unicode point is {#syntax#}0x10ffff{#endsyntax#}.</p>963 <p>Note that the maximum valid Unicode point is {#syntax#}0x10ffff{#endsyntax#}.</p>
...@@ -870,7 +971,7 @@ test "string literals" {...@@ -870,7 +971,7 @@ test "string literals" {
870 However, if the next line begins with {#syntax#}\\{#endsyntax#} then a newline is appended and971 However, if the next line begins with {#syntax#}\\{#endsyntax#} then a newline is appended and
871 the string literal continues.972 the string literal continues.
872 </p>973 </p>
873 {#code_begin|syntax#}974 {#code_begin|syntax|multiline_string_literals#}
874const hello_world_in_c =975const hello_world_in_c =
875 \\#include <stdio.h>976 \\#include <stdio.h>
876 \\977 \\
...@@ -902,7 +1003,7 @@ test "assignment" {...@@ -902,7 +1003,7 @@ test "assignment" {
902 {#code_end#}1003 {#code_end#}
903 <p>{#syntax#}const{#endsyntax#} applies to all of the bytes that the identifier immediately addresses. {#link|Pointers#} have their own const-ness.</p>1004 <p>{#syntax#}const{#endsyntax#} applies to all of the bytes that the identifier immediately addresses. {#link|Pointers#} have their own const-ness.</p>
904 <p>If you need a variable that you can modify, use the {#syntax#}var{#endsyntax#} keyword:</p>1005 <p>If you need a variable that you can modify, use the {#syntax#}var{#endsyntax#} keyword:</p>
905 {#code_begin|test#}1006 {#code_begin|test|var_test#}
906const expect = @import("std").testing.expect;1007const expect = @import("std").testing.expect;
9071008
908test "var" {1009test "var" {
...@@ -923,7 +1024,7 @@ test "initialization" {...@@ -923,7 +1024,7 @@ test "initialization" {
923 {#code_end#}1024 {#code_end#}
924 {#header_open|undefined#}1025 {#header_open|undefined#}
925 <p>Use {#syntax#}undefined{#endsyntax#} to leave variables uninitialized:</p>1026 <p>Use {#syntax#}undefined{#endsyntax#} to leave variables uninitialized:</p>
926 {#code_begin|test#}1027 {#code_begin|test|undefined_test#}
927const expect = @import("std").testing.expect;1028const expect = @import("std").testing.expect;
9281029
929test "init with undefined" {1030test "init with undefined" {
...@@ -1108,7 +1209,7 @@ test "comptime vars" {...@@ -1108,7 +1209,7 @@ test "comptime vars" {
11081209
1109 {#header_open|Integers#}1210 {#header_open|Integers#}
1110 {#header_open|Integer Literals#}1211 {#header_open|Integer Literals#}
1111 {#code_begin|syntax#}1212 {#code_begin|syntax|integer_literals#}
1112const decimal_int = 98222;1213const decimal_int = 98222;
1113const hex_int = 0xff;1214const hex_int = 0xff;
1114const another_hex_int = 0xFF;1215const another_hex_int = 0xFF;
...@@ -1131,7 +1232,7 @@ const big_address = 0xFF80_0000_0000_0000;...@@ -1131,7 +1232,7 @@ const big_address = 0xFF80_0000_0000_0000;
1131 However, once an integer value is no longer known at compile-time, it must have a1232 However, once an integer value is no longer known at compile-time, it must have a
1132 known size, and is vulnerable to undefined behavior.1233 known size, and is vulnerable to undefined behavior.
1133 </p>1234 </p>
1134 {#code_begin|syntax#}1235 {#code_begin|syntax|runtime_vs_comptime#}
1135fn divide(a: i32, b: i32) i32 {1236fn divide(a: i32, b: i32) i32 {
1136 return a / b;1237 return a / b;
1137}1238}
...@@ -1174,7 +1275,7 @@ fn divide(a: i32, b: i32) i32 {...@@ -1174,7 +1275,7 @@ fn divide(a: i32, b: i32) i32 {
1174 Float literals {#link|coerce|Type Coercion#} to any floating point type,1275 Float literals {#link|coerce|Type Coercion#} to any floating point type,
1175 and to any {#link|integer|Integers#} type when there is no fractional component.1276 and to any {#link|integer|Integers#} type when there is no fractional component.
1176 </p>1277 </p>
1177 {#code_begin|syntax#}1278 {#code_begin|syntax|float_literals#}
1178const floating_point = 123.0E+77;1279const floating_point = 123.0E+77;
1179const another_float = 123.0;1280const another_float = 123.0;
1180const yet_another = 123.0e+77;1281const yet_another = 123.0e+77;
...@@ -1192,7 +1293,7 @@ const more_hex = 0x1234_5678.9ABC_CDEFp-10;...@@ -1192,7 +1293,7 @@ const more_hex = 0x1234_5678.9ABC_CDEFp-10;
1192 There is no syntax for NaN, infinity, or negative infinity. For these special values,1293 There is no syntax for NaN, infinity, or negative infinity. For these special values,
1193 one must use the standard library:1294 one must use the standard library:
1194 </p>1295 </p>
1195 {#code_begin|syntax#}1296 {#code_begin|syntax|float_special_values#}
1196const std = @import("std");1297const std = @import("std");
11971298
1198const inf = std.math.inf(f32);1299const inf = std.math.inf(f32);
...@@ -1245,23 +1346,19 @@ pub fn main() void {...@@ -1245,23 +1346,19 @@ pub fn main() void {
1245 {#header_open|Table of Operators#}1346 {#header_open|Table of Operators#}
1246 <div class="table-wrapper">1347 <div class="table-wrapper">
1247 <table>1348 <table>
1349 <caption>Table of Operators</caption>
1350 <thead>
1248 <tr>1351 <tr>
1249 <th>1352 <th scope="col">Syntax</th>
1250 Syntax1353 <th scope="col">Relevant Types</th>
1251 </th>1354 <th scope="col">Description</th>
1252 <th>1355 <th scope="col">Example</th>
1253 Relevant Types
1254 </th>
1255 <th>
1256 Description
1257 </th>
1258 <th>
1259 Example
1260 </th>
1261 </tr>1356 </tr>
1357 </thead>
1358 <tbody>
1262 <tr>1359 <tr>
1263 <td><pre>{#syntax#}a + b1360 <th scope="row"><pre>{#syntax#}a + b
1264a += b{#endsyntax#}</pre></td>1361a += b{#endsyntax#}</pre></th>
1265 <td>1362 <td>
1266 <ul>1363 <ul>
1267 <li>{#link|Integers#}</li>1364 <li>{#link|Integers#}</li>
...@@ -1280,8 +1377,8 @@ a += b{#endsyntax#}</pre></td>...@@ -1280,8 +1377,8 @@ a += b{#endsyntax#}</pre></td>
1280 </td>1377 </td>
1281 </tr>1378 </tr>
1282 <tr>1379 <tr>
1283 <td><pre>{#syntax#}a +% b1380 <th scope="row"><pre>{#syntax#}a +% b
1284a +%= b{#endsyntax#}</pre></td>1381a +%= b{#endsyntax#}</pre></th>
1285 <td>1382 <td>
1286 <ul>1383 <ul>
1287 <li>{#link|Integers#}</li>1384 <li>{#link|Integers#}</li>
...@@ -1299,8 +1396,8 @@ a +%= b{#endsyntax#}</pre></td>...@@ -1299,8 +1396,8 @@ a +%= b{#endsyntax#}</pre></td>
1299 </td>1396 </td>
1300 </tr>1397 </tr>
1301 <tr>1398 <tr>
1302 <td><pre>{#syntax#}a - b1399 <th scope="row"><pre>{#syntax#}a - b
1303a -= b{#endsyntax#}</pre></td>1400a -= b{#endsyntax#}</pre></th>
1304 <td>1401 <td>
1305 <ul>1402 <ul>
1306 <li>{#link|Integers#}</li>1403 <li>{#link|Integers#}</li>
...@@ -1319,8 +1416,8 @@ a -= b{#endsyntax#}</pre></td>...@@ -1319,8 +1416,8 @@ a -= b{#endsyntax#}</pre></td>
1319 </td>1416 </td>
1320 </tr>1417 </tr>
1321 <tr>1418 <tr>
1322 <td><pre>{#syntax#}a -% b1419 <th scope="row"><pre>{#syntax#}a -% b
1323a -%= b{#endsyntax#}</pre></td>1420a -%= b{#endsyntax#}</pre></th>
1324 <td>1421 <td>
1325 <ul>1422 <ul>
1326 <li>{#link|Integers#}</li>1423 <li>{#link|Integers#}</li>
...@@ -1338,7 +1435,7 @@ a -%= b{#endsyntax#}</pre></td>...@@ -1338,7 +1435,7 @@ a -%= b{#endsyntax#}</pre></td>
1338 </td>1435 </td>
1339 </tr>1436 </tr>
1340 <tr>1437 <tr>
1341 <td><pre>{#syntax#}-a{#endsyntax#}</pre></td>1438 <th scope="row"><pre>{#syntax#}-a{#endsyntax#}</pre></th>
1342 <td>1439 <td>
1343 <ul>1440 <ul>
1344 <li>{#link|Integers#}</li>1441 <li>{#link|Integers#}</li>
...@@ -1356,7 +1453,7 @@ a -%= b{#endsyntax#}</pre></td>...@@ -1356,7 +1453,7 @@ a -%= b{#endsyntax#}</pre></td>
1356 </td>1453 </td>
1357 </tr>1454 </tr>
1358 <tr>1455 <tr>
1359 <td><pre>{#syntax#}-%a{#endsyntax#}</pre></td>1456 <th scope="row"><pre>{#syntax#}-%a{#endsyntax#}</pre></th>
1360 <td>1457 <td>
1361 <ul>1458 <ul>
1362 <li>{#link|Integers#}</li>1459 <li>{#link|Integers#}</li>
...@@ -1373,8 +1470,8 @@ a -%= b{#endsyntax#}</pre></td>...@@ -1373,8 +1470,8 @@ a -%= b{#endsyntax#}</pre></td>
1373 </td>1470 </td>
1374 </tr>1471 </tr>
1375 <tr>1472 <tr>
1376 <td><pre>{#syntax#}a * b1473 <th scope="row"><pre>{#syntax#}a * b
1377a *= b{#endsyntax#}</pre></td>1474a *= b{#endsyntax#}</pre></th>
1378 <td>1475 <td>
1379 <ul>1476 <ul>
1380 <li>{#link|Integers#}</li>1477 <li>{#link|Integers#}</li>
...@@ -1393,8 +1490,8 @@ a *= b{#endsyntax#}</pre></td>...@@ -1393,8 +1490,8 @@ a *= b{#endsyntax#}</pre></td>
1393 </td>1490 </td>
1394 </tr>1491 </tr>
1395 <tr>1492 <tr>
1396 <td><pre>{#syntax#}a *% b1493 <th scope="row"><pre>{#syntax#}a *% b
1397a *%= b{#endsyntax#}</pre></td>1494a *%= b{#endsyntax#}</pre></th>
1398 <td>1495 <td>
1399 <ul>1496 <ul>
1400 <li>{#link|Integers#}</li>1497 <li>{#link|Integers#}</li>
...@@ -1412,8 +1509,8 @@ a *%= b{#endsyntax#}</pre></td>...@@ -1412,8 +1509,8 @@ a *%= b{#endsyntax#}</pre></td>
1412 </td>1509 </td>
1413 </tr>1510 </tr>
1414 <tr>1511 <tr>
1415 <td><pre>{#syntax#}a / b1512 <th scope="row"><pre>{#syntax#}a / b
1416a /= b{#endsyntax#}</pre></td>1513a /= b{#endsyntax#}</pre></th>
1417 <td>1514 <td>
1418 <ul>1515 <ul>
1419 <li>{#link|Integers#}</li>1516 <li>{#link|Integers#}</li>
...@@ -1438,8 +1535,8 @@ a /= b{#endsyntax#}</pre></td>...@@ -1438,8 +1535,8 @@ a /= b{#endsyntax#}</pre></td>
1438 </td>1535 </td>
1439 </tr>1536 </tr>
1440 <tr>1537 <tr>
1441 <td><pre>{#syntax#}a % b1538 <th scope="row"><pre>{#syntax#}a % b
1442a %= b{#endsyntax#}</pre></td>1539a %= b{#endsyntax#}</pre></th>
1443 <td>1540 <td>
1444 <ul>1541 <ul>
1445 <li>{#link|Integers#}</li>1542 <li>{#link|Integers#}</li>
...@@ -1462,8 +1559,8 @@ a %= b{#endsyntax#}</pre></td>...@@ -1462,8 +1559,8 @@ a %= b{#endsyntax#}</pre></td>
1462 </td>1559 </td>
1463 </tr>1560 </tr>
1464 <tr>1561 <tr>
1465 <td><pre>{#syntax#}a << b1562 <th scope="row"><pre>{#syntax#}a << b
1466a <<= b{#endsyntax#}</pre></td>1563a <<= b{#endsyntax#}</pre></th>
1467 <td>1564 <td>
1468 <ul>1565 <ul>
1469 <li>{#link|Integers#}</li>1566 <li>{#link|Integers#}</li>
...@@ -1481,8 +1578,8 @@ a <<= b{#endsyntax#}</pre></td>...@@ -1481,8 +1578,8 @@ a <<= b{#endsyntax#}</pre></td>
1481 </td>1578 </td>
1482 </tr>1579 </tr>
1483 <tr>1580 <tr>
1484 <td><pre>{#syntax#}a >> b1581 <th scope="row"><pre>{#syntax#}a >> b
1485a >>= b{#endsyntax#}</pre></td>1582a >>= b{#endsyntax#}</pre></th>
1486 <td>1583 <td>
1487 <ul>1584 <ul>
1488 <li>{#link|Integers#}</li>1585 <li>{#link|Integers#}</li>
...@@ -1499,8 +1596,8 @@ a >>= b{#endsyntax#}</pre></td>...@@ -1499,8 +1596,8 @@ a >>= b{#endsyntax#}</pre></td>
1499 </td>1596 </td>
1500 </tr>1597 </tr>
1501 <tr>1598 <tr>
1502 <td><pre>{#syntax#}a & b1599 <th scope="row"><pre>{#syntax#}a & b
1503a &= b{#endsyntax#}</pre></td>1600a &= b{#endsyntax#}</pre></th>
1504 <td>1601 <td>
1505 <ul>1602 <ul>
1506 <li>{#link|Integers#}</li>1603 <li>{#link|Integers#}</li>
...@@ -1516,8 +1613,8 @@ a &= b{#endsyntax#}</pre></td>...@@ -1516,8 +1613,8 @@ a &= b{#endsyntax#}</pre></td>
1516 </td>1613 </td>
1517 </tr>1614 </tr>
1518 <tr>1615 <tr>
1519 <td><pre>{#syntax#}a | b1616 <th scope="row"><pre>{#syntax#}a | b
1520a |= b{#endsyntax#}</pre></td>1617a |= b{#endsyntax#}</pre></th>
1521 <td>1618 <td>
1522 <ul>1619 <ul>
1523 <li>{#link|Integers#}</li>1620 <li>{#link|Integers#}</li>
...@@ -1533,8 +1630,8 @@ a |= b{#endsyntax#}</pre></td>...@@ -1533,8 +1630,8 @@ a |= b{#endsyntax#}</pre></td>
1533 </td>1630 </td>
1534 </tr>1631 </tr>
1535 <tr>1632 <tr>
1536 <td><pre>{#syntax#}a ^ b1633 <th scope="row"><pre>{#syntax#}a ^ b
1537a ^= b{#endsyntax#}</pre></td>1634a ^= b{#endsyntax#}</pre></th>
1538 <td>1635 <td>
1539 <ul>1636 <ul>
1540 <li>{#link|Integers#}</li>1637 <li>{#link|Integers#}</li>
...@@ -1550,7 +1647,7 @@ a ^= b{#endsyntax#}</pre></td>...@@ -1550,7 +1647,7 @@ a ^= b{#endsyntax#}</pre></td>
1550 </td>1647 </td>
1551 </tr>1648 </tr>
1552 <tr>1649 <tr>
1553 <td><pre>{#syntax#}~a{#endsyntax#}</pre></td>1650 <th scope="row"><pre>{#syntax#}~a{#endsyntax#}</pre></th>
1554 <td>1651 <td>
1555 <ul>1652 <ul>
1556 <li>{#link|Integers#}</li>1653 <li>{#link|Integers#}</li>
...@@ -1564,7 +1661,7 @@ a ^= b{#endsyntax#}</pre></td>...@@ -1564,7 +1661,7 @@ a ^= b{#endsyntax#}</pre></td>
1564 </td>1661 </td>
1565 </tr>1662 </tr>
1566 <tr>1663 <tr>
1567 <td><pre>{#syntax#}a orelse b{#endsyntax#}</pre></td>1664 <th scope="row"><pre>{#syntax#}a orelse b{#endsyntax#}</pre></th>
1568 <td>1665 <td>
1569 <ul>1666 <ul>
1570 <li>{#link|Optionals#}</li>1667 <li>{#link|Optionals#}</li>
...@@ -1582,7 +1679,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1582,7 +1679,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1582 </td>1679 </td>
1583 </tr>1680 </tr>
1584 <tr>1681 <tr>
1585 <td><pre>{#syntax#}a.?{#endsyntax#}</pre></td>1682 <th scope="row"><pre>{#syntax#}a.?{#endsyntax#}</pre></th>
1586 <td>1683 <td>
1587 <ul>1684 <ul>
1588 <li>{#link|Optionals#}</li>1685 <li>{#link|Optionals#}</li>
...@@ -1598,8 +1695,8 @@ value.? == 5678{#endsyntax#}</pre>...@@ -1598,8 +1695,8 @@ value.? == 5678{#endsyntax#}</pre>
1598 </td>1695 </td>
1599 </tr>1696 </tr>
1600 <tr>1697 <tr>
1601 <td><pre>{#syntax#}a catch b1698 <th scope="row"><pre>{#syntax#}a catch b
1602a catch |err| b{#endsyntax#}</pre></td>1699a catch |err| b{#endsyntax#}</pre></th>
1603 <td>1700 <td>
1604 <ul>1701 <ul>
1605 <li>{#link|Error Unions|Errors#}</li>1702 <li>{#link|Error Unions|Errors#}</li>
...@@ -1618,7 +1715,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1618,7 +1715,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1618 </td>1715 </td>
1619 </tr>1716 </tr>
1620 <tr>1717 <tr>
1621 <td><pre>{#syntax#}a and b{#endsyntax#}</pre></td>1718 <th scope="row"><pre>{#syntax#}a and b{#endsyntax#}</pre></th>
1622 <td>1719 <td>
1623 <ul>1720 <ul>
1624 <li>{#link|bool|Primitive Types#}</li>1721 <li>{#link|bool|Primitive Types#}</li>
...@@ -1633,7 +1730,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1633,7 +1730,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1633 </td>1730 </td>
1634 </tr>1731 </tr>
1635 <tr>1732 <tr>
1636 <td><pre>{#syntax#}a or b{#endsyntax#}</pre></td>1733 <th scope="row"><pre>{#syntax#}a or b{#endsyntax#}</pre></th>
1637 <td>1734 <td>
1638 <ul>1735 <ul>
1639 <li>{#link|bool|Primitive Types#}</li>1736 <li>{#link|bool|Primitive Types#}</li>
...@@ -1648,7 +1745,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1648,7 +1745,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1648 </td>1745 </td>
1649 </tr>1746 </tr>
1650 <tr>1747 <tr>
1651 <td><pre>{#syntax#}!a{#endsyntax#}</pre></td>1748 <th scope="row"><pre>{#syntax#}!a{#endsyntax#}</pre></th>
1652 <td>1749 <td>
1653 <ul>1750 <ul>
1654 <li>{#link|bool|Primitive Types#}</li>1751 <li>{#link|bool|Primitive Types#}</li>
...@@ -1662,7 +1759,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1662,7 +1759,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1662 </td>1759 </td>
1663 </tr>1760 </tr>
1664 <tr>1761 <tr>
1665 <td><pre>{#syntax#}a == b{#endsyntax#}</pre></td>1762 <th scope="row"><pre>{#syntax#}a == b{#endsyntax#}</pre></th>
1666 <td>1763 <td>
1667 <ul>1764 <ul>
1668 <li>{#link|Integers#}</li>1765 <li>{#link|Integers#}</li>
...@@ -1680,7 +1777,7 @@ unwrapped == 1234{#endsyntax#}</pre>...@@ -1680,7 +1777,7 @@ unwrapped == 1234{#endsyntax#}</pre>
1680 </td>1777 </td>
1681 </tr>1778 </tr>
1682 <tr>1779 <tr>
1683 <td><pre>{#syntax#}a == null{#endsyntax#}</pre></td>1780 <th scope="row"><pre>{#syntax#}a == null{#endsyntax#}</pre></th>
1684 <td>1781 <td>
1685 <ul>1782 <ul>
1686 <li>{#link|Optionals#}</li>1783 <li>{#link|Optionals#}</li>
...@@ -1695,7 +1792,7 @@ value == null{#endsyntax#}</pre>...@@ -1695,7 +1792,7 @@ value == null{#endsyntax#}</pre>
1695 </td>1792 </td>
1696 </tr>1793 </tr>
1697 <tr>1794 <tr>
1698 <td><pre>{#syntax#}a != b{#endsyntax#}</pre></td>1795 <th scope="row"><pre>{#syntax#}a != b{#endsyntax#}</pre></th>
1699 <td>1796 <td>
1700 <ul>1797 <ul>
1701 <li>{#link|Integers#}</li>1798 <li>{#link|Integers#}</li>
...@@ -1713,7 +1810,7 @@ value == null{#endsyntax#}</pre>...@@ -1713,7 +1810,7 @@ value == null{#endsyntax#}</pre>
1713 </td>1810 </td>
1714 </tr>1811 </tr>
1715 <tr>1812 <tr>
1716 <td><pre>{#syntax#}a > b{#endsyntax#}</pre></td>1813 <th scope="row"><pre>{#syntax#}a > b{#endsyntax#}</pre></th>
1717 <td>1814 <td>
1718 <ul>1815 <ul>
1719 <li>{#link|Integers#}</li>1816 <li>{#link|Integers#}</li>
...@@ -1729,7 +1826,7 @@ value == null{#endsyntax#}</pre>...@@ -1729,7 +1826,7 @@ value == null{#endsyntax#}</pre>
1729 </td>1826 </td>
1730 </tr>1827 </tr>
1731 <tr>1828 <tr>
1732 <td><pre>{#syntax#}a >= b{#endsyntax#}</pre></td>1829 <th scope="row"><pre>{#syntax#}a >= b{#endsyntax#}</pre></th>
1733 <td>1830 <td>
1734 <ul>1831 <ul>
1735 <li>{#link|Integers#}</li>1832 <li>{#link|Integers#}</li>
...@@ -1745,7 +1842,7 @@ value == null{#endsyntax#}</pre>...@@ -1745,7 +1842,7 @@ value == null{#endsyntax#}</pre>
1745 </td>1842 </td>
1746 </tr>1843 </tr>
1747 <tr>1844 <tr>
1748 <td><pre>{#syntax#}a < b{#endsyntax#}</pre></td>1845 <th scope="row"><pre>{#syntax#}a < b{#endsyntax#}</pre></th>
1749 <td>1846 <td>
1750 <ul>1847 <ul>
1751 <li>{#link|Integers#}</li>1848 <li>{#link|Integers#}</li>
...@@ -1761,7 +1858,7 @@ value == null{#endsyntax#}</pre>...@@ -1761,7 +1858,7 @@ value == null{#endsyntax#}</pre>
1761 </td>1858 </td>
1762 </tr>1859 </tr>
1763 <tr>1860 <tr>
1764 <td><pre>{#syntax#}a <= b{#endsyntax#}</pre></td>1861 <th scope="row"><pre>{#syntax#}a <= b{#endsyntax#}</pre></th>
1765 <td>1862 <td>
1766 <ul>1863 <ul>
1767 <li>{#link|Integers#}</li>1864 <li>{#link|Integers#}</li>
...@@ -1777,7 +1874,7 @@ value == null{#endsyntax#}</pre>...@@ -1777,7 +1874,7 @@ value == null{#endsyntax#}</pre>
1777 </td>1874 </td>
1778 </tr>1875 </tr>
1779 <tr>1876 <tr>
1780 <td><pre>{#syntax#}a ++ b{#endsyntax#}</pre></td>1877 <th scope="row"><pre>{#syntax#}a ++ b{#endsyntax#}</pre></th>
1781 <td>1878 <td>
1782 <ul>1879 <ul>
1783 <li>{#link|Arrays#}</li>1880 <li>{#link|Arrays#}</li>
...@@ -1786,7 +1883,7 @@ value == null{#endsyntax#}</pre>...@@ -1786,7 +1883,7 @@ value == null{#endsyntax#}</pre>
1786 <td>1883 <td>
1787 Array concatenation.1884 Array concatenation.
1788 <ul>1885 <ul>
1789 <li>Only available when {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are {#link|compile-time known|comptime#}.1886 <li>Only available when {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are {#link|compile-time known|comptime#}.</li>
1790 </ul>1887 </ul>
1791 </td>1888 </td>
1792 <td>1889 <td>
...@@ -1798,7 +1895,7 @@ mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>...@@ -1798,7 +1895,7 @@ mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>
1798 </td>1895 </td>
1799 </tr>1896 </tr>
1800 <tr>1897 <tr>
1801 <td><pre>{#syntax#}a ** b{#endsyntax#}</pre></td>1898 <th scope="row"><pre>{#syntax#}a ** b{#endsyntax#}</pre></th>
1802 <td>1899 <td>
1803 <ul>1900 <ul>
1804 <li>{#link|Arrays#}</li>1901 <li>{#link|Arrays#}</li>
...@@ -1807,7 +1904,7 @@ mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>...@@ -1807,7 +1904,7 @@ mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>
1807 <td>1904 <td>
1808 Array multiplication.1905 Array multiplication.
1809 <ul>1906 <ul>
1810 <li>Only available when {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are {#link|compile-time known|comptime#}.1907 <li>Only available when {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are {#link|compile-time known|comptime#}.</li>
1811 </ul>1908 </ul>
1812 </td>1909 </td>
1813 <td>1910 <td>
...@@ -1817,7 +1914,7 @@ mem.eql(u8, pattern, "ababab"){#endsyntax#}</pre>...@@ -1817,7 +1914,7 @@ mem.eql(u8, pattern, "ababab"){#endsyntax#}</pre>
1817 </td>1914 </td>
1818 </tr>1915 </tr>
1819 <tr>1916 <tr>
1820 <td><pre>{#syntax#}a.*{#endsyntax#}</pre></td>1917 <th scope="row"><pre>{#syntax#}a.*{#endsyntax#}</pre></th>
1821 <td>1918 <td>
1822 <ul>1919 <ul>
1823 <li>{#link|Pointers#}</li>1920 <li>{#link|Pointers#}</li>
...@@ -1833,7 +1930,7 @@ ptr.* == 1234{#endsyntax#}</pre>...@@ -1833,7 +1930,7 @@ ptr.* == 1234{#endsyntax#}</pre>
1833 </td>1930 </td>
1834 </tr>1931 </tr>
1835 <tr>1932 <tr>
1836 <td><pre>{#syntax#}&a{#endsyntax#}</pre></td>1933 <th scope="row"><pre>{#syntax#}&a{#endsyntax#}</pre></th>
1837 <td>1934 <td>
1838 All types1935 All types
1839 </td>1936 </td>
...@@ -1847,7 +1944,7 @@ ptr.* == 1234{#endsyntax#}</pre>...@@ -1847,7 +1944,7 @@ ptr.* == 1234{#endsyntax#}</pre>
1847 </td>1944 </td>
1848 </tr>1945 </tr>
1849 <tr>1946 <tr>
1850 <td><pre>{#syntax#}a || b{#endsyntax#}</pre></td>1947 <th scope="row"><pre>{#syntax#}a || b{#endsyntax#}</pre></th>
1851 <td>1948 <td>
1852 <ul>1949 <ul>
1853 <li>{#link|Error Set Type#}</li>1950 <li>{#link|Error Set Type#}</li>
...@@ -1862,6 +1959,7 @@ const B = error{Two};...@@ -1862,6 +1959,7 @@ const B = error{Two};
1862(A || B) == error{One, Two}{#endsyntax#}</pre>1959(A || B) == error{One, Two}{#endsyntax#}</pre>
1863 </td>1960 </td>
1864 </tr>1961 </tr>
1962 </tbody>
1865 </table>1963 </table>
1866 </div>1964 </div>
1867 {#header_close#}1965 {#header_close#}
...@@ -2138,7 +2236,7 @@ test "null terminated array" {...@@ -2138,7 +2236,7 @@ test "null terminated array" {
2138 </li>2236 </li>
2139 </ul>2237 </ul>
2140 <p>Use {#syntax#}&x{#endsyntax#} to obtain a single-item pointer:</p>2238 <p>Use {#syntax#}&x{#endsyntax#} to obtain a single-item pointer:</p>
2141 {#code_begin|test#}2239 {#code_begin|test|single_item_pointer_test#}
2142const expect = @import("std").testing.expect;2240const expect = @import("std").testing.expect;
21432241
2144test "address of syntax" {2242test "address of syntax" {
...@@ -2182,7 +2280,7 @@ test "pointer array access" {...@@ -2182,7 +2280,7 @@ test "pointer array access" {
2182 against this kind of undefined behavior. This is one reason2280 against this kind of undefined behavior. This is one reason
2183 we prefer slices to pointers.2281 we prefer slices to pointers.
2184 </p>2282 </p>
2185 {#code_begin|test#}2283 {#code_begin|test|slice_bounds#}
2186const expect = @import("std").testing.expect;2284const expect = @import("std").testing.expect;
21872285
2188test "pointer slicing" {2286test "pointer slicing" {
...@@ -2197,7 +2295,7 @@ test "pointer slicing" {...@@ -2197,7 +2295,7 @@ test "pointer slicing" {
2197 {#code_end#}2295 {#code_end#}
2198 <p>Pointers work at compile-time too, as long as the code does not depend on2296 <p>Pointers work at compile-time too, as long as the code does not depend on
2199 an undefined memory layout:</p>2297 an undefined memory layout:</p>
2200 {#code_begin|test#}2298 {#code_begin|test|comptime_pointers#}
2201const expect = @import("std").testing.expect;2299const expect = @import("std").testing.expect;
22022300
2203test "comptime pointers" {2301test "comptime pointers" {
...@@ -2212,7 +2310,7 @@ test "comptime pointers" {...@@ -2212,7 +2310,7 @@ test "comptime pointers" {
2212 {#code_end#}2310 {#code_end#}
2213 <p>To convert an integer address into a pointer, use {#syntax#}@intToPtr{#endsyntax#}.2311 <p>To convert an integer address into a pointer, use {#syntax#}@intToPtr{#endsyntax#}.
2214 To convert a pointer to an integer, use {#syntax#}@ptrToInt{#endsyntax#}:</p>2312 To convert a pointer to an integer, use {#syntax#}@ptrToInt{#endsyntax#}:</p>
2215 {#code_begin|test#}2313 {#code_begin|test|integer_pointer_conversion#}
2216const expect = @import("std").testing.expect;2314const expect = @import("std").testing.expect;
22172315
2218test "@ptrToInt and @intToPtr" {2316test "@ptrToInt and @intToPtr" {
...@@ -2224,7 +2322,7 @@ test "@ptrToInt and @intToPtr" {...@@ -2224,7 +2322,7 @@ test "@ptrToInt and @intToPtr" {
2224 {#code_end#}2322 {#code_end#}
2225 <p>Zig is able to preserve memory addresses in comptime code, as long as2323 <p>Zig is able to preserve memory addresses in comptime code, as long as
2226 the pointer is never dereferenced:</p>2324 the pointer is never dereferenced:</p>
2227 {#code_begin|test#}2325 {#code_begin|test|comptime_pointer_conversion#}
2228const expect = @import("std").testing.expect;2326const expect = @import("std").testing.expect;
22292327
2230test "comptime @intToPtr" {2328test "comptime @intToPtr" {
...@@ -2244,7 +2342,7 @@ test "comptime @intToPtr" {...@@ -2244,7 +2342,7 @@ test "comptime @intToPtr" {
2244 should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}.2342 should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}.
2245 In the following code, loads and stores with {#syntax#}mmio_ptr{#endsyntax#} are guaranteed to all happen2343 In the following code, loads and stores with {#syntax#}mmio_ptr{#endsyntax#} are guaranteed to all happen
2246 and in the same order as in source code:</p>2344 and in the same order as in source code:</p>
2247 {#code_begin|test#}2345 {#code_begin|test|volatile#}
2248const expect = @import("std").testing.expect;2346const expect = @import("std").testing.expect;
22492347
2250test "volatile" {2348test "volatile" {
...@@ -2263,7 +2361,7 @@ test "volatile" {...@@ -2263,7 +2361,7 @@ test "volatile" {
2263 operation that Zig cannot protect you against. Use {#syntax#}@ptrCast{#endsyntax#} only when other2361 operation that Zig cannot protect you against. Use {#syntax#}@ptrCast{#endsyntax#} only when other
2264 conversions are not possible.2362 conversions are not possible.
2265 </p>2363 </p>
2266 {#code_begin|test#}2364 {#code_begin|test|pointer_casting#}
2267const std = @import("std");2365const std = @import("std");
2268const expect = std.testing.expect;2366const expect = std.testing.expect;
22692367
...@@ -2301,7 +2399,7 @@ test "pointer child type" {...@@ -2301,7 +2399,7 @@ test "pointer child type" {
2301 In Zig, a pointer type has an alignment value. If the value is equal to the2399 In Zig, a pointer type has an alignment value. If the value is equal to the
2302 alignment of the underlying type, it can be omitted from the type:2400 alignment of the underlying type, it can be omitted from the type:
2303 </p>2401 </p>
2304 {#code_begin|test#}2402 {#code_begin|test|variable_alignment#}
2305const std = @import("std");2403const std = @import("std");
2306const expect = std.testing.expect;2404const expect = std.testing.expect;
23072405
...@@ -2323,7 +2421,7 @@ test "variable alignment" {...@@ -2323,7 +2421,7 @@ test "variable alignment" {
2323 You can specify alignment on variables and functions. If you do this, then2421 You can specify alignment on variables and functions. If you do this, then
2324 pointers to them get the specified alignment:2422 pointers to them get the specified alignment:
2325 </p>2423 </p>
2326 {#code_begin|test#}2424 {#code_begin|test|variable_func_alignment#}
2327const expect = @import("std").testing.expect;2425const expect = @import("std").testing.expect;
23282426
2329var foo: u8 align(4) = 100;2427var foo: u8 align(4) = 100;
...@@ -2660,7 +2758,7 @@ test "linked list" {...@@ -2660,7 +2758,7 @@ test "linked list" {
2660 Each struct field may have an expression indicating the default field value. Such expressions2758 Each struct field may have an expression indicating the default field value. Such expressions
2661 are executed at {#link|comptime#}, and allow the field to be omitted in a struct literal expression:2759 are executed at {#link|comptime#}, and allow the field to be omitted in a struct literal expression:
2662 </p>2760 </p>
2663 {#code_begin|test#}2761 {#code_begin|test|default_field_values#}
2664const Foo = struct {2762const Foo = struct {
2665 a: i32 = 1234,2763 a: i32 = 1234,
2666 b: i32,2764 b: i32,
...@@ -2709,7 +2807,7 @@ test "default struct initialization fields" {...@@ -2709,7 +2807,7 @@ test "default struct initialization fields" {
2709 in a {#link|@bitCast#} or a {#link|@ptrCast#} to reinterpret memory.2807 in a {#link|@bitCast#} or a {#link|@ptrCast#} to reinterpret memory.
2710 This even works at {#link|comptime#}:2808 This even works at {#link|comptime#}:
2711 </p>2809 </p>
2712 {#code_begin|test#}2810 {#code_begin|test|packed_structs#}
2713const std = @import("std");2811const std = @import("std");
2714const native_endian = @import("builtin").target.cpu.arch.endian();2812const native_endian = @import("builtin").target.cpu.arch.endian();
2715const expect = std.testing.expect;2813const expect = std.testing.expect;
...@@ -2750,7 +2848,7 @@ fn doTheTest() !void {...@@ -2750,7 +2848,7 @@ fn doTheTest() !void {
2750 <p>2848 <p>
2751 Zig allows the address to be taken of a non-byte-aligned field:2849 Zig allows the address to be taken of a non-byte-aligned field:
2752 </p>2850 </p>
2753 {#code_begin|test#}2851 {#code_begin|test|pointer_to_non-byte_aligned_field#}
2754const std = @import("std");2852const std = @import("std");
2755const expect = std.testing.expect;2853const expect = std.testing.expect;
27562854
...@@ -2806,7 +2904,7 @@ fn bar(x: *const u3) u3 {...@@ -2806,7 +2904,7 @@ fn bar(x: *const u3) u3 {
2806 <p>2904 <p>
2807 Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer:2905 Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer:
2808 </p>2906 </p>
2809 {#code_begin|test#}2907 {#code_begin|test|pointer_to_non-bit_aligned_field#}
2810const std = @import("std");2908const std = @import("std");
2811const expect = std.testing.expect;2909const expect = std.testing.expect;
28122910
...@@ -2830,7 +2928,7 @@ test "pointer to non-bit-aligned field" {...@@ -2830,7 +2928,7 @@ test "pointer to non-bit-aligned field" {
2830 <p>2928 <p>
2831 This can be observed with {#link|@bitOffsetOf#} and {#link|offsetOf#}:2929 This can be observed with {#link|@bitOffsetOf#} and {#link|offsetOf#}:
2832 </p>2930 </p>
2833 {#code_begin|test#}2931 {#code_begin|test|test_bitOffsetOf_offsetOf#}
2834const std = @import("std");2932const std = @import("std");
2835const expect = std.testing.expect;2933const expect = std.testing.expect;
28362934
...@@ -2875,7 +2973,7 @@ test "overaligned pointer to packed struct" {...@@ -2875,7 +2973,7 @@ test "overaligned pointer to packed struct" {
2875 <p>2973 <p>
2876 It's also possible to set alignment of struct fields:2974 It's also possible to set alignment of struct fields:
2877 </p>2975 </p>
2878 {#code_begin|test#}2976 {#code_begin|test|test_aligned_struct_fields#}
2879const std = @import("std");2977const std = @import("std");
2880const expectEqual = std.testing.expectEqual;2978const expectEqual = std.testing.expectEqual;
28812979
...@@ -3129,7 +3227,7 @@ export fn entry(foo: Foo) void { _ = foo; }...@@ -3129,7 +3227,7 @@ export fn entry(foo: Foo) void { _ = foo; }
3129 <p>3227 <p>
3130 Enum literals allow specifying the name of an enum field without specifying the enum type:3228 Enum literals allow specifying the name of an enum field without specifying the enum type:
3131 </p>3229 </p>
3132 {#code_begin|test#}3230 {#code_begin|test|test_enum_literals#}
3133const std = @import("std");3231const std = @import("std");
3134const expect = std.testing.expect;3232const expect = std.testing.expect;
31353233
...@@ -3171,7 +3269,7 @@ test "switch using enum literals" {...@@ -3171,7 +3269,7 @@ test "switch using enum literals" {
3171 A switch on a non-exhaustive enum can include a '_' prong as an alternative to an {#syntax#}else{#endsyntax#} prong3269 A switch on a non-exhaustive enum can include a '_' prong as an alternative to an {#syntax#}else{#endsyntax#} prong
3172 with the difference being that it makes it a compile error if all the known tag names are not handled by the switch.3270 with the difference being that it makes it a compile error if all the known tag names are not handled by the switch.
3173 </p>3271 </p>
3174 {#code_begin|test#}3272 {#code_begin|test|test_switch_non-exhaustive#}
3175const std = @import("std");3273const std = @import("std");
3176const expect = std.testing.expect;3274const expect = std.testing.expect;
31773275
...@@ -3224,7 +3322,7 @@ test "simple union" {...@@ -3224,7 +3322,7 @@ test "simple union" {
3224}3322}
3225 {#code_end#}3323 {#code_end#}
3226 <p>You can activate another field by assigning the entire union:</p>3324 <p>You can activate another field by assigning the entire union:</p>
3227 {#code_begin|test#}3325 {#code_begin|test|test_simple_union#}
3228const std = @import("std");3326const std = @import("std");
3229const expect = std.testing.expect;3327const expect = std.testing.expect;
32303328
...@@ -3253,7 +3351,7 @@ test "simple union" {...@@ -3253,7 +3351,7 @@ test "simple union" {
3253 to use with {#link|switch#} expressions.3351 to use with {#link|switch#} expressions.
3254 Tagged unions coerce to their tag type: {#link|Type Coercion: unions and enums#}.3352 Tagged unions coerce to their tag type: {#link|Type Coercion: unions and enums#}.
3255 </p>3353 </p>
3256 {#code_begin|test#}3354 {#code_begin|test|test_switch_tagged_union#}
3257const std = @import("std");3355const std = @import("std");
3258const expect = std.testing.expect;3356const expect = std.testing.expect;
32593357
...@@ -3291,7 +3389,7 @@ test "coerce to enum" {...@@ -3291,7 +3389,7 @@ test "coerce to enum" {
3291 <p>In order to modify the payload of a tagged union in a switch expression,3389 <p>In order to modify the payload of a tagged union in a switch expression,
3292 place a {#syntax#}*{#endsyntax#} before the variable name to make it a pointer:3390 place a {#syntax#}*{#endsyntax#} before the variable name to make it a pointer:
3293 </p>3391 </p>
3294 {#code_begin|test#}3392 {#code_begin|test|test_switch_modify_tagged_union#}
3295const std = @import("std");3393const std = @import("std");
3296const expect = std.testing.expect;3394const expect = std.testing.expect;
32973395
...@@ -3320,7 +3418,7 @@ test "modify tagged union in switch" {...@@ -3320,7 +3418,7 @@ test "modify tagged union in switch" {
3320 Unions can be made to infer the enum tag type.3418 Unions can be made to infer the enum tag type.
3321 Further, unions can have methods just like structs and enums.3419 Further, unions can have methods just like structs and enums.
3322 </p>3420 </p>
3323 {#code_begin|test#}3421 {#code_begin|test|test_union_method#}
3324const std = @import("std");3422const std = @import("std");
3325const expect = std.testing.expect;3423const expect = std.testing.expect;
33263424
...@@ -3352,7 +3450,7 @@ test "union method" {...@@ -3352,7 +3450,7 @@ test "union method" {
3352 {#link|@tagName#} can be used to return a {#link|comptime#}3450 {#link|@tagName#} can be used to return a {#link|comptime#}
3353 {#syntax#}[:0]const u8{#endsyntax#} value representing the field name:3451 {#syntax#}[:0]const u8{#endsyntax#} value representing the field name:
3354 </p>3452 </p>
3355 {#code_begin|test#}3453 {#code_begin|test|test_tagName#}
3356const std = @import("std");3454const std = @import("std");
3357const expect = std.testing.expect;3455const expect = std.testing.expect;
33583456
...@@ -3377,7 +3475,7 @@ test "@tagName" {...@@ -3377,7 +3475,7 @@ test "@tagName" {
33773475
3378 {#header_open|packed union#}3476 {#header_open|packed union#}
3379 <p>A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible3477 <p>A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible
3380 to be in a {#link|packed struct#}.3478 to be in a {#link|packed struct#}.</p>
3381 {#header_close#}3479 {#header_close#}
33823480
3383 {#header_open|Anonymous Union Literals#}3481 {#header_open|Anonymous Union Literals#}
...@@ -3448,7 +3546,7 @@ test "access variable after block scope" {...@@ -3448,7 +3546,7 @@ test "access variable after block scope" {
3448 <p>Blocks are expressions. When labeled, {#syntax#}break{#endsyntax#} can be used3546 <p>Blocks are expressions. When labeled, {#syntax#}break{#endsyntax#} can be used
3449 to return a value from the block:3547 to return a value from the block:
3450 </p>3548 </p>
3451 {#code_begin|test#}3549 {#code_begin|test|test_labeled_break#}
3452const std = @import("std");3550const std = @import("std");
3453const expect = std.testing.expect;3551const expect = std.testing.expect;
34543552
...@@ -3482,7 +3580,7 @@ test "inside test block" {...@@ -3482,7 +3580,7 @@ test "inside test block" {
3482 Because of this, when you read Zig code you can rely on an identifier always meaning the same thing,3580 Because of this, when you read Zig code you can rely on an identifier always meaning the same thing,
3483 within the scope it is defined. Note that you can, however use the same name if the scopes are separate:3581 within the scope it is defined. Note that you can, however use the same name if the scopes are separate:
3484 </p>3582 </p>
3485 {#code_begin|test#}3583 {#code_begin|test|test_scopes#}
3486test "separate scopes" {3584test "separate scopes" {
3487 {3585 {
3488 const pi = 3.14;3586 const pi = 3.14;
...@@ -3569,7 +3667,7 @@ test "switch inside function" {...@@ -3569,7 +3667,7 @@ test "switch inside function" {
3569 done by placing a {#syntax#}*{#endsyntax#} before the capture variable name,3667 done by placing a {#syntax#}*{#endsyntax#} before the capture variable name,
3570 turning it into a pointer.3668 turning it into a pointer.
3571 </p>3669 </p>
3572 {#code_begin|test#}3670 {#code_begin|test|test_switch_tagged_union#}
3573const expect = @import("std").testing.expect;3671const expect = @import("std").testing.expect;
35743672
3575test "switch on tagged union" {3673test "switch on tagged union" {
...@@ -3636,7 +3734,7 @@ test "exhaustive switching" {...@@ -3636,7 +3734,7 @@ test "exhaustive switching" {
3636 {#link|Enum Literals#} can be useful to use with {#syntax#}switch{#endsyntax#} to avoid3734 {#link|Enum Literals#} can be useful to use with {#syntax#}switch{#endsyntax#} to avoid
3637 repetitively specifying {#link|enum#} or {#link|union#} types:3735 repetitively specifying {#link|enum#} or {#link|union#} types:
3638 </p>3736 </p>
3639 {#code_begin|test#}3737 {#code_begin|test|test_exhaustive_switch#}
3640const std = @import("std");3738const std = @import("std");
3641const expect = std.testing.expect;3739const expect = std.testing.expect;
36423740
...@@ -3761,7 +3859,7 @@ fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {...@@ -3761,7 +3859,7 @@ fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {
3761 {#header_open|Labeled while#}3859 {#header_open|Labeled while#}
3762 <p>When a {#syntax#}while{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}3860 <p>When a {#syntax#}while{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}
3763 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>3861 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>
3764 {#code_begin|test#}3862 {#code_begin|test|test_nested_break#}
3765test "nested break" {3863test "nested break" {
3766 outer: while (true) {3864 outer: while (true) {
3767 while (true) {3865 while (true) {
...@@ -3866,7 +3964,7 @@ fn eventuallyErrorSequence() anyerror!u32 {...@@ -3866,7 +3964,7 @@ fn eventuallyErrorSequence() anyerror!u32 {
3866 allows the code to do some things which only work at compile time,3964 allows the code to do some things which only work at compile time,
3867 such as use types as first class values.3965 such as use types as first class values.
3868 </p>3966 </p>
3869 {#code_begin|test#}3967 {#code_begin|test|test_inline_while#}
3870const expect = @import("std").testing.expect;3968const expect = @import("std").testing.expect;
38713969
3872test "inline while loop" {3970test "inline while loop" {
...@@ -3969,7 +4067,7 @@ test "for else" {...@@ -3969,7 +4067,7 @@ test "for else" {
3969 {#header_open|Labeled for#}4067 {#header_open|Labeled for#}
3970 <p>When a {#syntax#}for{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}4068 <p>When a {#syntax#}for{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}
3971 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>4069 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>
3972 {#code_begin|test#}4070 {#code_begin|test|test_nested_break#}
3973const std = @import("std");4071const std = @import("std");
3974const expect = std.testing.expect;4072const expect = std.testing.expect;
39754073
...@@ -4005,7 +4103,7 @@ test "nested continue" {...@@ -4005,7 +4103,7 @@ test "nested continue" {
4005 The capture value and iterator value of inlined for loops are4103 The capture value and iterator value of inlined for loops are
4006 compile-time known.4104 compile-time known.
4007 </p>4105 </p>
4008 {#code_begin|test#}4106 {#code_begin|test|test_inline_loop#}
4009const expect = @import("std").testing.expect;4107const expect = @import("std").testing.expect;
40104108
4011test "inline for loop" {4109test "inline for loop" {
...@@ -4278,16 +4376,16 @@ test "errdefer unwinding" {...@@ -4278,16 +4376,16 @@ test "errdefer unwinding" {
4278 {#header_close#}4376 {#header_close#}
4279 {#header_open|unreachable#}4377 {#header_open|unreachable#}
4280 <p>4378 <p>
4281 In {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, and when using <code>zig test</code>,4379 In {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, and when using <kbd>zig test</kbd>,
4282 {#syntax#}unreachable{#endsyntax#} emits a call to {#syntax#}panic{#endsyntax#} with the message <code>reached unreachable code</code>.4380 {#syntax#}unreachable{#endsyntax#} emits a call to {#syntax#}panic{#endsyntax#} with the message <code>reached unreachable code</code>.
4283 </p>4381 </p>
4284 <p>4382 <p>
4285 In {#syntax#}ReleaseFast{#endsyntax#} mode, the optimizer uses the assumption that {#syntax#}unreachable{#endsyntax#} code4383 In {#syntax#}ReleaseFast{#endsyntax#} mode, the optimizer uses the assumption that {#syntax#}unreachable{#endsyntax#} code
4286 will never be hit to perform optimizations. However, <code>zig test</code> even in {#syntax#}ReleaseFast{#endsyntax#} mode4384 will never be hit to perform optimizations. However, <kbd>zig test</kbd> even in {#syntax#}ReleaseFast{#endsyntax#} mode
4287 still emits {#syntax#}unreachable{#endsyntax#} as calls to {#syntax#}panic{#endsyntax#}.4385 still emits {#syntax#}unreachable{#endsyntax#} as calls to {#syntax#}panic{#endsyntax#}.
4288 </p>4386 </p>
4289 {#header_open|Basics#}4387 {#header_open|Basics#}
4290 {#code_begin|test#}4388 {#code_begin|test|test_unreachable#}
4291// unreachable is used to assert that control flow will never happen upon a4389// unreachable is used to assert that control flow will never happen upon a
4292// particular location:4390// particular location:
4293test "basic math" {4391test "basic math" {
...@@ -4343,7 +4441,7 @@ test "type of unreachable" {...@@ -4343,7 +4441,7 @@ test "type of unreachable" {
4343 <p>When resolving types together, such as {#syntax#}if{#endsyntax#} clauses or {#syntax#}switch{#endsyntax#} prongs,4441 <p>When resolving types together, such as {#syntax#}if{#endsyntax#} clauses or {#syntax#}switch{#endsyntax#} prongs,
4344 the {#syntax#}noreturn{#endsyntax#} type is compatible with every other type. Consider:4442 the {#syntax#}noreturn{#endsyntax#} type is compatible with every other type. Consider:
4345 </p>4443 </p>
4346 {#code_begin|test#}4444 {#code_begin|test|test_noreturn#}
4347fn foo(condition: bool, b: u32) void {4445fn foo(condition: bool, b: u32) void {
4348 const a = if (condition) b else return;4446 const a = if (condition) b else return;
4349 _ = a;4447 _ = a;
...@@ -4354,7 +4452,7 @@ test "noreturn" {...@@ -4354,7 +4452,7 @@ test "noreturn" {
4354}4452}
4355 {#code_end#}4453 {#code_end#}
4356 <p>Another use case for {#syntax#}noreturn{#endsyntax#} is the {#syntax#}exit{#endsyntax#} function:</p>4454 <p>Another use case for {#syntax#}noreturn{#endsyntax#} is the {#syntax#}exit{#endsyntax#} function:</p>
4357 {#code_begin|test#}4455 {#code_begin|test|noreturn_from_exit#}
4358 {#target_windows#}4456 {#target_windows#}
4359pub extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(if (@import("builtin").target.cpu.arch == .i386) .Stdcall else .C) noreturn;4457pub extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(if (@import("builtin").target.cpu.arch == .i386) .Stdcall else .C) noreturn;
43604458
...@@ -4451,7 +4549,7 @@ fn foo() void { }...@@ -4451,7 +4549,7 @@ fn foo() void { }
4451 as parameters, Zig may choose to copy and pass by value, or pass by reference, whichever way4549 as parameters, Zig may choose to copy and pass by value, or pass by reference, whichever way
4452 Zig decides will be faster. This is made possible, in part, by the fact that parameters are immutable.4550 Zig decides will be faster. This is made possible, in part, by the fact that parameters are immutable.
4453 </p>4551 </p>
4454 {#code_begin|test#}4552 {#code_begin|test|pass_by_reference_or_value#}
4455const Point = struct {4553const Point = struct {
4456 x: i32,4554 x: i32,
4457 y: i32,4555 y: i32,
...@@ -4481,7 +4579,7 @@ test "pass struct to function" {...@@ -4481,7 +4579,7 @@ test "pass struct to function" {
4481 In this case the parameter types will be inferred when the function is called.4579 In this case the parameter types will be inferred when the function is called.
4482 Use {#link|@TypeOf#} and {#link|@typeInfo#} to get information about the inferred type.4580 Use {#link|@TypeOf#} and {#link|@typeInfo#} to get information about the inferred type.
4483 </p>4581 </p>
4484 {#code_begin|test#}4582 {#code_begin|test|test_fn_type_inference#}
4485const expect = @import("std").testing.expect;4583const expect = @import("std").testing.expect;
44864584
4487fn addFortyTwo(x: anytype) @TypeOf(x) {4585fn addFortyTwo(x: anytype) @TypeOf(x) {
...@@ -4499,7 +4597,7 @@ test "fn type inference" {...@@ -4499,7 +4597,7 @@ test "fn type inference" {
44994597
4500 {#header_close#}4598 {#header_close#}
4501 {#header_open|Function Reflection#}4599 {#header_open|Function Reflection#}
4502 {#code_begin|test#}4600 {#code_begin|test|test_fn_reflection#}
4503const expect = @import("std").testing.expect;4601const expect = @import("std").testing.expect;
45044602
4505test "fn reflection" {4603test "fn reflection" {
...@@ -4524,7 +4622,7 @@ test "fn reflection" {...@@ -4524,7 +4622,7 @@ test "fn reflection" {
4524 <p>4622 <p>
4525 You can {#link|coerce|Type Coercion#} an error from a subset to a superset:4623 You can {#link|coerce|Type Coercion#} an error from a subset to a superset:
4526 </p>4624 </p>
4527 {#code_begin|test#}4625 {#code_begin|test|coercing_subset_to_superset#}
4528const std = @import("std");4626const std = @import("std");
45294627
4530const FileOpenError = error {4628const FileOpenError = error {
...@@ -4608,7 +4706,7 @@ const err = (error {FileNotFound}).FileNotFound;...@@ -4608,7 +4706,7 @@ const err = (error {FileNotFound}).FileNotFound;
4608 <p>4706 <p>
4609 Here is a function to parse a string into a 64-bit integer:4707 Here is a function to parse a string into a 64-bit integer:
4610 </p>4708 </p>
4611 {#code_begin|test#}4709 {#code_begin|test|error_union_parsing_u64#}
4612const std = @import("std");4710const std = @import("std");
4613const maxInt = std.math.maxInt;4711const maxInt = std.math.maxInt;
46144712
...@@ -4791,7 +4889,7 @@ fn createFoo(param: i32) !Foo {...@@ -4791,7 +4889,7 @@ fn createFoo(param: i32) !Foo {
47914889
4792 <p>An error union is created with the {#syntax#}!{#endsyntax#} binary operator.4890 <p>An error union is created with the {#syntax#}!{#endsyntax#} binary operator.
4793 You can use compile-time reflection to access the child type of an error union:</p>4891 You can use compile-time reflection to access the child type of an error union:</p>
4794 {#code_begin|test#}4892 {#code_begin|test|test_error_union#}
4795const expect = @import("std").testing.expect;4893const expect = @import("std").testing.expect;
47964894
4797test "error union" {4895test "error union" {
...@@ -4823,7 +4921,7 @@ test "error union" {...@@ -4823,7 +4921,7 @@ test "error union" {
4823 {#syntax#}LinuxFileOpenError || WindowsFileOpenError{#endsyntax#} for the error set of opening4921 {#syntax#}LinuxFileOpenError || WindowsFileOpenError{#endsyntax#} for the error set of opening
4824 files.4922 files.
4825 </p>4923 </p>
4826 {#code_begin|test#}4924 {#code_begin|test|test_merging_error_sets#}
4827const A = error{4925const A = error{
4828 NotDir,4926 NotDir,
48294927
...@@ -4859,7 +4957,7 @@ test "merge error sets" {...@@ -4859,7 +4957,7 @@ test "merge error sets" {
4859 Because many functions in Zig return a possible error, Zig supports inferring the error set.4957 Because many functions in Zig return a possible error, Zig supports inferring the error set.
4860 To infer the error set for a function, use this syntax:4958 To infer the error set for a function, use this syntax:
4861 </p>4959 </p>
4862{#code_begin|test#}4960{#code_begin|test|inferred_error_sets#}
4863// With an inferred error set4961// With an inferred error set
4864pub fn add_inferred(comptime T: type, a: T, b: T) !T {4962pub fn add_inferred(comptime T: type, a: T, b: T) !T {
4865 var answer: T = undefined;4963 var answer: T = undefined;
...@@ -5173,7 +5271,7 @@ fn doAThing(optional_foo: ?*Foo) void {...@@ -5173,7 +5271,7 @@ fn doAThing(optional_foo: ?*Foo) void {
5173 {#header_open|Optional Type#}5271 {#header_open|Optional Type#}
5174 <p>An optional is created by putting {#syntax#}?{#endsyntax#} in front of a type. You can use compile-time5272 <p>An optional is created by putting {#syntax#}?{#endsyntax#} in front of a type. You can use compile-time
5175 reflection to access the child type of an optional:</p>5273 reflection to access the child type of an optional:</p>
5176 {#code_begin|test#}5274 {#code_begin|test|test_optional_type#}
5177const expect = @import("std").testing.expect;5275const expect = @import("std").testing.expect;
51785276
5179test "optional type" {5277test "optional type" {
...@@ -5200,7 +5298,7 @@ const optional_value: ?i32 = null;...@@ -5200,7 +5298,7 @@ const optional_value: ?i32 = null;
5200 {#header_open|Optional Pointers#}5298 {#header_open|Optional Pointers#}
5201 <p>An optional pointer is guaranteed to be the same size as a pointer. The {#syntax#}null{#endsyntax#} of5299 <p>An optional pointer is guaranteed to be the same size as a pointer. The {#syntax#}null{#endsyntax#} of
5202 the optional is guaranteed to be address 0.</p>5300 the optional is guaranteed to be address 0.</p>
5203 {#code_begin|test#}5301 {#code_begin|test|test_optional_pointer#}
5204const expect = @import("std").testing.expect;5302const expect = @import("std").testing.expect;
52055303
5206test "optional pointers" {5304test "optional pointers" {
...@@ -5232,7 +5330,7 @@ test "optional pointers" {...@@ -5232,7 +5330,7 @@ test "optional pointers" {
5232 <p>5330 <p>
5233 Type coercion occurs when one type is expected, but different type is provided:5331 Type coercion occurs when one type is expected, but different type is provided:
5234 </p>5332 </p>
5235 {#code_begin|test#}5333 {#code_begin|test|type_coercion#}
5236test "type coercion - variable declaration" {5334test "type coercion - variable declaration" {
5237 var a: u8 = 1;5335 var a: u8 = 1;
5238 var b: u16 = a;5336 var b: u16 = a;
...@@ -5272,7 +5370,7 @@ test "type coercion - @as builtin" {...@@ -5272,7 +5370,7 @@ test "type coercion - @as builtin" {
5272 <p>5370 <p>
5273 These casts are no-ops at runtime since the value representation does not change.5371 These casts are no-ops at runtime since the value representation does not change.
5274 </p>5372 </p>
5275 {#code_begin|test#}5373 {#code_begin|test|no_op_casts#}
5276test "type coercion - const qualification" {5374test "type coercion - const qualification" {
5277 var a: i32 = 1;5375 var a: i32 = 1;
5278 var b: *i32 = &a;5376 var b: *i32 = &a;
...@@ -5284,7 +5382,7 @@ fn foo(_: *const i32) void {}...@@ -5284,7 +5382,7 @@ fn foo(_: *const i32) void {}
5284 <p>5382 <p>
5285 In addition, pointers coerce to const optional pointers:5383 In addition, pointers coerce to const optional pointers:
5286 </p>5384 </p>
5287 {#code_begin|test#}5385 {#code_begin|test|pointer_coerce_const_optional#}
5288const std = @import("std");5386const std = @import("std");
5289const expect = std.testing.expect;5387const expect = std.testing.expect;
5290const mem = std.mem;5388const mem = std.mem;
...@@ -5301,7 +5399,7 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" {...@@ -5301,7 +5399,7 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
5301 {#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise5399 {#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise
5302 {#link|Floats#} coerce to float types which can represent every value of the old type.5400 {#link|Floats#} coerce to float types which can represent every value of the old type.
5303 </p>5401 </p>
5304 {#code_begin|test#}5402 {#code_begin|test|test_integer_widening#}
5305const std = @import("std");5403const std = @import("std");
5306const expect = std.testing.expect;5404const expect = std.testing.expect;
5307const mem = std.mem;5405const mem = std.mem;
...@@ -5429,7 +5527,7 @@ test "*T to *[1]T" {...@@ -5429,7 +5527,7 @@ test "*T to *[1]T" {
5429 <p>5527 <p>
5430 The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type.5528 The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type.
5431 </p>5529 </p>
5432 {#code_begin|test#}5530 {#code_begin|test|test_coerce_optionals#}
5433const std = @import("std");5531const std = @import("std");
5434const expect = std.testing.expect;5532const expect = std.testing.expect;
54355533
...@@ -5442,7 +5540,7 @@ test "coerce to optionals" {...@@ -5442,7 +5540,7 @@ test "coerce to optionals" {
5442}5540}
5443 {#code_end#}5541 {#code_end#}
5444 <p>It works nested inside the {#link|Error Union Type#}, too:</p>5542 <p>It works nested inside the {#link|Error Union Type#}, too:</p>
5445 {#code_begin|test#}5543 {#code_begin|test|test_corerce_optional_wrapped_error_union#}
5446const std = @import("std");5544const std = @import("std");
5447const expect = std.testing.expect;5545const expect = std.testing.expect;
54485546
...@@ -5459,7 +5557,7 @@ test "coerce to optionals wrapped in error union" {...@@ -5459,7 +5557,7 @@ test "coerce to optionals wrapped in error union" {
5459 <p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#}5557 <p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#}
5460 coerce to the error union type:5558 coerce to the error union type:
5461 </p>5559 </p>
5462 {#code_begin|test#}5560 {#code_begin|test|test_coerce_to_error_union#}
5463const std = @import("std");5561const std = @import("std");
5464const expect = std.testing.expect;5562const expect = std.testing.expect;
54655563
...@@ -5476,7 +5574,7 @@ test "coercion to error unions" {...@@ -5476,7 +5574,7 @@ test "coercion to error unions" {
5476 <p>When a number is {#link|comptime#}-known to be representable in the destination type,5574 <p>When a number is {#link|comptime#}-known to be representable in the destination type,
5477 it may be coerced:5575 it may be coerced:
5478 </p>5576 </p>
5479 {#code_begin|test#}5577 {#code_begin|test|test_coerce_large_to_small#}
5480const std = @import("std");5578const std = @import("std");
5481const expect = std.testing.expect;5579const expect = std.testing.expect;
54825580
...@@ -5492,7 +5590,7 @@ test "coercing large integer type to smaller one when value is comptime known to...@@ -5492,7 +5590,7 @@ test "coercing large integer type to smaller one when value is comptime known to
5492 when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as5590 when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as
5493 {#link|void#}:5591 {#link|void#}:
5494 </p>5592 </p>
5495 {#code_begin|test#}5593 {#code_begin|test|test_coerce_unions_enums#}
5496const std = @import("std");5594const std = @import("std");
5497const expect = std.testing.expect;5595const expect = std.testing.expect;
54985596
...@@ -5525,7 +5623,7 @@ test "coercion between unions and enums" {...@@ -5525,7 +5623,7 @@ test "coercion between unions and enums" {
5525 regardless of const.</p>5623 regardless of const.</p>
5526 <p>TODO document the reasoning for this</p>5624 <p>TODO document the reasoning for this</p>
5527 <p>TODO document whether vice versa should work and why</p>5625 <p>TODO document whether vice versa should work and why</p>
5528 {#code_begin|test#}5626 {#code_begin|test|coerce_zero_bit_types#}
5529test "coercion of zero bit types" {5627test "coercion of zero bit types" {
5530 var x: void = {};5628 var x: void = {};
5531 var y: *void = x;5629 var y: *void = x;
...@@ -5715,7 +5813,7 @@ export fn entry() void {...@@ -5715,7 +5813,7 @@ export fn entry() void {
5715 {#syntax#}Map(Key, Value){#endsyntax#}, one can pass {#syntax#}void{#endsyntax#} for the {#syntax#}Value{#endsyntax#}5813 {#syntax#}Map(Key, Value){#endsyntax#}, one can pass {#syntax#}void{#endsyntax#} for the {#syntax#}Value{#endsyntax#}
5716 type to make it into a {#syntax#}Set{#endsyntax#}:5814 type to make it into a {#syntax#}Set{#endsyntax#}:
5717 </p>5815 </p>
5718 {#code_begin|test#}5816 {#code_begin|test|void_in_hashmap#}
5719const std = @import("std");5817const std = @import("std");
5720const expect = std.testing.expect;5818const expect = std.testing.expect;
57215819
...@@ -5755,7 +5853,7 @@ fn foo() i32 {...@@ -5755,7 +5853,7 @@ fn foo() i32 {
5755}5853}
5756 {#code_end#}5854 {#code_end#}
5757 <p>However, if the expression has type {#syntax#}void{#endsyntax#}, there will be no error. Function return values can also be explicitly ignored by assigning them to {#syntax#}_{#endsyntax#}. </p>5855 <p>However, if the expression has type {#syntax#}void{#endsyntax#}, there will be no error. Function return values can also be explicitly ignored by assigning them to {#syntax#}_{#endsyntax#}. </p>
5758 {#code_begin|test#}5856 {#code_begin|test|void_ignored#}
5759test "void is ignored" {5857test "void is ignored" {
5760 returnsVoid();5858 returnsVoid();
5761}5859}
...@@ -5774,7 +5872,7 @@ fn foo() i32 {...@@ -5774,7 +5872,7 @@ fn foo() i32 {
57745872
5775 {#header_open|Pointers to Zero Bit Types#}5873 {#header_open|Pointers to Zero Bit Types#}
5776 <p>Pointers to zero bit types also have zero bits. They always compare equal to each other:</p>5874 <p>Pointers to zero bit types also have zero bits. They always compare equal to each other:</p>
5777 {#code_begin|test#}5875 {#code_begin|test|pointers_to_zero_bits#}
5778const std = @import("std");5876const std = @import("std");
5779const expect = std.testing.expect;5877const expect = std.testing.expect;
57805878
...@@ -5826,10 +5924,10 @@ test "using std namespace" {...@@ -5826,10 +5924,10 @@ test "using std namespace" {
5826 {#code_end#}5924 {#code_end#}
5827 <p>5925 <p>
5828 {#syntax#}usingnamespace{#endsyntax#} has an important use case when organizing the public5926 {#syntax#}usingnamespace{#endsyntax#} has an important use case when organizing the public
5829 API of a file or package. For example, one might have <code>c.zig</code> with all of the5927 API of a file or package. For example, one might have <code class="file">c.zig</code> with all of the
5830 {#link|C imports|Import from C Header File#}:5928 {#link|C imports|Import from C Header File#}:
5831 </p>5929 </p>
5832 <pre>{#syntax#}5930 {#syntax_block|zig|c.zig#}
5833pub usingnamespace @cImport({5931pub usingnamespace @cImport({
5834 @cInclude("epoxy/gl.h");5932 @cInclude("epoxy/gl.h");
5835 @cInclude("GLFW/glfw3.h");5933 @cInclude("GLFW/glfw3.h");
...@@ -5837,7 +5935,7 @@ pub usingnamespace @cImport({...@@ -5837,7 +5935,7 @@ pub usingnamespace @cImport({
5837 @cDefine("STBI_NO_STDIO", "");5935 @cDefine("STBI_NO_STDIO", "");
5838 @cInclude("stb_image.h");5936 @cInclude("stb_image.h");
5839});5937});
5840 {#endsyntax#}</pre>5938 {#end_syntax_block#}
5841 <p>5939 <p>
5842 The above example demonstrates using {#syntax#}pub{#endsyntax#} to qualify the5940 The above example demonstrates using {#syntax#}pub{#endsyntax#} to qualify the
5843 {#syntax#}usingnamespace{#endsyntax#} additionally makes the imported declarations5941 {#syntax#}usingnamespace{#endsyntax#} additionally makes the imported declarations
...@@ -5923,7 +6021,7 @@ test "try to compare bools" {...@@ -5923,7 +6021,7 @@ test "try to compare bools" {
5923 value is known at compile-time. This means that we actually could make this work for the bool type6021 value is known at compile-time. This means that we actually could make this work for the bool type
5924 if we wanted to:6022 if we wanted to:
5925 </p>6023 </p>
5926 {#code_begin|test#}6024 {#code_begin|test|comptime_max_with_bool#}
5927fn max(comptime T: type, a: T, b: T) T {6025fn max(comptime T: type, a: T, b: T) T {
5928 if (T == bool) {6026 if (T == bool) {
5929 return a or b;6027 return a or b;
...@@ -6086,7 +6184,7 @@ test "foo" {...@@ -6086,7 +6184,7 @@ test "foo" {
6086 <p>6184 <p>
6087 Let's look at an example:6185 Let's look at an example:
6088 </p>6186 </p>
6089 {#code_begin|test#}6187 {#code_begin|test|fibonacci_recursion#}
6090const expect = @import("std").testing.expect;6188const expect = @import("std").testing.expect;
60916189
6092fn fibonacci(index: u32) u32 {6190fn fibonacci(index: u32) u32 {
...@@ -6179,7 +6277,7 @@ test "fibonacci" {...@@ -6179,7 +6277,7 @@ test "fibonacci" {
6179 {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to6277 {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to
6180 initialize complex static data. For example:6278 initialize complex static data. For example:
6181 </p>6279 </p>
6182 {#code_begin|test#}6280 {#code_begin|test|N_primes#}
6183const first_25_primes = firstNPrimes(25);6281const first_25_primes = firstNPrimes(25);
6184const sum_of_first_25_primes = sum(&first_25_primes);6282const sum_of_first_25_primes = sum(&first_25_primes);
61856283
...@@ -6480,7 +6578,7 @@ pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {...@@ -6480,7 +6578,7 @@ pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
6480 <p>6578 <p>
6481 Dissecting the syntax:6579 Dissecting the syntax:
6482 </p>6580 </p>
6483 <pre>{#syntax#}// Inline assembly is an expression which returns a value.6581 {#syntax_block|zig|Assembly Syntax Explained#}// Inline assembly is an expression which returns a value.
6484// the `asm` keyword begins the expression.6582// the `asm` keyword begins the expression.
6485_ = asm6583_ = asm
6486// `volatile` is an optional modifier that tells Zig this6584// `volatile` is an optional modifier that tells Zig this
...@@ -6535,7 +6633,7 @@ volatile (...@@ -6535,7 +6633,7 @@ volatile (
6535// output. In this example we list $rcx and $r11 because it is known the6633// output. In this example we list $rcx and $r11 because it is known the
6536// kernel syscall does not preserve these registers.6634// kernel syscall does not preserve these registers.
6537 : "rcx", "r11"6635 : "rcx", "r11"
6538);{#endsyntax#}</pre>6636);{#end_syntax_block#}
6539 <p>6637 <p>
6540 For i386 and x86_64 targets, the syntax is AT&amp;T syntax, rather than the more6638 For i386 and x86_64 targets, the syntax is AT&amp;T syntax, rather than the more
6541 popular Intel syntax. This is due to technical constraints; assembly parsing is6639 popular Intel syntax. This is due to technical constraints; assembly parsing is
...@@ -6661,7 +6759,7 @@ test "global assembly" {...@@ -6661,7 +6759,7 @@ test "global assembly" {
6661 return to the callsite (in the case of the first suspension),6759 return to the callsite (in the case of the first suspension),
6662 or resumer (in the case of subsequent suspensions).6760 or resumer (in the case of subsequent suspensions).
6663 </p>6761 </p>
6664 {#code_begin|test#}6762 {#code_begin|test|suspend_no_resume#}
6665const std = @import("std");6763const std = @import("std");
6666const expect = std.testing.expect;6764const expect = std.testing.expect;
66676765
...@@ -6688,7 +6786,7 @@ fn func() void {...@@ -6688,7 +6786,7 @@ fn func() void {
6688 {#syntax#}resume{#endsyntax#} operation on a different thread.6786 {#syntax#}resume{#endsyntax#} operation on a different thread.
6689 {#link|@frame#} provides access to the async function frame pointer.6787 {#link|@frame#} provides access to the async function frame pointer.
6690 </p>6788 </p>
6691 {#code_begin|test#}6789 {#code_begin|test|async_suspend_block#}
6692const std = @import("std");6790const std = @import("std");
6693const expect = std.testing.expect;6791const expect = std.testing.expect;
66946792
...@@ -6726,7 +6824,7 @@ fn testSuspendBlock() void {...@@ -6726,7 +6824,7 @@ fn testSuspendBlock() void {
6726 However, the async function can be directly resumed from the suspend block, in which case it6824 However, the async function can be directly resumed from the suspend block, in which case it
6727 never returns to its resumer and continues executing.6825 never returns to its resumer and continues executing.
6728 </p>6826 </p>
6729 {#code_begin|test#}6827 {#code_begin|test|resume_from_suspend#}
6730const std = @import("std");6828const std = @import("std");
6731const expect = std.testing.expect;6829const expect = std.testing.expect;
67326830
...@@ -6762,7 +6860,7 @@ fn testResumeFromSuspend(my_result: *i32) void {...@@ -6762,7 +6860,7 @@ fn testResumeFromSuspend(my_result: *i32) void {
6762 execution would continue at the most recent {#syntax#}async{#endsyntax#} callsite or {#syntax#}resume{#endsyntax#} callsite,6860 execution would continue at the most recent {#syntax#}async{#endsyntax#} callsite or {#syntax#}resume{#endsyntax#} callsite,
6763 and the return value of the async function would be lost.6861 and the return value of the async function would be lost.
6764 </p>6862 </p>
6765 {#code_begin|test#}6863 {#code_begin|test|async_await#}
6766const std = @import("std");6864const std = @import("std");
6767const expect = std.testing.expect;6865const expect = std.testing.expect;
67686866
...@@ -6806,7 +6904,7 @@ fn func() void {...@@ -6806,7 +6904,7 @@ fn func() void {
6806 does not suspend; instead it copies the6904 does not suspend; instead it copies the
6807 return value directly from the target function's frame.6905 return value directly from the target function's frame.
6808 </p>6906 </p>
6809 {#code_begin|test#}6907 {#code_begin|test|async_await_sequence#}
6810const std = @import("std");6908const std = @import("std");
6811const expect = std.testing.expect;6909const expect = std.testing.expect;
68126910
...@@ -7084,7 +7182,7 @@ comptime {...@@ -7084,7 +7182,7 @@ comptime {
7084 read after {#link|await|Async and Await#} completes. Any result location provided to7182 read after {#link|await|Async and Await#} completes. Any result location provided to
7085 {#syntax#}await{#endsyntax#} will copy the result from {#syntax#}result_ptr{#endsyntax#}.7183 {#syntax#}await{#endsyntax#} will copy the result from {#syntax#}result_ptr{#endsyntax#}.
7086 </p>7184 </p>
7087 {#code_begin|test#}7185 {#code_begin|test|async_struct_field_fn_pointer#}
7088const std = @import("std");7186const std = @import("std");
7089const expect = std.testing.expect;7187const expect = std.testing.expect;
70907188
...@@ -7526,7 +7624,7 @@ test "main" {...@@ -7526,7 +7624,7 @@ test "main" {
7526 not encountered by analysis, the7624 not encountered by analysis, the
7527 program compiles successfully and the generated executable prints:7625 program compiles successfully and the generated executable prints:
7528 </p>7626 </p>
7529 {#code_begin|test#}7627 {#code_begin|test|without_compileLog#}
7530const print = @import("std").debug.print;7628const print = @import("std").debug.print;
75317629
7532const num1 = blk: {7630const num1 = blk: {
...@@ -7758,7 +7856,7 @@ export fn @"A function name that is a complete sentence."() void {}...@@ -7758,7 +7856,7 @@ export fn @"A function name that is a complete sentence."() void {}
7758 <pre>{#syntax#}@field(lhs: anytype, comptime field_name: []const u8) (field){#endsyntax#}</pre>7856 <pre>{#syntax#}@field(lhs: anytype, comptime field_name: []const u8) (field){#endsyntax#}</pre>
7759 <p>Performs field access by a compile-time string. Works on both fields and declarations.7857 <p>Performs field access by a compile-time string. Works on both fields and declarations.
7760 </p>7858 </p>
7761 {#code_begin|test#}7859 {#code_begin|test|field_decl_access_by_string#}
7762const std = @import("std");7860const std = @import("std");
77637861
7764const Point = struct {7862const Point = struct {
...@@ -7843,7 +7941,7 @@ test "decl access by string" {...@@ -7843,7 +7941,7 @@ test "decl access by string" {
7843 This type is suitable to be used as the return type of {#link|async|Async and Await#} which7941 This type is suitable to be used as the return type of {#link|async|Async and Await#} which
7844 allows one to, for example, heap-allocate an async function frame:7942 allows one to, for example, heap-allocate an async function frame:
7845 </p>7943 </p>
7846 {#code_begin|test#}7944 {#code_begin|test|heap_allocated_frame#}
7847const std = @import("std");7945const std = @import("std");
78487946
7849test "heap allocated frame" {7947test "heap allocated frame" {
...@@ -7889,7 +7987,7 @@ fn func() void {...@@ -7889,7 +7987,7 @@ fn func() void {
7889 Returns whether or not a {#link|struct#}, {#link|enum#}, or {#link|union#} has a declaration7987 Returns whether or not a {#link|struct#}, {#link|enum#}, or {#link|union#} has a declaration
7890 matching {#syntax#}name{#endsyntax#}.7988 matching {#syntax#}name{#endsyntax#}.
7891 </p>7989 </p>
7892 {#code_begin|test#}7990 {#code_begin|test|hasDecl#}
7893const std = @import("std");7991const std = @import("std");
7894const expect = std.testing.expect;7992const expect = std.testing.expect;
78957993
...@@ -8104,7 +8202,7 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>...@@ -8104,7 +8202,7 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>
8104 designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use8202 designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use
8105 something like {#syntax#}@import("std").heap.WasmPageAllocator{#endsyntax#}.8203 something like {#syntax#}@import("std").heap.WasmPageAllocator{#endsyntax#}.
8106 </p>8204 </p>
8107 {#code_begin|test#}8205 {#code_begin|test|wasmMemoryGrow#}
8108const std = @import("std");8206const std = @import("std");
8109const native_arch = @import("builtin").target.cpu.arch;8207const native_arch = @import("builtin").target.cpu.arch;
8110const expect = std.testing.expect;8208const expect = std.testing.expect;
...@@ -8291,7 +8389,7 @@ test "foo" {...@@ -8291,7 +8389,7 @@ test "foo" {
8291}8389}
8292 {#code_end#}8390 {#code_end#}
8293 <p>Now we use {#syntax#}@setEvalBranchQuota{#endsyntax#}:</p>8391 <p>Now we use {#syntax#}@setEvalBranchQuota{#endsyntax#}:</p>
8294 {#code_begin|test#}8392 {#code_begin|test|setEvalBranchQuota#}
8295test "foo" {8393test "foo" {
8296 comptime {8394 comptime {
8297 @setEvalBranchQuota(1001);8395 @setEvalBranchQuota(1001);
...@@ -8490,7 +8588,7 @@ test "@setRuntimeSafety" {...@@ -8490,7 +8588,7 @@ test "@setRuntimeSafety" {
8490 Produces a vector of length {#syntax#}len{#endsyntax#} where each element is the value8588 Produces a vector of length {#syntax#}len{#endsyntax#} where each element is the value
8491 {#syntax#}scalar{#endsyntax#}:8589 {#syntax#}scalar{#endsyntax#}:
8492 </p>8590 </p>
8493 {#code_begin|test#}8591 {#code_begin|test|vector_splat#}
8494const std = @import("std");8592const std = @import("std");
8495const expect = std.testing.expect;8593const expect = std.testing.expect;
84968594
...@@ -8524,7 +8622,7 @@ test "vector @splat" {...@@ -8524,7 +8622,7 @@ test "vector @splat" {
8524 <li>{#syntax#}.Min{#endsyntax#}, {#syntax#}.Max{#endsyntax#},8622 <li>{#syntax#}.Min{#endsyntax#}, {#syntax#}.Max{#endsyntax#},
8525 {#syntax#}.Add{#endsyntax#}, {#syntax#}.Mul{#endsyntax#} are8623 {#syntax#}.Add{#endsyntax#}, {#syntax#}.Mul{#endsyntax#} are
8526 available for {#link|floating point|Floats#} vectors,</li>8624 available for {#link|floating point|Floats#} vectors,</li>
8527 <li>Every operator is available for {#link|integer|Integers#} vectors.8625 <li>Every operator is available for {#link|integer|Integers#} vectors.</li>
8528 </ul>8626 </ul>
8529 <p>8627 <p>
8530 Note that {#syntax#}.Add{#endsyntax#} and {#syntax#}.Mul{#endsyntax#}8628 Note that {#syntax#}.Add{#endsyntax#} and {#syntax#}.Mul{#endsyntax#}
...@@ -8532,7 +8630,7 @@ test "vector @splat" {...@@ -8532,7 +8630,7 @@ test "vector @splat" {
8532 types the operation associativity is preserved, unless the float mode is8630 types the operation associativity is preserved, unless the float mode is
8533 set to {#syntax#}Optimized{#endsyntax#}.8631 set to {#syntax#}Optimized{#endsyntax#}.
8534 </p>8632 </p>
8535 {#code_begin|test#}8633 {#code_begin|test|vector_reduce#}
8536const std = @import("std");8634const std = @import("std");
8537const expect = std.testing.expect;8635const expect = std.testing.expect;
85388636
...@@ -8554,7 +8652,7 @@ test "vector @reduce" {...@@ -8554,7 +8652,7 @@ test "vector @reduce" {
8554 <p>8652 <p>
8555 Returns a {#syntax#}SourceLocation{#endsyntax#} struct representing the function's name and location in the source code. This must be called in a function.8653 Returns a {#syntax#}SourceLocation{#endsyntax#} struct representing the function's name and location in the source code. This must be called in a function.
8556 </p>8654 </p>
8557 {#code_begin|test#}8655 {#code_begin|test|source_location#}
8558const std = @import("std");8656const std = @import("std");
8559const expect = std.testing.expect;8657const expect = std.testing.expect;
85608658
...@@ -8568,7 +8666,7 @@ fn doTheTest() !void {...@@ -8568,7 +8666,7 @@ fn doTheTest() !void {
8568 try expect(src.line == 9);8666 try expect(src.line == 9);
8569 try expect(src.column == 17);8667 try expect(src.column == 17);
8570 try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest"));8668 try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest"));
8571 try expect(std.mem.endsWith(u8, src.file, "test.zig"));8669 try expect(std.mem.endsWith(u8, src.file, "source_location.zig"));
8572}8670}
8573 {#code_end#}8671 {#code_end#}
8574 {#header_close#}8672 {#header_close#}
...@@ -8749,7 +8847,7 @@ fn doTheTest() !void {...@@ -8749,7 +8847,7 @@ fn doTheTest() !void {
8749 Returns the innermost struct, enum, or union that this function call is inside.8847 Returns the innermost struct, enum, or union that this function call is inside.
8750 This can be useful for an anonymous struct that needs to refer to itself:8848 This can be useful for an anonymous struct that needs to refer to itself:
8751 </p>8849 </p>
8752 {#code_begin|test#}8850 {#code_begin|test|this_innermost#}
8753const std = @import("std");8851const std = @import("std");
8754const expect = std.testing.expect;8852const expect = std.testing.expect;
87558853
...@@ -8884,7 +8982,7 @@ test "integer truncation" {...@@ -8884,7 +8982,7 @@ test "integer truncation" {
8884 <p>8982 <p>
8885 The expressions are evaluated, however they are guaranteed to have no <em>runtime</em> side-effects:8983 The expressions are evaluated, however they are guaranteed to have no <em>runtime</em> side-effects:
8886 </p>8984 </p>
8887 {#code_begin|test#}8985 {#code_begin|test|no_runtime_side_effects#}
8888const std = @import("std");8986const std = @import("std");
8889const expect = std.testing.expect;8987const expect = std.testing.expect;
88908988
...@@ -8925,9 +9023,9 @@ fn foo(comptime T: type, ptr: *T) T {...@@ -8925,9 +9023,9 @@ fn foo(comptime T: type, ptr: *T) T {
8925 <li>{#link|ReleaseSmall#}</li>9023 <li>{#link|ReleaseSmall#}</li>
8926 </ul>9024 </ul>
8927 <p>9025 <p>
8928 To add standard build options to a <code>build.zig</code> file:9026 To add standard build options to a <code class="file">build.zig</code> file:
8929 </p>9027 </p>
8930 {#code_begin|syntax#}9028 {#code_begin|syntax|build#}
8931const Builder = @import("std").build.Builder;9029const Builder = @import("std").build.Builder;
89329030
8933pub fn build(b: *Builder) void {9031pub fn build(b: *Builder) void {
...@@ -8939,11 +9037,13 @@ pub fn build(b: *Builder) void {...@@ -8939,11 +9037,13 @@ pub fn build(b: *Builder) void {
8939 <p>9037 <p>
8940 This causes these options to be available:9038 This causes these options to be available:
8941 </p>9039 </p>
8942 <pre><code class="shell"> -Drelease-safe=[bool] optimizations on and safety on9040 <dl>
8943 -Drelease-fast=[bool] optimizations on and safety off9041 <dt><kbd>-Drelease-safe=[bool]</kbd></dt><dd>Optimizations on and safety on</dd>
8944 -Drelease-small=[bool] size optimizations on and safety off</code></pre>9042 <dt><kbd>-Drelease-fast=[bool]</kbd></dt><dd>Optimizations on and safety off</dd>
9043 <dt><kbd>-Drelease-small=[bool]</kbd></dt><dd>Size optimizations on and safety off</dd>
9044 </dl>
8945 {#header_open|Debug#}9045 {#header_open|Debug#}
8946 <pre><code class="shell">$ zig build-exe example.zig</code></pre>9046 {#shell_samp#}$ zig build-exe example.zig{#end_shell_samp#}
8947 <ul>9047 <ul>
8948 <li>Fast compilation speed</li>9048 <li>Fast compilation speed</li>
8949 <li>Safety checks enabled</li>9049 <li>Safety checks enabled</li>
...@@ -8953,7 +9053,7 @@ pub fn build(b: *Builder) void {...@@ -8953,7 +9053,7 @@ pub fn build(b: *Builder) void {
8953 </ul>9053 </ul>
8954 {#header_close#}9054 {#header_close#}
8955 {#header_open|ReleaseFast#}9055 {#header_open|ReleaseFast#}
8956 <pre><code class="shell">$ zig build-exe example.zig -O ReleaseFast</code></pre>9056 {#shell_samp#}$ zig build-exe example.zig -O ReleaseFast{#end_shell_samp#}
8957 <ul>9057 <ul>
8958 <li>Fast runtime performance</li>9058 <li>Fast runtime performance</li>
8959 <li>Safety checks disabled</li>9059 <li>Safety checks disabled</li>
...@@ -8963,7 +9063,7 @@ pub fn build(b: *Builder) void {...@@ -8963,7 +9063,7 @@ pub fn build(b: *Builder) void {
8963 </ul>9063 </ul>
8964 {#header_close#}9064 {#header_close#}
8965 {#header_open|ReleaseSafe#}9065 {#header_open|ReleaseSafe#}
8966 <pre><code class="shell">$ zig build-exe example.zig -O ReleaseSafe</code></pre>9066 {#shell_samp#}$ zig build-exe example.zig -O ReleaseSafe{#end_shell_samp#}
8967 <ul>9067 <ul>
8968 <li>Medium runtime performance</li>9068 <li>Medium runtime performance</li>
8969 <li>Safety checks enabled</li>9069 <li>Safety checks enabled</li>
...@@ -8973,7 +9073,7 @@ pub fn build(b: *Builder) void {...@@ -8973,7 +9073,7 @@ pub fn build(b: *Builder) void {
8973 </ul>9073 </ul>
8974 {#header_close#}9074 {#header_close#}
8975 {#header_open|ReleaseSmall#}9075 {#header_open|ReleaseSmall#}
8976 <pre><code class="shell">$ zig build-exe example.zig -O ReleaseSmall</code></pre>9076 {#shell_samp#}$ zig build-exe example.zig -O ReleaseSmall{#end_shell_samp#}
8977 <ul>9077 <ul>
8978 <li>Medium runtime performance</li>9078 <li>Medium runtime performance</li>
8979 <li>Safety checks disabled</li>9079 <li>Safety checks disabled</li>
...@@ -8986,7 +9086,7 @@ pub fn build(b: *Builder) void {...@@ -8986,7 +9086,7 @@ pub fn build(b: *Builder) void {
8986 {#header_close#}9086 {#header_close#}
89879087
8988 {#header_open|Single Threaded Builds#}9088 {#header_open|Single Threaded Builds#}
8989 <p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p>9089 <p>Zig has a compile option <kbd>--single-threaded</kbd> which has the following effects:</p>
8990 <ul>9090 <ul>
8991 <li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li>9091 <li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li>
8992 <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>9092 <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>
...@@ -9197,7 +9297,7 @@ pub fn main() void {...@@ -9197,7 +9297,7 @@ pub fn main() void {
9197 <li>{#syntax#}-%{#endsyntax#} (wraparound negation)</li>9297 <li>{#syntax#}-%{#endsyntax#} (wraparound negation)</li>
9198 <li>{#syntax#}*%{#endsyntax#} (wraparound multiplication)</li>9298 <li>{#syntax#}*%{#endsyntax#} (wraparound multiplication)</li>
9199 </ul>9299 </ul>
9200 {#code_begin|test#}9300 {#code_begin|test|wraparound_semantics#}
9201const std = @import("std");9301const std = @import("std");
9202const expect = std.testing.expect;9302const expect = std.testing.expect;
9203const minInt = std.math.minInt;9303const minInt = std.math.minInt;
...@@ -9935,14 +10035,14 @@ const separator = if (builtin.os.tag == builtin.Os.windows) '\\' else '/';...@@ -9935,14 +10035,14 @@ const separator = if (builtin.os.tag == builtin.Os.windows) '\\' else '/';
9935 <li>Custom tasks.</li>10035 <li>Custom tasks.</li>
9936 </ul>10036 </ul>
9937 <p>10037 <p>
9938 To use the build system, run <code class="shell">zig build --help</code>10038 To use the build system, run <kbd>zig build --help</kbd>
9939 to see a command-line usage help menu. This will include project-specific10039 to see a command-line usage help menu. This will include project-specific
9940 options that were declared in the build.zig script.10040 options that were declared in the build.zig script.
9941 </p>10041 </p>
994210042
9943 {#header_open|Building an Executable#}10043 {#header_open|Building an Executable#}
9944 <p>This <code>build.zig</code> file is automatically generated10044 <p>This <code class="file">build.zig</code> file is automatically generated
9945 by <code>zig init-exe</code>.</p>10045 by <kbd>zig init-exe</kbd>.</p>
9946 {#code_begin|syntax|build#}10046 {#code_begin|syntax|build#}
9947const Builder = @import("std").build.Builder;10047const Builder = @import("std").build.Builder;
994810048
...@@ -9975,8 +10075,8 @@ pub fn build(b: *Builder) void {...@@ -9975,8 +10075,8 @@ pub fn build(b: *Builder) void {
9975 {#header_close#}10075 {#header_close#}
997610076
9977 {#header_open|Building a Library#}10077 {#header_open|Building a Library#}
9978 <p>This <code>build.zig</code> file is automatically generated10078 <p>This <code class="file">build.zig</code> file is automatically generated
9979 by <code>zig init-lib</code>.</p>10079 by <kbd>zig init-lib</kbd>.</p>
9980 {#code_begin|syntax|build#}10080 {#code_begin|syntax|build#}
9981const Builder = @import("std").build.Builder;10081const Builder = @import("std").build.Builder;
998210082
...@@ -10035,7 +10135,7 @@ lib.addCSourceFile("src/lib.c", &[_][]const u8{...@@ -10035,7 +10135,7 @@ lib.addCSourceFile("src/lib.c", &[_][]const u8{
10035 {#header_open|Import from C Header File#}10135 {#header_open|Import from C Header File#}
10036 <p>10136 <p>
10037 The {#syntax#}@cImport{#endsyntax#} builtin function can be used10137 The {#syntax#}@cImport{#endsyntax#} builtin function can be used
10038 to directly import symbols from .h files:10138 to directly import symbols from <code class="file">.h</code> files:
10039 </p>10139 </p>
10040 {#code_begin|exe#}10140 {#code_begin|exe#}
10041 {#link_libc#}10141 {#link_libc#}
...@@ -10051,7 +10151,7 @@ pub fn main() void {...@@ -10051,7 +10151,7 @@ pub fn main() void {
10051 <p>10151 <p>
10052 The {#syntax#}@cImport{#endsyntax#} function takes an expression as a parameter.10152 The {#syntax#}@cImport{#endsyntax#} function takes an expression as a parameter.
10053 This expression is evaluated at compile-time and is used to control10153 This expression is evaluated at compile-time and is used to control
10054 preprocessor directives and include multiple .h files:10154 preprocessor directives and include multiple <code class="file">.h</code> files:
10055 </p>10155 </p>
10056 {#code_begin|syntax#}10156 {#code_begin|syntax#}
10057const builtin = @import("builtin");10157const builtin = @import("builtin");
...@@ -10072,66 +10172,65 @@ const c = @cImport({...@@ -10072,66 +10172,65 @@ const c = @cImport({
10072 {#header_close#}10172 {#header_close#}
1007310173
10074 {#header_open|C Translation CLI#}10174 {#header_open|C Translation CLI#}
10075 Zig's C translation capability is available as a CLI tool via <code class="shell">zig translate-c</code>.10175 Zig's C translation capability is available as a CLI tool via <kbd>zig translate-c</kbd>.
10076 It requires a single filename as an argument. It may also take a set of optional flags that are10176 It requires a single filename as an argument. It may also take a set of optional flags that are
10077 forwarded to clang. It writes the translated file to stdout.10177 forwarded to clang. It writes the translated file to stdout.
10078 {#header_open|Command line flags#}10178 {#header_open|Command line flags#}
10079 <ul>10179 <ul>
10080 <li>10180 <li>
10081 <code class="shell">-I</code>:10181 <kbd>-I</kbd>:
10082 Specify a search directory for include files. May be used multiple times. Equivalent to10182 Specify a search directory for include files. May be used multiple times. Equivalent to
10083 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html#cmdoption-clang-i-dir">10183 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html#cmdoption-clang-i-dir">
10084 clang's <code>-I</code> flag</a>. The current directory is <em>not</em> included by default;10184 clang's <kbd>-I</kbd> flag</a>. The current directory is <em>not</em> included by default;
10085 use <code>-I.</code> to include it.10185 use <kbd>-I.</kbd> to include it.
10086 </li>10186 </li>
10087 <li>10187 <li>
10088 <code class="shell">-D</code>: Define a preprocessor macro. Equivalent to10188 <kbd>-D</kbd>: Define a preprocessor macro. Equivalent to
10089 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html#cmdoption-clang-d-macro">10189 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html#cmdoption-clang-d-macro">
10090 clang's <code>-D</code> flag</a>.10190 clang's <kbd>-D</kbd> flag</a>.
10091 </li>10191 </li>
10092 <li>10192 <li>
10093 <code class="shell">-cflags [flags] --</code>: Pass arbitrary additional10193 <kbd>-cflags [flags] --</kbd>: Pass arbitrary additional
10094 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html">command line10194 <a href="https://releases.llvm.org/12.0.0/tools/clang/docs/ClangCommandLineReference.html">command line
10095 flags</a> to clang. Note: the list of flags must end with <code>--</code>10195 flags</a> to clang. Note: the list of flags must end with <kbd>--</kbd>
10096 </li>10196 </li>
10097 <li>10197 <li>
10098 <code class="shell">-target</code>: The {#link|target triple|Targets#} for the translated Zig code.10198 <kbd>-target</kbd>: The {#link|target triple|Targets#} for the translated Zig code.
10099 If no target is specified, the current host target will be used.10199 If no target is specified, the current host target will be used.
10100 </li>10200 </li>
10101 </ul>10201 </ul>
10102 {#header_close#}10202 {#header_close#}
10103 {#header_open|Using -target and -cflags#}10203 {#header_open|Using -target and -cflags#}
10104 <p>10204 <p>
10105 <strong>Important!</strong> When translating C code with <code class="shell">zig translate-c</code>,10205 <strong>Important!</strong> When translating C code with <kbd>zig translate-c</kbd>,
10106 you <strong>must</strong> use the same <code>-target</code> triple that you will use when compiling10206 you <strong>must</strong> use the same <kbd>-target</kbd> triple that you will use when compiling
10107 the translated code. In addition, you <strong>must</strong> ensure that the <code>-cflags</code> used,10207 the translated code. In addition, you <strong>must</strong> ensure that the <kbd>-cflags</kbd> used,
10108 if any, match the cflags used by code on the target system. Using the incorrect <code>-target</code>10208 if any, match the cflags used by code on the target system. Using the incorrect <kbd>-target</kbd>
10109 or <code>-cflags</code> could result in clang or Zig parse failures, or subtle ABI incompatibilities10209 or <kbd>-cflags</kbd> could result in clang or Zig parse failures, or subtle ABI incompatibilities
10110 when linking with C code.10210 when linking with C code.
10111 </p>10211 </p>
10112 <p class="file">varytarget.h</p>10212 {#syntax_block|c|varytarget.h#}long FOO = __LONG_MAX__;{#end_syntax_block#}
10113 <pre><code class="c">long FOO = __LONG_MAX__;</code></pre>10213 {#shell_samp#}$ zig translate-c -target <em>thumb-freestanding-gnueabihf</em> varytarget.h|grep FOO
10114 <pre><code class="shell">$ zig translate-c -target <strong>thumb-freestanding-gnueabihf</strong> varytarget.h|grep FOO10214pub export var FOO: c_long = <em>2147483647</em>;
10115pub export var FOO: c_long = <strong>2147483647</strong>;</code></pre>10215$ zig translate-c -target <em>x86_64-macos-gnu</em> varytarget.h|grep FOO
10116 <pre><code class="shell">$ zig translate-c -target <strong>x86_64-macos-gnu</strong> varytarget.h|grep FOO10216pub export var FOO: c_long = <em>9223372036854775807</em>;{#end_shell_samp#}
10117pub export var FOO: c_long = <strong>9223372036854775807</strong>;</code></pre>10217 {#syntax_block|c|varycflags.h#}enum FOO { BAR };
10118 <p class="file">varycflags.h</p>10218int do_something(enum FOO foo);
10119 <pre><code class="c">enum FOO { BAR };10219 {#end_syntax_block#}
10120int do_something(enum FOO foo);</code></pre>10220 {#shell_samp#}$ zig translate-c varycflags.h|grep -B1 do_something
10121 <pre><code class="shell">$ zig translate-c varycflags.h|grep -B1 do_something10221pub const enum_FOO = <em>c_uint</em>;
10122pub const enum_FOO = <strong>c_uint</strong>;10222pub extern fn do_something(foo: enum_FOO) c_int;
10123pub extern fn do_something(foo: enum_FOO) c_int;</code></pre>10223$ zig translate-c <em>-cflags -fshort-enums --</em> varycflags.h|grep -B1 do_something
10124 <pre><code class="shell">$ zig translate-c <strong>-cflags -fshort-enums --</strong> varycflags.h|grep -B1 do_something10224pub const enum_FOO = <em>u8</em>;
10125pub const enum_FOO = <strong>u8</strong>;10225pub extern fn do_something(foo: enum_FOO) c_int;{#end_shell_samp#}
10126pub extern fn do_something(foo: enum_FOO) c_int;</code></pre>
10127 {#header_close#}10226 {#header_close#}
10128 {#header_open|@cImport vs translate-c#}10227 {#header_open|@cImport vs translate-c#}
10129 <p>{#syntax#}@cImport{#endsyntax#} and <code class="shell">zig translate-c</code> use the same underlying10228 <p>{#syntax#}@cImport{#endsyntax#} and <kbd>zig translate-c</kbd> use the same underlying
10130 C translation functionality, so on a technical level they are equivalent. In practice,10229 C translation functionality, so on a technical level they are equivalent. In practice,
10131 {#syntax#}@cImport{#endsyntax#} is useful as a way to quickly and easily access numeric constants, typedefs,10230 {#syntax#}@cImport{#endsyntax#} is useful as a way to quickly and easily access numeric constants, typedefs,
10132 and record types without needing any extra setup. If you need to pass {#link|cflags|Using -target and -cflags#}10231 and record types without needing any extra setup. If you need to pass {#link|cflags|Using -target and -cflags#}
10133 to clang, or if you would like to edit the translated code, it is recommended to use10232 to clang, or if you would like to edit the translated code, it is recommended to use
10134 <code class="shell">zig translate-c</code> and save the results to a file. Common reasons for editing10233 <kbd>zig translate-c</kbd> and save the results to a file. Common reasons for editing
10135 the generated code include: changing {#syntax#}anytype{#endsyntax#} parameters in function-like macros to more10234 the generated code include: changing {#syntax#}anytype{#endsyntax#} parameters in function-like macros to more
10136 specific types; changing {#syntax#}[*c]T{#endsyntax#} pointers to {#syntax#}[*]T{#endsyntax#} or10235 specific types; changing {#syntax#}[*c]T{#endsyntax#} pointers to {#syntax#}[*]T{#endsyntax#} or
10137 {#syntax#}*T{#endsyntax#} pointers for improved type safety; and10236 {#syntax#}*T{#endsyntax#} pointers for improved type safety; and
...@@ -10142,14 +10241,14 @@ pub extern fn do_something(foo: enum_FOO) c_int;</code></pre>...@@ -10142,14 +10241,14 @@ pub extern fn do_something(foo: enum_FOO) c_int;</code></pre>
10142 {#header_close#}10241 {#header_close#}
10143 {#header_open|C Translation Caching#}10242 {#header_open|C Translation Caching#}
10144 <p>10243 <p>
10145 The C translation feature (whether used via <code class="shell">zig translate-c</code> or10244 The C translation feature (whether used via <kbd>zig translate-c</kbd> or
10146 {#syntax#}@cImport{#endsyntax#}) integrates with the Zig caching system. Subsequent runs with10245 {#syntax#}@cImport{#endsyntax#}) integrates with the Zig caching system. Subsequent runs with
10147 the same source file, target, and cflags will use the cache instead of repeatedly translating10246 the same source file, target, and cflags will use the cache instead of repeatedly translating
10148 the same code.10247 the same code.
10149 </p>10248 </p>
10150 <p>10249 <p>
10151 To see where the cached files are stored when compiling code that uses {#syntax#}@cImport{#endsyntax#},10250 To see where the cached files are stored when compiling code that uses {#syntax#}@cImport{#endsyntax#},
10152 use the <code class="shell">--verbose-cimport</code> flag:10251 use the <kbd>--verbose-cimport</kbd> flag:
10153 </p>10252 </p>
10154 {#code_begin|exe|verbose#}10253 {#code_begin|exe|verbose#}
10155 {#link_libc#}10254 {#link_libc#}
...@@ -10163,10 +10262,10 @@ pub fn main() void {...@@ -10163,10 +10262,10 @@ pub fn main() void {
10163}10262}
10164 {#code_end#}10263 {#code_end#}
10165 <p>10264 <p>
10166 <code class="shell">cimport.h</code> contains the file to translate (constructed from calls to10265 <code class="file">cimport.h</code> contains the file to translate (constructed from calls to
10167 {#syntax#}@cInclude{#endsyntax#}, {#syntax#}@cDefine{#endsyntax#}, and {#syntax#}@cUndef{#endsyntax#}),10266 {#syntax#}@cInclude{#endsyntax#}, {#syntax#}@cDefine{#endsyntax#}, and {#syntax#}@cUndef{#endsyntax#}),
10168 <code class="shell">cimport.h.d</code> is the list of file dependencies, and10267 <code class="file">cimport.h.d</code> is the list of file dependencies, and
10169 <code class="shell">cimport.zig</code> contains the translated output.10268 <code class="file">cimport.zig</code> contains the translated output.
10170 </p>10269 </p>
10171 {#see_also|Import from C Header File|C Translation CLI|@cInclude|@cImport#}10270 {#see_also|Import from C Header File|C Translation CLI|@cInclude|@cImport#}
10172 {#header_close#}10271 {#header_close#}
...@@ -10206,22 +10305,22 @@ pub fn main() void {...@@ -10206,22 +10305,22 @@ pub fn main() void {
10206 Zig.10305 Zig.
10207 </p>10306 </p>
10208 <p>Consider the following example:</p>10307 <p>Consider the following example:</p>
10209 <p class="file">macro.c</p>10308 {#syntax_block|c|macro.c#}#define MAKELOCAL(NAME, INIT) int NAME = INIT
10210 <pre><code class="c">#define MAKELOCAL(NAME, INIT) int NAME = INIT
10211int foo(void) {10309int foo(void) {
10212 MAKELOCAL(a, 1);10310 MAKELOCAL(a, 1);
10213 MAKELOCAL(b, 2);10311 MAKELOCAL(b, 2);
10214 return a + b;10312 return a + b;
10215}</code></pre>10313}
10216<pre><code class="shell">$ zig translate-c macro.c > macro.zig10314 {#end_syntax_block#}
10217</code></pre>10315 {#shell_samp#}$ zig translate-c macro.c > macro.zig{#end_shell_samp#}
10218 <p class="file">macro.zig</p>10316 {#code_begin|syntax|macro#}
10219 <pre>{#syntax#}pub export fn foo() c_int {10317pub export fn foo() c_int {
10220 var a: c_int = 1;10318 var a: c_int = 1;
10221 var b: c_int = 2;10319 var b: c_int = 2;
10222 return a + b;10320 return a + b;
10223}10321}
10224pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected token .Equal"); // macro.c:1:9{#endsyntax#}</pre>10322pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected token .Equal"); // macro.c:1:9
10323 {#code_end#}
10225 <p>Note that {#syntax#}foo{#endsyntax#} was translated correctly despite using a non-translateable10324 <p>Note that {#syntax#}foo{#endsyntax#} was translated correctly despite using a non-translateable
10226 macro. {#syntax#}MAKELOCAL{#endsyntax#} was demoted to {#syntax#}@compileError{#endsyntax#} since10325 macro. {#syntax#}MAKELOCAL{#endsyntax#} was demoted to {#syntax#}@compileError{#endsyntax#} since
10227 it cannot be expressed as a Zig function; this simply means that you cannot directly use10326 it cannot be expressed as a Zig function; this simply means that you cannot directly use
...@@ -10272,31 +10371,27 @@ pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected toke...@@ -10272,31 +10371,27 @@ pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected toke
10272 to call into. The {#syntax#}export{#endsyntax#} keyword in front of functions, variables, and types causes them to10371 to call into. The {#syntax#}export{#endsyntax#} keyword in front of functions, variables, and types causes them to
10273 be part of the library API:10372 be part of the library API:
10274 </p>10373 </p>
10275 <p class="file">mathtest.zig</p>10374 {#code_begin|syntax|mathtest#}
10276 {#code_begin|syntax#}
10277export fn add(a: i32, b: i32) i32 {10375export fn add(a: i32, b: i32) i32 {
10278 return a + b;10376 return a + b;
10279}10377}
10280 {#code_end#}10378 {#code_end#}
10281 <p>To make a static library:</p>10379 <p>To make a static library:</p>
10282 <pre><code class="shell">$ zig build-lib mathtest.zig10380 {#shell_samp#}$ zig build-lib mathtest.zig{#end_shell_samp#}
10283</code></pre>
10284 <p>To make a shared library:</p>10381 <p>To make a shared library:</p>
10285 <pre><code class="shell">$ zig build-lib mathtest.zig -dynamic10382 {#shell_samp#}$ zig build-lib mathtest.zig -dynamic{#end_shell_samp#}
10286</code></pre>
10287 <p>Here is an example with the {#link|Zig Build System#}:</p>10383 <p>Here is an example with the {#link|Zig Build System#}:</p>
10288 <p class="file">test.c</p>10384 {#syntax_block|c|test.c#}// This header is generated by zig from mathtest.zig
10289 <pre><code class="cpp">// This header is generated by zig from mathtest.zig
10290#include "mathtest.h"10385#include "mathtest.h"
10291#include &lt;stdio.h&gt;10386#include <stdio.h>
1029210387
10293int main(int argc, char **argv) {10388int main(int argc, char **argv) {
10294 int32_t result = add(42, 1337);10389 int32_t result = add(42, 1337);
10295 printf("%d\n", result);10390 printf("%d\n", result);
10296 return 0;10391 return 0;
10297}</code></pre>10392}
10298 <p class="file">build.zig</p>10393 {#end_syntax_block#}
10299 {#code_begin|syntax#}10394 {#code_begin|syntax|build#}
10300const Builder = @import("std").build.Builder;10395const Builder = @import("std").build.Builder;
1030110396
10302pub fn build(b: *Builder) void {10397pub fn build(b: *Builder) void {
...@@ -10315,18 +10410,15 @@ pub fn build(b: *Builder) void {...@@ -10315,18 +10410,15 @@ pub fn build(b: *Builder) void {
10315 test_step.dependOn(&run_cmd.step);10410 test_step.dependOn(&run_cmd.step);
10316}10411}
10317 {#code_end#}10412 {#code_end#}
10318 <p class="file">terminal</p>10413 {#shell_samp#}$ zig build test
10319 <pre><code class="shell">$ zig build test104141379{#end_shell_samp#}
103201379
10321</code></pre>
10322 {#see_also|export#}10415 {#see_also|export#}
10323 {#header_close#}10416 {#header_close#}
10324 {#header_open|Mixing Object Files#}10417 {#header_open|Mixing Object Files#}
10325 <p>10418 <p>
10326 You can mix Zig object files with any other object files that respect the C ABI. Example:10419 You can mix Zig object files with any other object files that respect the C ABI. Example:
10327 </p>10420 </p>
10328 <p class="file">base64.zig</p>10421 {#code_begin|syntax|base64#}
10329 {#code_begin|syntax#}
10330const base64 = @import("std").base64;10422const base64 = @import("std").base64;
1033110423
10332export fn decode_base_64(10424export fn decode_base_64(
...@@ -10343,12 +10435,11 @@ export fn decode_base_64(...@@ -10343,12 +10435,11 @@ export fn decode_base_64(
10343 return decoded_size;10435 return decoded_size;
10344}10436}
10345 {#code_end#}10437 {#code_end#}
10346 <p class="file">test.c</p>10438 {#syntax_block|c|test.c#}// This header is generated by zig from base64.zig
10347 <pre><code class="cpp">// This header is generated by zig from base64.zig
10348#include "base64.h"10439#include "base64.h"
1034910440
10350#include &lt;string.h&gt;10441#include <string.h>
10351#include &lt;stdio.h&gt;10442#include <stdio.h>
1035210443
10353int main(int argc, char **argv) {10444int main(int argc, char **argv) {
10354 const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz";10445 const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz";
...@@ -10359,9 +10450,9 @@ int main(int argc, char **argv) {...@@ -10359,9 +10450,9 @@ int main(int argc, char **argv) {
10359 puts(buf);10450 puts(buf);
1036010451
10361 return 0;10452 return 0;
10362}</code></pre>10453}
10363 <p class="file">build.zig</p>10454 {#end_syntax_block#}
10364 {#code_begin|syntax#}10455 {#code_begin|syntax|build#}
10365const Builder = @import("std").build.Builder;10456const Builder = @import("std").build.Builder;
1036610457
10367pub fn build(b: *Builder) void {10458pub fn build(b: *Builder) void {
...@@ -10374,10 +10465,9 @@ pub fn build(b: *Builder) void {...@@ -10374,10 +10465,9 @@ pub fn build(b: *Builder) void {
10374 exe.install();10465 exe.install();
10375}10466}
10376 {#code_end#}10467 {#code_end#}
10377 <p class="file">terminal</p>10468 {#shell_samp#}$ zig build
10378 <pre><code class="shell">$ zig build
10379$ ./zig-out/bin/test10469$ ./zig-out/bin/test
10380all your base are belong to us</code></pre>10470all your base are belong to us{#end_shell_samp#}
10381 {#see_also|Targets|Zig Build System#}10471 {#see_also|Targets|Zig Build System#}
10382 {#header_close#}10472 {#header_close#}
10383 {#header_close#}10473 {#header_close#}
...@@ -10395,9 +10485,7 @@ export fn add(a: i32, b: i32) void {...@@ -10395,9 +10485,7 @@ export fn add(a: i32, b: i32) void {
10395 print(a + b);10485 print(a + b);
10396}10486}
10397 {#code_end#}10487 {#code_end#}
10398 {#header_close#}10488 {#syntax_block|javascript|test.js#}const fs = require('fs');
10399 <p class="file">test.js</p>
10400 <pre><code>const fs = require('fs');
10401const source = fs.readFileSync("./math.wasm");10489const source = fs.readFileSync("./math.wasm");
10402const typedArray = new Uint8Array(source);10490const typedArray = new Uint8Array(source);
1040310491
...@@ -10407,9 +10495,10 @@ WebAssembly.instantiate(typedArray, {...@@ -10407,9 +10495,10 @@ WebAssembly.instantiate(typedArray, {
10407 }}).then(result =&gt; {10495 }}).then(result =&gt; {
10408 const add = result.instance.exports.add;10496 const add = result.instance.exports.add;
10409 add(1, 2);10497 add(1, 2);
10410});</code></pre>10498});{#end_syntax_block#}
10411 <pre><code>$ node test.js10499 {#shell_samp#}$ node test.js
10412The result is 3</code></pre>10500The result is 3{#end_shell_samp#}
10501 {#header_close#}
10413 {#header_open|WASI#}10502 {#header_open|WASI#}
10414 <p>Zig's support for WebAssembly System Interface (WASI) is under active development.10503 <p>Zig's support for WebAssembly System Interface (WASI) is under active development.
10415 Example of using the standard library and reading command line arguments:</p>10504 Example of using the standard library and reading command line arguments:</p>
...@@ -10428,10 +10517,10 @@ pub fn main() !void {...@@ -10428,10 +10517,10 @@ pub fn main() !void {
10428 }10517 }
10429}10518}
10430 {#code_end#}10519 {#code_end#}
10431 <pre><code>$ wasmtime args.wasm 123 hello10520 {#shell_samp#}$ wasmtime args.wasm 123 hello
104320: args.wasm105210: args.wasm
104331: 123105221: 123
104342: hello</code></pre>105232: hello{#end_shell_samp#}
10435 <p>A more interesting example would be extracting the list of preopens from the runtime.10524 <p>A more interesting example would be extracting the list of preopens from the runtime.
10436 This is now supported in the standard library via {#syntax#}std.fs.wasi.PreopenList{#endsyntax#}:</p>10525 This is now supported in the standard library via {#syntax#}std.fs.wasi.PreopenList{#endsyntax#}:</p>
10437 {#code_begin|exe|preopens#}10526 {#code_begin|exe|preopens#}
...@@ -10453,9 +10542,9 @@ pub fn main() !void {...@@ -10453,9 +10542,9 @@ pub fn main() !void {
10453 }10542 }
10454}10543}
10455 {#code_end#}10544 {#code_end#}
10456 <pre><code>$ wasmtime --dir=. preopens.wasm10545 {#shell_samp#}$ wasmtime --dir=. preopens.wasm
104570: Preopen{ .fd = 3, .type = PreopenType{ .Dir = '.' } }105460: Preopen{ .fd = 3, .type = PreopenType{ .Dir = '.' } }
10458</code></pre>10547 {#end_shell_samp#}
10459 {#header_close#}10548 {#header_close#}
10460 {#header_close#}10549 {#header_close#}
10461 {#header_open|Targets#}10550 {#header_open|Targets#}
...@@ -10464,7 +10553,7 @@ pub fn main() !void {...@@ -10464,7 +10553,7 @@ pub fn main() !void {
10464 what it looks like to execute <code>zig targets</code> on a Linux x86_6410553 what it looks like to execute <code>zig targets</code> on a Linux x86_64
10465 computer:10554 computer:
10466 </p>10555 </p>
10467 <pre><code class="shell">$ zig targets10556 {#shell_samp#}$ zig targets
10468Architectures:10557Architectures:
10469 arm10558 arm
10470 v8_4a10559 v8_4a
...@@ -10701,7 +10790,7 @@ Available libcs:...@@ -10701,7 +10790,7 @@ Available libcs:
10701 wasm32-wasi-musl10790 wasm32-wasi-musl
10702 x86_64-linux-gnu10791 x86_64-linux-gnu
10703 x86_64-linux-gnux3210792 x86_64-linux-gnux32
10704 x86_64-linux-musl</code></pre>10793 x86_64-linux-musl{#end_shell_samp#}
10705 <p>10794 <p>
10706 The Zig Standard Library ({#syntax#}@import("std"){#endsyntax#}) has architecture, environment, and operating system10795 The Zig Standard Library ({#syntax#}@import("std"){#endsyntax#}) has architecture, environment, and operating system
10707 abstractions, and thus takes additional work to support more platforms.10796 abstractions, and thus takes additional work to support more platforms.
...@@ -10771,9 +10860,9 @@ coding style....@@ -10771,9 +10860,9 @@ coding style.
10771 <p>10860 <p>
10772 File names fall into two categories: types and namespaces. If the file10861 File names fall into two categories: types and namespaces. If the file
10773 (implicitly a struct) has top level fields, it should be named like any10862 (implicitly a struct) has top level fields, it should be named like any
10774 other struct with fields using {#syntax#}TitleCase{#endsyntax#}. Otherwise,10863 other struct with fields using <code class="file">TitleCase</code>. Otherwise,
10775 it should use {#syntax#}snake_case{#endsyntax#}. Directory names should be10864 it should use <code class="file">snake_case</code>. Directory names should be
10776 {#syntax#}snake_case{#endsyntax#}.10865 <code class="file">snake_case</code>.
10777 </p>10866 </p>
10778 <p>10867 <p>
10779 These are general rules of thumb; if it makes sense to do something different,10868 These are general rules of thumb; if it makes sense to do something different,
...@@ -10782,7 +10871,7 @@ coding style....@@ -10782,7 +10871,7 @@ coding style.
10782 </p>10871 </p>
10783 {#header_close#}10872 {#header_close#}
10784 {#header_open|Examples#}10873 {#header_open|Examples#}
10785 <pre>{#syntax#}10874 {#syntax_block|zig|style_example.zig#}
10786const namespace_name = @import("dir_name/file_name.zig");10875const namespace_name = @import("dir_name/file_name.zig");
10787const TypeName = @import("dir_name/TypeName.zig");10876const TypeName = @import("dir_name/TypeName.zig");
10788var global_var: i32 = undefined;10877var global_var: i32 = undefined;
...@@ -10826,9 +10915,9 @@ const XmlParser = struct {...@@ -10826,9 +10915,9 @@ const XmlParser = struct {
1082610915
10827// The initials BE (Big Endian) are just another word in Zig identifier names.10916// The initials BE (Big Endian) are just another word in Zig identifier names.
10828fn readU32Be() u32 {}10917fn readU32Be() u32 {}
10829 {#endsyntax#}</pre>10918 {#end_syntax_block#}
10830 <p>10919 <p>
10831 See the Zig Standard Library for more examples.10920 See the {#link|Zig Standard Library#} for more examples.
10832 </p>10921 </p>
10833 {#header_close#}10922 {#header_close#}
10834 {#header_open|Doc Comment Guidance#}10923 {#header_open|Doc Comment Guidance#}
...@@ -10863,7 +10952,7 @@ fn readU32Be() u32 {}...@@ -10863,7 +10952,7 @@ fn readU32Be() u32 {}
10863 but use of hard tabs is discouraged. See {#link|Grammar#}.10952 but use of hard tabs is discouraged. See {#link|Grammar#}.
10864 </p>10953 </p>
10865 <p>10954 <p>
10866 Note that running <code>zig fmt</code> on a source file will implement all recommendations mentioned here.10955 Note that running <kbd>zig fmt</kbd> on a source file will implement all recommendations mentioned here.
10867 Note also that the stage1 compiler does <a href="https://github.com/ziglang/zig/wiki/FAQ#why-does-zig-force-me-to-use-spaces-instead-of-tabs">not yet support CR or HT</a> control characters.10956 Note also that the stage1 compiler does <a href="https://github.com/ziglang/zig/wiki/FAQ#why-does-zig-force-me-to-use-spaces-instead-of-tabs">not yet support CR or HT</a> control characters.
10868 </p>10957 </p>
10869 <p>10958 <p>
...@@ -10881,18 +10970,18 @@ fn readU32Be() u32 {}...@@ -10881,18 +10970,18 @@ fn readU32Be() u32 {}
10881 {#header_open|Keyword Reference#}10970 {#header_open|Keyword Reference#}
10882 <div class="table-wrapper">10971 <div class="table-wrapper">
10883 <table>10972 <table>
10973 <caption>Keywords</caption>
10974 <thead>
10884 <tr>10975 <tr>
10885 <th>10976 <th scope="col">Keyword</th>
10886 Keyword10977 <th scope="col">Description</th>
10887 </th>
10888 <th>
10889 Description
10890 </th>
10891 </tr>10978 </tr>
10979 </thead>
10980 <tbody>
10892 <tr>10981 <tr>
10893 <td>10982 <th scope="row">
10894 <pre>{#syntax#}align{#endsyntax#}</pre>10983 <pre>{#syntax#}align{#endsyntax#}</pre>
10895 </td>10984 </th>
10896 <td>10985 <td>
10897 {#syntax#}align{#endsyntax#} can be used to specify the alignment of a pointer.10986 {#syntax#}align{#endsyntax#} can be used to specify the alignment of a pointer.
10898 It can also be used after a variable or function declaration to specify the alignment of pointers to that variable or function.10987 It can also be used after a variable or function declaration to specify the alignment of pointers to that variable or function.
...@@ -10902,9 +10991,9 @@ fn readU32Be() u32 {}...@@ -10902,9 +10991,9 @@ fn readU32Be() u32 {}
10902 </td>10991 </td>
10903 </tr>10992 </tr>
10904 <tr>10993 <tr>
10905 <td>10994 <th scope="row">
10906 <pre>{#syntax#}allowzero{#endsyntax#}</pre>10995 <pre>{#syntax#}allowzero{#endsyntax#}</pre>
10907 </td>10996 </th>
10908 <td>10997 <td>
10909 The pointer attribute {#syntax#}allowzero{#endsyntax#} allows a pointer to have address zero.10998 The pointer attribute {#syntax#}allowzero{#endsyntax#} allows a pointer to have address zero.
10910 <ul>10999 <ul>
...@@ -10913,9 +11002,9 @@ fn readU32Be() u32 {}...@@ -10913,9 +11002,9 @@ fn readU32Be() u32 {}
10913 </td>11002 </td>
10914 </tr>11003 </tr>
10915 <tr>11004 <tr>
10916 <td>11005 <th scope="row">
10917 <pre>{#syntax#}and{#endsyntax#}</pre>11006 <pre>{#syntax#}and{#endsyntax#}</pre>
10918 </td>11007 </th>
10919 <td>11008 <td>
10920 The boolean operator {#syntax#}and{#endsyntax#}.11009 The boolean operator {#syntax#}and{#endsyntax#}.
10921 <ul>11010 <ul>
...@@ -10924,9 +11013,9 @@ fn readU32Be() u32 {}...@@ -10924,9 +11013,9 @@ fn readU32Be() u32 {}
10924 </td>11013 </td>
10925 </tr>11014 </tr>
10926 <tr>11015 <tr>
10927 <td>11016 <th scope="row">
10928 <pre>{#syntax#}anyframe{#endsyntax#}</pre>11017 <pre>{#syntax#}anyframe{#endsyntax#}</pre>
10929 </td>11018 </th>
10930 <td>11019 <td>
10931 {#syntax#}anyframe{#endsyntax#} can be used as a type for variables which hold pointers to function frames.11020 {#syntax#}anyframe{#endsyntax#} can be used as a type for variables which hold pointers to function frames.
10932 <ul>11021 <ul>
...@@ -10935,9 +11024,9 @@ fn readU32Be() u32 {}...@@ -10935,9 +11024,9 @@ fn readU32Be() u32 {}
10935 </td>11024 </td>
10936 </tr>11025 </tr>
10937 <tr>11026 <tr>
10938 <td>11027 <th scope="row">
10939 <pre>{#syntax#}anytype{#endsyntax#}</pre>11028 <pre>{#syntax#}anytype{#endsyntax#}</pre>
10940 </td>11029 </th>
10941 <td>11030 <td>
10942 Function parameters and struct fields can be declared with {#syntax#}anytype{#endsyntax#} in place of the type.11031 Function parameters and struct fields can be declared with {#syntax#}anytype{#endsyntax#} in place of the type.
10943 The type will be inferred where the function is called or the struct is instantiated.11032 The type will be inferred where the function is called or the struct is instantiated.
...@@ -10947,9 +11036,9 @@ fn readU32Be() u32 {}...@@ -10947,9 +11036,9 @@ fn readU32Be() u32 {}
10947 </td>11036 </td>
10948 </tr>11037 </tr>
10949 <tr>11038 <tr>
10950 <td>11039 <th scope="row">
10951 <pre>{#syntax#}asm{#endsyntax#}</pre>11040 <pre>{#syntax#}asm{#endsyntax#}</pre>
10952 </td>11041 </th>
10953 <td>11042 <td>
10954 {#syntax#}asm{#endsyntax#} begins an inline assembly expression. This allows for directly controlling the machine code generated on compilation.11043 {#syntax#}asm{#endsyntax#} begins an inline assembly expression. This allows for directly controlling the machine code generated on compilation.
10955 <ul>11044 <ul>
...@@ -10958,9 +11047,9 @@ fn readU32Be() u32 {}...@@ -10958,9 +11047,9 @@ fn readU32Be() u32 {}
10958 </td>11047 </td>
10959 </tr>11048 </tr>
10960 <tr>11049 <tr>
10961 <td>11050 <th scope="row">
10962 <pre>{#syntax#}async{#endsyntax#}</pre>11051 <pre>{#syntax#}async{#endsyntax#}</pre>
10963 </td>11052 </th>
10964 <td>11053 <td>
10965 {#syntax#}async{#endsyntax#} can be used before a function call to get a pointer to the function's frame when it suspends.11054 {#syntax#}async{#endsyntax#} can be used before a function call to get a pointer to the function's frame when it suspends.
10966 <ul>11055 <ul>
...@@ -10969,9 +11058,9 @@ fn readU32Be() u32 {}...@@ -10969,9 +11058,9 @@ fn readU32Be() u32 {}
10969 </td>11058 </td>
10970 </tr>11059 </tr>
10971 <tr>11060 <tr>
10972 <td>11061 <th scope="row">
10973 <pre>{#syntax#}await{#endsyntax#}</pre>11062 <pre>{#syntax#}await{#endsyntax#}</pre>
10974 </td>11063 </th>
10975 <td>11064 <td>
10976 {#syntax#}await{#endsyntax#} can be used to suspend the current function until the frame provided after the {#syntax#}await{#endsyntax#} completes.11065 {#syntax#}await{#endsyntax#} can be used to suspend the current function until the frame provided after the {#syntax#}await{#endsyntax#} completes.
10977 {#syntax#}await{#endsyntax#} copies the value returned from the target function's frame to the caller.11066 {#syntax#}await{#endsyntax#} copies the value returned from the target function's frame to the caller.
...@@ -10981,9 +11070,9 @@ fn readU32Be() u32 {}...@@ -10981,9 +11070,9 @@ fn readU32Be() u32 {}
10981 </td>11070 </td>
10982 </tr>11071 </tr>
10983 <tr>11072 <tr>
10984 <td>11073 <th scope="row">
10985 <pre>{#syntax#}break{#endsyntax#}</pre>11074 <pre>{#syntax#}break{#endsyntax#}</pre>
10986 </td>11075 </th>
10987 <td>11076 <td>
10988 {#syntax#}break{#endsyntax#} can be used with a block label to return a value from the block.11077 {#syntax#}break{#endsyntax#} can be used with a block label to return a value from the block.
10989 It can also be used to exit a loop before iteration completes naturally.11078 It can also be used to exit a loop before iteration completes naturally.
...@@ -10993,9 +11082,9 @@ fn readU32Be() u32 {}...@@ -10993,9 +11082,9 @@ fn readU32Be() u32 {}
10993 </td>11082 </td>
10994 </tr>11083 </tr>
10995 <tr>11084 <tr>
10996 <td>11085 <th scope="row">
10997 <pre>{#syntax#}catch{#endsyntax#}</pre>11086 <pre>{#syntax#}catch{#endsyntax#}</pre>
10998 </td>11087 </th>
10999 <td>11088 <td>
11000 {#syntax#}catch{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to an error.11089 {#syntax#}catch{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to an error.
11001 The expression after the {#syntax#}catch{#endsyntax#} can optionally capture the error value.11090 The expression after the {#syntax#}catch{#endsyntax#} can optionally capture the error value.
...@@ -11005,9 +11094,9 @@ fn readU32Be() u32 {}...@@ -11005,9 +11094,9 @@ fn readU32Be() u32 {}
11005 </td>11094 </td>
11006 </tr>11095 </tr>
11007 <tr>11096 <tr>
11008 <td>11097 <th scope="row">
11009 <pre>{#syntax#}comptime{#endsyntax#}</pre>11098 <pre>{#syntax#}comptime{#endsyntax#}</pre>
11010 </td>11099 </th>
11011 <td>11100 <td>
11012 {#syntax#}comptime{#endsyntax#} before a declaration can be used to label variables or function parameters as known at compile time.11101 {#syntax#}comptime{#endsyntax#} before a declaration can be used to label variables or function parameters as known at compile time.
11013 It can also be used to guarantee an expression is run at compile time.11102 It can also be used to guarantee an expression is run at compile time.
...@@ -11017,9 +11106,9 @@ fn readU32Be() u32 {}...@@ -11017,9 +11106,9 @@ fn readU32Be() u32 {}
11017 </td>11106 </td>
11018 </tr>11107 </tr>
11019 <tr>11108 <tr>
11020 <td>11109 <th scope="row">
11021 <pre>{#syntax#}const{#endsyntax#}</pre>11110 <pre>{#syntax#}const{#endsyntax#}</pre>
11022 </td>11111 </th>
11023 <td>11112 <td>
11024 {#syntax#}const{#endsyntax#} declares a variable that can not be modified.11113 {#syntax#}const{#endsyntax#} declares a variable that can not be modified.
11025 Used as a pointer attribute, it denotes the value referenced by the pointer cannot be modified.11114 Used as a pointer attribute, it denotes the value referenced by the pointer cannot be modified.
...@@ -11029,9 +11118,9 @@ fn readU32Be() u32 {}...@@ -11029,9 +11118,9 @@ fn readU32Be() u32 {}
11029 </td>11118 </td>
11030 </tr>11119 </tr>
11031 <tr>11120 <tr>
11032 <td>11121 <th scope="row">
11033 <pre>{#syntax#}continue{#endsyntax#}</pre>11122 <pre>{#syntax#}continue{#endsyntax#}</pre>
11034 </td>11123 </th>
11035 <td>11124 <td>
11036 {#syntax#}continue{#endsyntax#} can be used in a loop to jump back to the beginning of the loop.11125 {#syntax#}continue{#endsyntax#} can be used in a loop to jump back to the beginning of the loop.
11037 <ul>11126 <ul>
...@@ -11040,9 +11129,9 @@ fn readU32Be() u32 {}...@@ -11040,9 +11129,9 @@ fn readU32Be() u32 {}
11040 </td>11129 </td>
11041 </tr>11130 </tr>
11042 <tr>11131 <tr>
11043 <td>11132 <th scope="row">
11044 <pre>{#syntax#}defer{#endsyntax#}</pre>11133 <pre>{#syntax#}defer{#endsyntax#}</pre>
11045 </td>11134 </th>
11046 <td>11135 <td>
11047 {#syntax#}defer{#endsyntax#} will execute an expression when control flow leaves the current block.11136 {#syntax#}defer{#endsyntax#} will execute an expression when control flow leaves the current block.
11048 <ul>11137 <ul>
...@@ -11051,9 +11140,9 @@ fn readU32Be() u32 {}...@@ -11051,9 +11140,9 @@ fn readU32Be() u32 {}
11051 </td>11140 </td>
11052 </tr>11141 </tr>
11053 <tr>11142 <tr>
11054 <td>11143 <th scope="row">
11055 <pre>{#syntax#}else{#endsyntax#}</pre>11144 <pre>{#syntax#}else{#endsyntax#}</pre>
11056 </td>11145 </th>
11057 <td>11146 <td>
11058 {#syntax#}else{#endsyntax#} can be used to provide an alternate branch for {#syntax#}if{#endsyntax#}, {#syntax#}switch{#endsyntax#},11147 {#syntax#}else{#endsyntax#} can be used to provide an alternate branch for {#syntax#}if{#endsyntax#}, {#syntax#}switch{#endsyntax#},
11059 {#syntax#}while{#endsyntax#}, and {#syntax#}for{#endsyntax#} expressions.11148 {#syntax#}while{#endsyntax#}, and {#syntax#}for{#endsyntax#} expressions.
...@@ -11066,9 +11155,9 @@ fn readU32Be() u32 {}...@@ -11066,9 +11155,9 @@ fn readU32Be() u32 {}
11066 </td>11155 </td>
11067 </tr>11156 </tr>
11068 <tr>11157 <tr>
11069 <td>11158 <th scope="row">
11070 <pre>{#syntax#}enum{#endsyntax#}</pre>11159 <pre>{#syntax#}enum{#endsyntax#}</pre>
11071 </td>11160 </th>
11072 <td>11161 <td>
11073 {#syntax#}enum{#endsyntax#} defines an enum type.11162 {#syntax#}enum{#endsyntax#} defines an enum type.
11074 <ul>11163 <ul>
...@@ -11077,9 +11166,9 @@ fn readU32Be() u32 {}...@@ -11077,9 +11166,9 @@ fn readU32Be() u32 {}
11077 </td>11166 </td>
11078 </tr>11167 </tr>
11079 <tr>11168 <tr>
11080 <td>11169 <th scope="row">
11081 <pre>{#syntax#}errdefer{#endsyntax#}</pre>11170 <pre>{#syntax#}errdefer{#endsyntax#}</pre>
11082 </td>11171 </th>
11083 <td>11172 <td>
11084 {#syntax#}errdefer{#endsyntax#} will execute an expression when control flow leaves the current block if the function returns an error.11173 {#syntax#}errdefer{#endsyntax#} will execute an expression when control flow leaves the current block if the function returns an error.
11085 <ul>11174 <ul>
...@@ -11088,9 +11177,9 @@ fn readU32Be() u32 {}...@@ -11088,9 +11177,9 @@ fn readU32Be() u32 {}
11088 </td>11177 </td>
11089 </tr>11178 </tr>
11090 <tr>11179 <tr>
11091 <td>11180 <th scope="row">
11092 <pre>{#syntax#}error{#endsyntax#}</pre>11181 <pre>{#syntax#}error{#endsyntax#}</pre>
11093 </td>11182 </th>
11094 <td>11183 <td>
11095 {#syntax#}error{#endsyntax#} defines an error type.11184 {#syntax#}error{#endsyntax#} defines an error type.
11096 <ul>11185 <ul>
...@@ -11099,9 +11188,9 @@ fn readU32Be() u32 {}...@@ -11099,9 +11188,9 @@ fn readU32Be() u32 {}
11099 </td>11188 </td>
11100 </tr>11189 </tr>
11101 <tr>11190 <tr>
11102 <td>11191 <th scope="row">
11103 <pre>{#syntax#}export{#endsyntax#}</pre>11192 <pre>{#syntax#}export{#endsyntax#}</pre>
11104 </td>11193 </th>
11105 <td>11194 <td>
11106 {#syntax#}export{#endsyntax#} makes a function or variable externally visible in the generated object file.11195 {#syntax#}export{#endsyntax#} makes a function or variable externally visible in the generated object file.
11107 Exported functions default to the C calling convention.11196 Exported functions default to the C calling convention.
...@@ -11111,9 +11200,9 @@ fn readU32Be() u32 {}...@@ -11111,9 +11200,9 @@ fn readU32Be() u32 {}
11111 </td>11200 </td>
11112 </tr>11201 </tr>
11113 <tr>11202 <tr>
11114 <td>11203 <th scope="row">
11115 <pre>{#syntax#}extern{#endsyntax#}</pre>11204 <pre>{#syntax#}extern{#endsyntax#}</pre>
11116 </td>11205 </th>
11117 <td>11206 <td>
11118 {#syntax#}extern{#endsyntax#} can be used to declare a function or variable that will be resolved at link time, when linking statically11207 {#syntax#}extern{#endsyntax#} can be used to declare a function or variable that will be resolved at link time, when linking statically
11119 or at runtime, when linking dynamically.11208 or at runtime, when linking dynamically.
...@@ -11123,9 +11212,9 @@ fn readU32Be() u32 {}...@@ -11123,9 +11212,9 @@ fn readU32Be() u32 {}
11123 </td>11212 </td>
11124 </tr>11213 </tr>
11125 <tr>11214 <tr>
11126 <td>11215 <th scope="row">
11127 <pre>{#syntax#}false{#endsyntax#}</pre>11216 <pre>{#syntax#}false{#endsyntax#}</pre>
11128 </td>11217 </th>
11129 <td>11218 <td>
11130 The boolean value {#syntax#}false{#endsyntax#}.11219 The boolean value {#syntax#}false{#endsyntax#}.
11131 <ul>11220 <ul>
...@@ -11134,9 +11223,9 @@ fn readU32Be() u32 {}...@@ -11134,9 +11223,9 @@ fn readU32Be() u32 {}
11134 </td>11223 </td>
11135 </tr>11224 </tr>
11136 <tr>11225 <tr>
11137 <td>11226 <th scope="row">
11138 <pre>{#syntax#}fn{#endsyntax#}</pre>11227 <pre>{#syntax#}fn{#endsyntax#}</pre>
11139 </td>11228 </th>
11140 <td>11229 <td>
11141 {#syntax#}fn{#endsyntax#} declares a function.11230 {#syntax#}fn{#endsyntax#} declares a function.
11142 <ul>11231 <ul>
...@@ -11145,9 +11234,9 @@ fn readU32Be() u32 {}...@@ -11145,9 +11234,9 @@ fn readU32Be() u32 {}
11145 </td>11234 </td>
11146 </tr>11235 </tr>
11147 <tr>11236 <tr>
11148 <td>11237 <th scope="row">
11149 <pre>{#syntax#}for{#endsyntax#}</pre>11238 <pre>{#syntax#}for{#endsyntax#}</pre>
11150 </td>11239 </th>
11151 <td>11240 <td>
11152 A {#syntax#}for{#endsyntax#} expression can be used to iterate over the elements of a slice, array, or tuple.11241 A {#syntax#}for{#endsyntax#} expression can be used to iterate over the elements of a slice, array, or tuple.
11153 <ul>11242 <ul>
...@@ -11156,9 +11245,9 @@ fn readU32Be() u32 {}...@@ -11156,9 +11245,9 @@ fn readU32Be() u32 {}
11156 </td>11245 </td>
11157 </tr>11246 </tr>
11158 <tr>11247 <tr>
11159 <td>11248 <th scope="row">
11160 <pre>{#syntax#}if{#endsyntax#}</pre>11249 <pre>{#syntax#}if{#endsyntax#}</pre>
11161 </td>11250 </th>
11162 <td>11251 <td>
11163 An {#syntax#}if{#endsyntax#} expression can test boolean expressions, optional values, or error unions.11252 An {#syntax#}if{#endsyntax#} expression can test boolean expressions, optional values, or error unions.
11164 For optional values or error unions, the if expression can capture the unwrapped value.11253 For optional values or error unions, the if expression can capture the unwrapped value.
...@@ -11168,9 +11257,9 @@ fn readU32Be() u32 {}...@@ -11168,9 +11257,9 @@ fn readU32Be() u32 {}
11168 </td>11257 </td>
11169 </tr>11258 </tr>
11170 <tr>11259 <tr>
11171 <td>11260 <th scope="row">
11172 <pre>{#syntax#}inline{#endsyntax#}</pre>11261 <pre>{#syntax#}inline{#endsyntax#}</pre>
11173 </td>11262 </th>
11174 <td>11263 <td>
11175 {#syntax#}inline{#endsyntax#} can be used to label a loop expression such that it will be unrolled at compile time.11264 {#syntax#}inline{#endsyntax#} can be used to label a loop expression such that it will be unrolled at compile time.
11176 It can also be used to force a function to be inlined at all call sites.11265 It can also be used to force a function to be inlined at all call sites.
...@@ -11180,9 +11269,9 @@ fn readU32Be() u32 {}...@@ -11180,9 +11269,9 @@ fn readU32Be() u32 {}
11180 </td>11269 </td>
11181 </tr>11270 </tr>
11182 <tr>11271 <tr>
11183 <td>11272 <th scope="row">
11184 <pre>{#syntax#}noalias{#endsyntax#}</pre>11273 <pre>{#syntax#}noalias{#endsyntax#}</pre>
11185 </td>11274 </th>
11186 <td>11275 <td>
11187 The {#syntax#}noalias{#endsyntax#} keyword.11276 The {#syntax#}noalias{#endsyntax#} keyword.
11188 <ul>11277 <ul>
...@@ -11191,9 +11280,9 @@ fn readU32Be() u32 {}...@@ -11191,9 +11280,9 @@ fn readU32Be() u32 {}
11191 </td>11280 </td>
11192 </tr>11281 </tr>
11193 <tr>11282 <tr>
11194 <td>11283 <th scope="row">
11195 <pre>{#syntax#}nosuspend{#endsyntax#}</pre>11284 <pre>{#syntax#}nosuspend{#endsyntax#}</pre>
11196 </td>11285 </th>
11197 <td>11286 <td>
11198 The {#syntax#}nosuspend{#endsyntax#} keyword can be used in front of a block, statement or expression, to mark a scope where no suspension points are reached.11287 The {#syntax#}nosuspend{#endsyntax#} keyword can be used in front of a block, statement or expression, to mark a scope where no suspension points are reached.
11199 In particular, inside a {#syntax#}nosuspend{#endsyntax#} scope:11288 In particular, inside a {#syntax#}nosuspend{#endsyntax#} scope:
...@@ -11209,9 +11298,9 @@ fn readU32Be() u32 {}...@@ -11209,9 +11298,9 @@ fn readU32Be() u32 {}
11209 </td>11298 </td>
11210 </tr>11299 </tr>
11211 <tr>11300 <tr>
11212 <td>11301 <th scope="row">
11213 <pre>{#syntax#}null{#endsyntax#}</pre>11302 <pre>{#syntax#}null{#endsyntax#}</pre>
11214 </td>11303 </th>
11215 <td>11304 <td>
11216 The optional value {#syntax#}null{#endsyntax#}.11305 The optional value {#syntax#}null{#endsyntax#}.
11217 <ul>11306 <ul>
...@@ -11220,9 +11309,9 @@ fn readU32Be() u32 {}...@@ -11220,9 +11309,9 @@ fn readU32Be() u32 {}
11220 </td>11309 </td>
11221 </tr>11310 </tr>
11222 <tr>11311 <tr>
11223 <td>11312 <th scope="row">
11224 <pre>{#syntax#}or{#endsyntax#}</pre>11313 <pre>{#syntax#}or{#endsyntax#}</pre>
11225 </td>11314 </th>
11226 <td>11315 <td>
11227 The boolean operator {#syntax#}or{#endsyntax#}.11316 The boolean operator {#syntax#}or{#endsyntax#}.
11228 <ul>11317 <ul>
...@@ -11231,9 +11320,9 @@ fn readU32Be() u32 {}...@@ -11231,9 +11320,9 @@ fn readU32Be() u32 {}
11231 </td>11320 </td>
11232 </tr>11321 </tr>
11233 <tr>11322 <tr>
11234 <td>11323 <th scope="row">
11235 <pre>{#syntax#}orelse{#endsyntax#}</pre>11324 <pre>{#syntax#}orelse{#endsyntax#}</pre>
11236 </td>11325 </th>
11237 <td>11326 <td>
11238 {#syntax#}orelse{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to null.11327 {#syntax#}orelse{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to null.
11239 <ul>11328 <ul>
...@@ -11242,9 +11331,9 @@ fn readU32Be() u32 {}...@@ -11242,9 +11331,9 @@ fn readU32Be() u32 {}
11242 </td>11331 </td>
11243 </tr>11332 </tr>
11244 <tr>11333 <tr>
11245 <td>11334 <th scope="row">
11246 <pre>{#syntax#}packed{#endsyntax#}</pre>11335 <pre>{#syntax#}packed{#endsyntax#}</pre>
11247 </td>11336 </th>
11248 <td>11337 <td>
11249 The {#syntax#}packed{#endsyntax#} keyword before a struct definition changes the struct's in-memory layout11338 The {#syntax#}packed{#endsyntax#} keyword before a struct definition changes the struct's in-memory layout
11250 to the guaranteed {#syntax#}packed{#endsyntax#} layout.11339 to the guaranteed {#syntax#}packed{#endsyntax#} layout.
...@@ -11254,9 +11343,9 @@ fn readU32Be() u32 {}...@@ -11254,9 +11343,9 @@ fn readU32Be() u32 {}
11254 </td>11343 </td>
11255 </tr>11344 </tr>
11256 <tr>11345 <tr>
11257 <td>11346 <th scope="row">
11258 <pre>{#syntax#}pub{#endsyntax#}</pre>11347 <pre>{#syntax#}pub{#endsyntax#}</pre>
11259 </td>11348 </th>
11260 <td>11349 <td>
11261 The {#syntax#}pub{#endsyntax#} in front of a top level declaration makes the declaration available11350 The {#syntax#}pub{#endsyntax#} in front of a top level declaration makes the declaration available
11262 to reference from a different file than the one it is declared in.11351 to reference from a different file than the one it is declared in.
...@@ -11266,9 +11355,9 @@ fn readU32Be() u32 {}...@@ -11266,9 +11355,9 @@ fn readU32Be() u32 {}
11266 </td>11355 </td>
11267 </tr>11356 </tr>
11268 <tr>11357 <tr>
11269 <td>11358 <th scope="row">
11270 <pre>{#syntax#}resume{#endsyntax#}</pre>11359 <pre>{#syntax#}resume{#endsyntax#}</pre>
11271 </td>11360 </th>
11272 <td>11361 <td>
11273 {#syntax#}resume{#endsyntax#} will continue execution of a function frame after the point the function was suspended.11362 {#syntax#}resume{#endsyntax#} will continue execution of a function frame after the point the function was suspended.
11274 <ul>11363 <ul>
...@@ -11277,9 +11366,9 @@ fn readU32Be() u32 {}...@@ -11277,9 +11366,9 @@ fn readU32Be() u32 {}
11277 </td>11366 </td>
11278 </tr>11367 </tr>
11279 <tr>11368 <tr>
11280 <td>11369 <th scope="row">
11281 <pre>{#syntax#}return{#endsyntax#}</pre>11370 <pre>{#syntax#}return{#endsyntax#}</pre>
11282 </td>11371 </th>
11283 <td>11372 <td>
11284 {#syntax#}return{#endsyntax#} exits a function with a value.11373 {#syntax#}return{#endsyntax#} exits a function with a value.
11285 <ul>11374 <ul>
...@@ -11288,9 +11377,9 @@ fn readU32Be() u32 {}...@@ -11288,9 +11377,9 @@ fn readU32Be() u32 {}
11288 </td>11377 </td>
11289 </tr>11378 </tr>
11290 <tr>11379 <tr>
11291 <td>11380 <th scope="row">
11292 <pre>{#syntax#}linksection{#endsyntax#}</pre>11381 <pre>{#syntax#}linksection{#endsyntax#}</pre>
11293 </td>11382 </th>
11294 <td>11383 <td>
11295 The {#syntax#}linksection{#endsyntax#} keyword.11384 The {#syntax#}linksection{#endsyntax#} keyword.
11296 <ul>11385 <ul>
...@@ -11299,9 +11388,9 @@ fn readU32Be() u32 {}...@@ -11299,9 +11388,9 @@ fn readU32Be() u32 {}
11299 </td>11388 </td>
11300 </tr>11389 </tr>
11301 <tr>11390 <tr>
11302 <td>11391 <th scope="row">
11303 <pre>{#syntax#}struct{#endsyntax#}</pre>11392 <pre>{#syntax#}struct{#endsyntax#}</pre>
11304 </td>11393 </th>
11305 <td>11394 <td>
11306 {#syntax#}struct{#endsyntax#} defines a struct.11395 {#syntax#}struct{#endsyntax#} defines a struct.
11307 <ul>11396 <ul>
...@@ -11310,9 +11399,9 @@ fn readU32Be() u32 {}...@@ -11310,9 +11399,9 @@ fn readU32Be() u32 {}
11310 </td>11399 </td>
11311 </tr>11400 </tr>
11312 <tr>11401 <tr>
11313 <td>11402 <th scope="row">
11314 <pre>{#syntax#}suspend{#endsyntax#}</pre>11403 <pre>{#syntax#}suspend{#endsyntax#}</pre>
11315 </td>11404 </th>
11316 <td>11405 <td>
11317 {#syntax#}suspend{#endsyntax#} will cause control flow to return to the call site or resumer of the function.11406 {#syntax#}suspend{#endsyntax#} will cause control flow to return to the call site or resumer of the function.
11318 {#syntax#}suspend{#endsyntax#} can also be used before a block within a function,11407 {#syntax#}suspend{#endsyntax#} can also be used before a block within a function,
...@@ -11323,9 +11412,9 @@ fn readU32Be() u32 {}...@@ -11323,9 +11412,9 @@ fn readU32Be() u32 {}
11323 </td>11412 </td>
11324 </tr>11413 </tr>
11325 <tr>11414 <tr>
11326 <td>11415 <th scope="row">
11327 <pre>{#syntax#}switch{#endsyntax#}</pre>11416 <pre>{#syntax#}switch{#endsyntax#}</pre>
11328 </td>11417 </th>
11329 <td>11418 <td>
11330 A {#syntax#}switch{#endsyntax#} expression can be used to test values of a common type.11419 A {#syntax#}switch{#endsyntax#} expression can be used to test values of a common type.
11331 {#syntax#}switch{#endsyntax#} cases can capture field values of a {#link|Tagged union#}.11420 {#syntax#}switch{#endsyntax#} cases can capture field values of a {#link|Tagged union#}.
...@@ -11335,9 +11424,9 @@ fn readU32Be() u32 {}...@@ -11335,9 +11424,9 @@ fn readU32Be() u32 {}
11335 </td>11424 </td>
11336 </tr>11425 </tr>
11337 <tr>11426 <tr>
11338 <td>11427 <th scope="row">
11339 <pre>{#syntax#}test{#endsyntax#}</pre>11428 <pre>{#syntax#}test{#endsyntax#}</pre>
11340 </td>11429 </th>
11341 <td>11430 <td>
11342 The {#syntax#}test{#endsyntax#} keyword can be used to denote a top-level block of code11431 The {#syntax#}test{#endsyntax#} keyword can be used to denote a top-level block of code
11343 used to make sure behavior meets expectations.11432 used to make sure behavior meets expectations.
...@@ -11347,9 +11436,9 @@ fn readU32Be() u32 {}...@@ -11347,9 +11436,9 @@ fn readU32Be() u32 {}
11347 </td>11436 </td>
11348 </tr>11437 </tr>
11349 <tr>11438 <tr>
11350 <td>11439 <th scope="row">
11351 <pre>{#syntax#}threadlocal{#endsyntax#}</pre>11440 <pre>{#syntax#}threadlocal{#endsyntax#}</pre>
11352 </td>11441 </th>
11353 <td>11442 <td>
11354 {#syntax#}threadlocal{#endsyntax#} can be used to specify a variable as thread-local.11443 {#syntax#}threadlocal{#endsyntax#} can be used to specify a variable as thread-local.
11355 <ul>11444 <ul>
...@@ -11358,9 +11447,9 @@ fn readU32Be() u32 {}...@@ -11358,9 +11447,9 @@ fn readU32Be() u32 {}
11358 </td>11447 </td>
11359 </tr>11448 </tr>
11360 <tr>11449 <tr>
11361 <td>11450 <th scope="row">
11362 <pre>{#syntax#}true{#endsyntax#}</pre>11451 <pre>{#syntax#}true{#endsyntax#}</pre>
11363 </td>11452 </th>
11364 <td>11453 <td>
11365 The boolean value {#syntax#}true{#endsyntax#}.11454 The boolean value {#syntax#}true{#endsyntax#}.
11366 <ul>11455 <ul>
...@@ -11369,9 +11458,9 @@ fn readU32Be() u32 {}...@@ -11369,9 +11458,9 @@ fn readU32Be() u32 {}
11369 </td>11458 </td>
11370 </tr>11459 </tr>
11371 <tr>11460 <tr>
11372 <td>11461 <th scope="row">
11373 <pre>{#syntax#}try{#endsyntax#}</pre>11462 <pre>{#syntax#}try{#endsyntax#}</pre>
11374 </td>11463 </th>
11375 <td>11464 <td>
11376 {#syntax#}try{#endsyntax#} evaluates an error union expression.11465 {#syntax#}try{#endsyntax#} evaluates an error union expression.
11377 If it is an error, it returns from the current function with the same error.11466 If it is an error, it returns from the current function with the same error.
...@@ -11382,9 +11471,9 @@ fn readU32Be() u32 {}...@@ -11382,9 +11471,9 @@ fn readU32Be() u32 {}
11382 </td>11471 </td>
11383 </tr>11472 </tr>
11384 <tr>11473 <tr>
11385 <td>11474 <th scope="row">
11386 <pre>{#syntax#}undefined{#endsyntax#}</pre>11475 <pre>{#syntax#}undefined{#endsyntax#}</pre>
11387 </td>11476 </th>
11388 <td>11477 <td>
11389 {#syntax#}undefined{#endsyntax#} can be used to leave a value uninitialized.11478 {#syntax#}undefined{#endsyntax#} can be used to leave a value uninitialized.
11390 <ul>11479 <ul>
...@@ -11393,9 +11482,9 @@ fn readU32Be() u32 {}...@@ -11393,9 +11482,9 @@ fn readU32Be() u32 {}
11393 </td>11482 </td>
11394 </tr>11483 </tr>
11395 <tr>11484 <tr>
11396 <td>11485 <th scope="row">
11397 <pre>{#syntax#}union{#endsyntax#}</pre>11486 <pre>{#syntax#}union{#endsyntax#}</pre>
11398 </td>11487 </th>
11399 <td>11488 <td>
11400 {#syntax#}union{#endsyntax#} defines a union.11489 {#syntax#}union{#endsyntax#} defines a union.
11401 <ul>11490 <ul>
...@@ -11404,23 +11493,23 @@ fn readU32Be() u32 {}...@@ -11404,23 +11493,23 @@ fn readU32Be() u32 {}
11404 </td>11493 </td>
11405 </tr>11494 </tr>
11406 <tr>11495 <tr>
11407 <td>11496 <th scope="row">
11408 <pre>{#syntax#}unreachable{#endsyntax#}</pre>11497 <pre>{#syntax#}unreachable{#endsyntax#}</pre>
11409 </td>11498 </th>
11410 <td>11499 <td>
11411 {#syntax#}unreachable{#endsyntax#} can be used to assert that control flow will never happen upon a particular location.11500 {#syntax#}unreachable{#endsyntax#} can be used to assert that control flow will never happen upon a particular location.
11412 Depending on the build mode, {#syntax#}unreachable{#endsyntax#} may emit a panic.11501 Depending on the build mode, {#syntax#}unreachable{#endsyntax#} may emit a panic.
11413 <ul>11502 <ul>
11414 <li>Emits a panic in {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, or when using <code>zig test</code>.</li>11503 <li>Emits a panic in {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, or when using <kbd>zig test</kbd>.</li>
11415 <li>Does not emit a panic in {#syntax#}ReleaseFast{#endsyntax#} mode, unless <code>zig test</code> is being used.</li>11504 <li>Does not emit a panic in {#syntax#}ReleaseFast{#endsyntax#} mode, unless <kbd>zig test</kbd> is being used.</li>
11416 <li>See also {#link|unreachable#}</li>11505 <li>See also {#link|unreachable#}</li>
11417 </ul>11506 </ul>
11418 </td>11507 </td>
11419 </tr>11508 </tr>
11420 <tr>11509 <tr>
11421 <td>11510 <th scope="row">
11422 <pre>{#syntax#}usingnamespace{#endsyntax#}</pre>11511 <pre>{#syntax#}usingnamespace{#endsyntax#}</pre>
11423 </td>11512 </th>
11424 <td>11513 <td>
11425 {#syntax#}usingnamespace{#endsyntax#} is a top-level declaration that imports all the public declarations of the operand,11514 {#syntax#}usingnamespace{#endsyntax#} is a top-level declaration that imports all the public declarations of the operand,
11426 which must be a struct, union, or enum, into the current scope.11515 which must be a struct, union, or enum, into the current scope.
...@@ -11430,9 +11519,9 @@ fn readU32Be() u32 {}...@@ -11430,9 +11519,9 @@ fn readU32Be() u32 {}
11430 </td>11519 </td>
11431 </tr>11520 </tr>
11432 <tr>11521 <tr>
11433 <td>11522 <th scope="row">
11434 <pre>{#syntax#}var{#endsyntax#}</pre>11523 <pre>{#syntax#}var{#endsyntax#}</pre>
11435 </td>11524 </th>
11436 <td>11525 <td>
11437 {#syntax#}var{#endsyntax#} declares a variable that may be modified.11526 {#syntax#}var{#endsyntax#} declares a variable that may be modified.
11438 <ul>11527 <ul>
...@@ -11441,9 +11530,9 @@ fn readU32Be() u32 {}...@@ -11441,9 +11530,9 @@ fn readU32Be() u32 {}
11441 </td>11530 </td>
11442 </tr>11531 </tr>
11443 <tr>11532 <tr>
11444 <td>11533 <th scope="row">
11445 <pre>{#syntax#}volatile{#endsyntax#}</pre>11534 <pre>{#syntax#}volatile{#endsyntax#}</pre>
11446 </td>11535 </th>
11447 <td>11536 <td>
11448 {#syntax#}volatile{#endsyntax#} can be used to denote loads or stores of a pointer have side effects.11537 {#syntax#}volatile{#endsyntax#} can be used to denote loads or stores of a pointer have side effects.
11449 It can also modify an inline assembly expression to denote it has side effects.11538 It can also modify an inline assembly expression to denote it has side effects.
...@@ -11453,9 +11542,9 @@ fn readU32Be() u32 {}...@@ -11453,9 +11542,9 @@ fn readU32Be() u32 {}
11453 </td>11542 </td>
11454 </tr>11543 </tr>
11455 <tr>11544 <tr>
11456 <td>11545 <th scope="row">
11457 <pre>{#syntax#}while{#endsyntax#}</pre>11546 <pre>{#syntax#}while{#endsyntax#}</pre>
11458 </td>11547 </th>
11459 <td>11548 <td>
11460 A {#syntax#}while{#endsyntax#} expression can be used to repeatedly test a boolean, optional, or error union expression,11549 A {#syntax#}while{#endsyntax#} expression can be used to repeatedly test a boolean, optional, or error union expression,
11461 and cease looping when that expression evaluates to false, null, or an error, respectively.11550 and cease looping when that expression evaluates to false, null, or an error, respectively.
...@@ -11464,6 +11553,7 @@ fn readU32Be() u32 {}...@@ -11464,6 +11553,7 @@ fn readU32Be() u32 {}
11464 </ul>11553 </ul>
11465 </td>11554 </td>
11466 </tr>11555 </tr>
11556 </tbody>
11467 </table>11557 </table>
11468 </div>11558 </div>
11469 {#header_close#}11559 {#header_close#}
...@@ -12034,7 +12124,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_allowzero / KEYWORD_and / KEYWORD_anyframe...@@ -12034,7 +12124,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_allowzero / KEYWORD_and / KEYWORD_anyframe
12034 <li>Together we serve the users.</li>12124 <li>Together we serve the users.</li>
12035 </ul>12125 </ul>
12036 {#header_close#}12126 {#header_close#}
12037 </div></div>12127 </main></div>
12038 </div>12128 </div>
12039 </body>12129 </body>
12040</html>12130</html>