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 {
280280 id: Id,
281281 name: []const u8,
282282 source_token: Token,
283 is_inline: bool,
283 just_check_syntax: bool,
284284 mode: std.builtin.Mode,
285285 link_objects: []const []const u8,
286286 target_str: ?[]const u8,
......@@ -305,6 +305,18 @@ const Link = struct {
305305 token: Token,
306306};
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
308320const Node = union(enum) {
309321 Content: []const u8,
310322 Nav,
......@@ -313,7 +325,9 @@ const Node = union(enum) {
313325 SeeAlso: []const SeeAlsoItem,
314326 Code: Code,
315327 Link: Link,
316 Syntax: Token,
328 InlineSyntax: Token,
329 Shell: Token,
330 SyntaxBlock: SyntaxBlock,
317331};
318332
319333const Toc = struct {
......@@ -403,7 +417,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
403417 .HeaderOpen = HeaderOpen{
404418 .name = content,
405419 .url = urlized,
406 .n = header_stack_size,
420 .n = header_stack_size + 1, // highest-level section headers start at h2
407421 },
408422 });
409423 if (try urls.fetchPut(urlized, tag_token)) |kv| {
......@@ -502,7 +516,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
502516 }
503517 const code_kind_str = tokenizer.buffer[code_kind_tok.start..code_kind_tok.end];
504518 var code_kind_id: Code.Id = undefined;
505 var is_inline = false;
519 var just_check_syntax = false;
506520 if (mem.eql(u8, code_kind_str, "exe")) {
507521 code_kind_id = Code.Id{ .Exe = ExpectedOutcome.Succeed };
508522 } else if (mem.eql(u8, code_kind_str, "exe_err")) {
......@@ -526,7 +540,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
526540 code_kind_id = Code.Id.Lib;
527541 } else if (mem.eql(u8, code_kind_str, "syntax")) {
528542 code_kind_id = Code.Id{ .Obj = null };
529 is_inline = true;
543 just_check_syntax = true;
530544 } else {
531545 return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {s}", .{code_kind_str});
532546 }
......@@ -589,7 +603,7 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
589603 .id = code_kind_id,
590604 .name = name,
591605 .source_token = source_token,
592 .is_inline = is_inline,
606 .just_check_syntax = just_check_syntax,
593607 .mode = mode,
594608 .link_objects = link_objects.toOwnedSlice(),
595609 .target_str = target_str,
......@@ -615,7 +629,67 @@ fn genToc(allocator: *Allocator, tokenizer: *Tokenizer) !Toc {
615629 );
616630 }
617631 _ = 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 } });
619693 } else {
620694 return parseError(tokenizer, tag_token, "unrecognized tag name: {s}", .{tag_name});
621695 }
......@@ -693,7 +767,7 @@ test "term color" {
693767 const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";
694768 const result = try termColor(std.testing.allocator, input_bytes);
695769 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);
697771}
698772
699773fn termColor(allocator: *Allocator, input: []const u8) ![]u8 {
......@@ -799,7 +873,7 @@ fn tokenizeAndPrintRaw(
799873) !void {
800874 const src_non_terminated = mem.trim(u8, raw_src, " \n");
801875 const src = try allocator.dupeZ(u8, src_non_terminated);
802 try out.writeAll("<code class=\"zig\">");
876 try out.writeAll("<code>");
803877 var tokenizer = std.zig.Tokenizer.init(src);
804878 var index: usize = 0;
805879 var next_tok_is_fn = false;
......@@ -1033,6 +1107,47 @@ fn tokenizeAndPrint(
10331107 return tokenizeAndPrintRaw(allocator, docgen_tokenizer, out, source_token, raw_src);
10341108}
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
10361151fn genHtml(
10371152 allocator: *Allocator,
10381153 tokenizer: *Tokenizer,
......@@ -1066,9 +1181,9 @@ fn genHtml(
10661181 try out.writeAll(toc.toc);
10671182 },
10681183 .Builtin => |tok| {
1069 try out.writeAll("<pre>");
1184 try out.writeAll("<figure><figcaption class=\"zig-cap\"><cite>@import(\"builtin\")</cite></figcaption><pre>");
10701185 try tokenizeAndPrintRaw(allocator, tokenizer, out, tok, builtin_code);
1071 try out.writeAll("</pre>");
1186 try out.writeAll("</pre></figure>");
10721187 },
10731188 .HeaderOpen => |info| {
10741189 try out.print(
......@@ -1087,30 +1202,44 @@ fn genHtml(
10871202 }
10881203 try out.writeAll("</ul>\n");
10891204 },
1090 .Syntax => |content_tok| {
1205 .InlineSyntax => |content_tok| {
10911206 try tokenizeAndPrint(allocator, tokenizer, out, content_tok);
10921207 },
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 },
10931215 .Code => |code| {
1094 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];
1095 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
1096 if (!code.is_inline) {
1097 try out.print("<p class=\"file\">{s}.zig</p>", .{code.name});
1098 }
1099 try out.writeAll("<pre>");
1100 try tokenizeAndPrint(allocator, tokenizer, out, code.source_token);
1101 try out.writeAll("</pre>");
1216 const name_plus_ext = try std.fmt.allocPrint(allocator, "{s}.zig", .{code.name});
1217 const syntax_block = SyntaxBlock{
1218 .source_type = .zig,
1219 .name = name_plus_ext,
1220 .source_token = code.source_token,
1221 };
1222
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) {
11041228 continue;
11051229 }
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");
11081233 const tmp_source_file_name = try fs.path.join(
11091234 allocator,
11101235 &[_][]const u8{ tmp_dir_name, name_plus_ext },
11111236 );
11121237 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
11141243 switch (code.id) {
11151244 Code.Id.Exe => |expected_outcome| code_block: {
11161245 var build_args = std.ArrayList([]const u8).init(allocator);
......@@ -1121,12 +1250,14 @@ fn genHtml(
11211250 "--color", "on",
11221251 "--enable-cache", tmp_source_file_name,
11231252 });
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
11251256 switch (code.mode) {
11261257 .Debug => {},
11271258 else => {
11281259 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)});
11301261 },
11311262 }
11321263 for (code.link_objects) |link_object| {
......@@ -1136,25 +1267,26 @@ fn genHtml(
11361267 &[_][]const u8{ tmp_dir_name, name_with_ext },
11371268 );
11381269 try build_args.append(full_path_object);
1139 try out.print(" {s}", .{name_with_ext});
1270 try shell_out.print("{s} ", .{name_with_ext});
11401271 }
11411272 if (code.link_libc) {
11421273 try build_args.append("-lc");
1143 try out.print(" -lc", .{});
1274 try shell_out.print("-lc ", .{});
11441275 }
11451276 const target = try std.zig.CrossTarget.parse(.{
11461277 .arch_os_abi = code.target_str orelse "native",
11471278 });
11481279 if (code.target_str) |triple| {
11491280 try build_args.appendSlice(&[_][]const u8{ "-target", triple });
1150 if (!code.is_inline) {
1151 try out.print(" -target {s}", .{triple});
1152 }
1281 try shell_out.print("-target {s} ", .{triple});
11531282 }
11541283 if (code.verbose_cimport) {
11551284 try build_args.append("--verbose-cimport");
1156 try out.print(" --verbose-cimport", .{});
1285 try shell_out.print("--verbose-cimport ", .{});
11571286 }
1287
1288 try shell_out.print("\n", .{});
1289
11581290 if (expected_outcome == .BuildFail) {
11591291 const result = try ChildProcess.exec(.{
11601292 .allocator = allocator,
......@@ -1180,12 +1312,17 @@ fn genHtml(
11801312 }
11811313 const escaped_stderr = try escapeHtml(allocator, result.stderr);
11821314 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);
11841316 break :code_block;
11851317 }
11861318 const exec_result = exec(allocator, &env_map, build_args.items) catch
11871319 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
11891326 if (code.target_str) |triple| {
11901327 if (mem.startsWith(u8, triple, "wasm32") or
11911328 mem.startsWith(u8, triple, "riscv64-linux") or
......@@ -1193,7 +1330,6 @@ fn genHtml(
11931330 std.Target.current.os.tag != .linux or std.Target.current.cpu.arch != .x86_64))
11941331 {
11951332 // skip execution
1196 try out.print("</code></pre>\n", .{});
11971333 break :code_block;
11981334 }
11991335 }
......@@ -1241,41 +1377,38 @@ fn genHtml(
12411377 const colored_stderr = try termColor(allocator, escaped_stderr);
12421378 const colored_stdout = try termColor(allocator, escaped_stdout);
12431379
1244 if (code.verbose_cimport) {
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 });
1380 try shell_out.print("\n$ ./{s}\n{s}{s}", .{ code.name, colored_stdout, colored_stderr });
12491381 if (exited_with_signal) {
1250 try out.print("(process terminated by signal)", .{});
1382 try shell_out.print("(process terminated by signal)", .{});
12511383 }
1252 try out.print("</code></pre>\n", .{});
1384 try shell_out.writeAll("\n");
12531385 },
12541386 Code.Id.Test => {
12551387 var test_args = std.ArrayList([]const u8).init(allocator);
12561388 defer test_args.deinit();
12571389
12581390 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
12601393 switch (code.mode) {
12611394 .Debug => {},
12621395 else => {
12631396 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)});
12651398 },
12661399 }
12671400 if (code.link_libc) {
12681401 try test_args.append("-lc");
1269 try out.print(" -lc", .{});
1402 try shell_out.print("-lc ", .{});
12701403 }
12711404 if (code.target_str) |triple| {
12721405 try test_args.appendSlice(&[_][]const u8{ "-target", triple });
1273 try out.print(" -target {s}", .{triple});
1406 try shell_out.print("-target {s} ", .{triple});
12741407 }
12751408 const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});
12761409 const escaped_stderr = try escapeHtml(allocator, result.stderr);
12771410 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 });
12791412 },
12801413 Code.Id.TestError => |error_match| {
12811414 var test_args = std.ArrayList([]const u8).init(allocator);
......@@ -1288,12 +1421,13 @@ fn genHtml(
12881421 "on",
12891422 tmp_source_file_name,
12901423 });
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
12921426 switch (code.mode) {
12931427 .Debug => {},
12941428 else => {
12951429 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)});
12971431 },
12981432 }
12991433 const result = try ChildProcess.exec(.{
......@@ -1325,7 +1459,7 @@ fn genHtml(
13251459 }
13261460 const escaped_stderr = try escapeHtml(allocator, result.stderr);
13271461 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});
13291463 },
13301464
13311465 Code.Id.TestSafety => |error_match| {
......@@ -1383,7 +1517,7 @@ fn genHtml(
13831517 }
13841518 const escaped_stderr = try escapeHtml(allocator, result.stderr);
13851519 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", .{
13871521 code.name,
13881522 mode_arg,
13891523 colored_stderr,
......@@ -1406,23 +1540,20 @@ fn genHtml(
14061540 tmp_dir_name, fs.path.sep, name_plus_obj_ext,
14071541 }),
14081542 });
1409 if (!code.is_inline) {
1410 try out.print("<pre><code class=\"shell\">$ zig build-obj {s}.zig", .{code.name});
1411 }
1543
1544 try shell_out.print("$ zig build-obj {s}.zig ", .{code.name});
14121545
14131546 switch (code.mode) {
14141547 .Debug => {},
14151548 else => {
14161549 try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
1417 if (!code.is_inline) {
1418 try out.print(" -O {s}", .{@tagName(code.mode)});
1419 }
1550 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
14201551 },
14211552 }
14221553
14231554 if (code.target_str) |triple| {
14241555 try build_args.appendSlice(&[_][]const u8{ "-target", triple });
1425 try out.print(" -target {s}", .{triple});
1556 try shell_out.print("-target {s} ", .{triple});
14261557 }
14271558
14281559 if (maybe_error_match) |error_match| {
......@@ -1455,13 +1586,11 @@ fn genHtml(
14551586 }
14561587 const escaped_stderr = try escapeHtml(allocator, result.stderr);
14571588 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});
14591590 } else {
14601591 _ = exec(allocator, &env_map, build_args.items) catch return parseError(tokenizer, code.source_token, "example failed to compile", .{});
14611592 }
1462 if (!code.is_inline) {
1463 try out.print("</code></pre>\n", .{});
1464 }
1593 try shell_out.writeAll("\n");
14651594 },
14661595 Code.Id.Lib => {
14671596 const bin_basename = try std.zig.binNameAlloc(allocator, .{
......@@ -1481,36 +1610,41 @@ fn genHtml(
14811610 tmp_dir_name, fs.path.sep_str, bin_basename,
14821611 }),
14831612 });
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
14851615 switch (code.mode) {
14861616 .Debug => {},
14871617 else => {
14881618 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)});
14901620 },
14911621 }
14921622 if (code.target_str) |triple| {
14931623 try test_args.appendSlice(&[_][]const u8{ "-target", triple });
1494 try out.print(" -target {s}", .{triple});
1624 try shell_out.print("-target {s} ", .{triple});
14951625 }
14961626 if (code.link_mode) |link_mode| {
14971627 switch (link_mode) {
14981628 .Static => {
14991629 try test_args.append("-static");
1500 try out.print(" -static", .{});
1630 try shell_out.print("-static ", .{});
15011631 },
15021632 .Dynamic => {
15031633 try test_args.append("-dynamic");
1504 try out.print(" -dynamic", .{});
1634 try shell_out.print("-dynamic ", .{});
15051635 },
15061636 }
15071637 }
15081638 const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});
15091639 const escaped_stderr = try escapeHtml(allocator, result.stderr);
15101640 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 });
15121642 },
15131643 }
1644
1645 if (!code.just_check_syntax) {
1646 try printShell(out, shell_buffer.items);
1647 }
15141648 },
15151649 }
15161650 }
......@@ -1551,3 +1685,195 @@ fn dumpArgs(args: []const []const u8) void {
15511685 else
15521686 print("\n", .{});
15531687}
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 @@
66 <title>Documentation - The Zig Programming Language</title>
77 <link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg=="/>
88 <style>
9 :root{
10 --nav-width: 24em;
11 --nav-margin-l: 1em;
12 }
913 body{
1014 font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
1115 margin: 0;
16 line-height: 1.5;
1217 }
13 a:not(:hover) {
14 text-decoration: none;
18 header {
19 padding: 0 1em;
1520 }
16 table, th, td {
17 border-collapse: collapse;
18 border: 1px solid grey;
21 #contents {
22 max-width: 60em;
23 margin: auto;
24 padding: 0 1em;
1925 }
20 th, td {
21 padding: 0.1em;
26 #navigation {
27 padding: 0 1em;
2228 }
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;
24126 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;
25212 }
26213 .t2_0 {
27 color: grey;
214 color: grey;
28215 }
29216 .t31_1 {
30 color: red;
217 color: red;
31218 }
32219 .t32_1 {
33 color: green;
220 color: #00B800;
34221 }
35222 .t36_1 {
36 color: #0086b3;
223 color: #0086b3;
37224 }
38 .file {
39 text-decoration: underline;
225 code {
226 background: #222;
227 border-color: #444;
40228 }
41229 pre > code {
42 display: block;
43 overflow: auto;
44 padding: 0.5em;
45 color: #333;
46 background: #f8f8f8;
47 border: 1px dotted silver;
48 line-height: normal;
230 color: #ccc;
231 background: #222;
232 border: unset;
49233 }
50 code {
51 background-color: #f8f8f8;
52 border: 1px dotted silver;
53 padding-left: 0.3em;
54 padding-right: 0.3em;
234 samp {
235 background: #000;
236 color: #ccc;
55237 }
56 .table-wrapper {
57 width: 100%;
58 overflow-y: auto;
238 pre > samp {
239 border: unset;
59240 }
60
61241 .tok-kw {
62 color: #333;
63 font-weight: bold;
242 color: #eee;
64243 }
65244 .tok-str {
66 color: #d14;
245 color: #2e5;
67246 }
68247 .tok-builtin {
69 color: #0086b3;
248 color: #ff894c;
70249 }
71250 .tok-comment {
72 color: #777;
73 font-style: italic;
251 color: #aa7;
74252 }
75253 .tok-fn {
76 color: #900;
77 font-weight: bold;
254 color: #B1A0F8;
78255 }
79256 .tok-null {
80 color: #008080;
257 color: #ff8080;
81258 }
82259 .tok-number {
83 color: #008080;
260 color: #ff8080;
84261 }
85262 .tok-type {
86 color: #458;
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;
263 color: #68f;
98264 }
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
124265 h1 a, h2 a, h3 a, h4 a, h5 a {
125 text-decoration: none;
126 color: #333;
266 color: #aaa;
127267 }
128
129 a.hdr {
130 visibility: hidden;
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;
268 figcaption.zig-cap {
269 background-color: #b27306;
270 color: #000;
134271 }
135
136 @media (prefers-color-scheme: dark) {
137 body{
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 }
272 figcaption.shell-cap {
273 background: #2a2a2a;
274 color: #fff;
195275 }
196 </style>
197 </head>
198 <body>
199 <div id="main-wrapper">
200 <div id="toc">
201 <a href="https://ziglang.org/documentation/0.1.1/">0.1.1</a> |
202 <a href="https://ziglang.org/documentation/0.2.0/">0.2.0</a> |
203 <a href="https://ziglang.org/documentation/0.3.0/">0.3.0</a> |
204 <a href="https://ziglang.org/documentation/0.4.0/">0.4.0</a> |
205 <a href="https://ziglang.org/documentation/0.5.0/">0.5.0</a> |
206 <a href="https://ziglang.org/documentation/0.6.0/">0.6.0</a> |
207 <a href="https://ziglang.org/documentation/0.7.1/">0.7.1</a> |
208 <a href="https://ziglang.org/documentation/0.8.1/">0.8.1</a> |
209 master
210 <h1>Contents</h1>
211 {#nav#}
276 }
277 </style>
278</head>
279<body>
280 <header><h1>Zig Language Reference</h1></header>
281 <div id="main-wrapper">
282 <div id="navigation">
283 <nav aria-labelledby="zig-version">
284 <h2 id="zig-version">Zig Version</h2>
285 <a href="https://ziglang.org/documentation/0.1.1/">0.1.1</a> |
286 <a href="https://ziglang.org/documentation/0.2.0/">0.2.0</a> |
287 <a href="https://ziglang.org/documentation/0.3.0/">0.3.0</a> |
288 <a href="https://ziglang.org/documentation/0.4.0/">0.4.0</a> |
289 <a href="https://ziglang.org/documentation/0.5.0/">0.5.0</a> |
290 <a href="https://ziglang.org/documentation/0.6.0/">0.6.0</a> |
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>
212299 </div>
213 <div id="contents-wrapper"><div id="contents">
300 <div id="contents-wrapper"><main id="contents">
214301 {#header_open|Introduction#}
215302 <p>
216 Zig is a general-purpose programming language and toolchain for maintaining
303 <a href="https://ziglang.org">Zig</a> is a general-purpose programming language and toolchain for maintaining
217304 <strong>robust</strong>, <strong>optimal</strong>, and <strong>reusable</strong> software.
218305 </p>
219 <ul>
220 <li><strong>Robust</strong> - behavior is correct even for edge cases such as out of memory.</li>
221 <li><strong>Optimal</strong> - write programs the best way they can behave and perform.</li>
222 <li><strong>Reusable</strong> - the same code works in many environments which have different
223 constraints.</li>
224 <li><strong>Maintainable</strong> - precisely communicate intent to the compiler and
306 <dl>
307 <dt>Robust</dt><dd>Behavior is correct even for edge cases such as out of memory.</dd>
308 <dt>Optimal</dt><dd>Write programs the best way they can behave and perform.</dd>
309 <dt>Reusable</dt><dd>The same code works in many environments which have different
310 constraints.</dd>
311 <dt>Maintainable</dt><dd>Precisely communicate intent to the compiler and
225312 other programmers. The language imposes a low overhead to reading code and is
226 resilient to changing requirements and environments.</li>
227 </ul>
313 resilient to changing requirements and environments.</dd>
314 </dl>
228315 <p>
229316 Often the most efficient way to learn something new is to see examples, so
230317 this documentation shows how to use each of Zig's features. It is
......@@ -236,8 +323,16 @@
236323 <p>
237324 This HTML document depends on no external files, so you can use it offline.
238325 </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>
239332 <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.
241336 </p>
242337 {#header_close#}
243338
......@@ -252,96 +347,102 @@ pub fn main() !void {
252347}
253348 {#code_end#}
254349 <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>.
256351 </p>
257352 <p>
258 The code sample shows the contents of a file named <code>hello.zig</code>. Files storing Zig
353 The code sample shows the contents of a file named <code class="file">hello.zig</code>. Files storing Zig
259354 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.
261356 </p>
262357 <p>
263 Following the <code>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, the
265 <code>hello</code> program is executed showing its output <code>Hello, world!</code>. The
266 lines beginning with <code>$</code> represent command line prompts and a command.
358 Following the <code class="file">hello.zig</code> Zig code sample, the {#link|Zig Build System#} is used
359 to build an executable program from the <code class="file">hello.zig</code> source code. Then, the
360 <code class="file">hello</code> program is executed showing its output <samp>Hello, world!</samp>. The
361 lines beginning with <samp>$</samp> represent command line prompts and a command.
267362 Everything else is program output.
268363 </p>
269364 <p>
270 The code sample begins by adding Zig's 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.
365 The code sample begins by adding the {#link|Zig Standard Library#} to the build using the {#link|@import#} builtin function.
366 The {#syntax#}@import("std"){#endsyntax#} function call creates a structure that represents the Zig Standard Library.
272367 The code then {#link|declares|Container Level Variables#} a
273 {#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to
274 <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>.
368 {#link|constant identifier|Assignment#}, named {#syntax#}std{#endsyntax#}, that gives access the features of the Zig Standard Library.
275369 </p>
276370 <p>
277 Next, a {#link|public function|Functions#}, {#syntax#}pub fn{#endsyntax#}, named <code>main</code>
278 is declared. The <code>main</code> function is necessary because it tells the Zig compiler where the start of
371 Next, a {#link|public function|Functions#}, {#syntax#}pub fn{#endsyntax#}, named {#syntax#}main{#endsyntax#}
372 is declared. The {#syntax#}main{#endsyntax#} function is necessary because it tells the Zig compiler where the start of
279373 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.
283374 </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>
284382 <p>
285383 A function is a block of any number of statements and expressions that, as a whole, perform a task.
286384 Functions may or may not return data after they are done performing their task. If a function
287385 cannot perform its task, it might return an error. Zig makes all of this explicit.
288386 </p>
289387 <p>
290 In the <code>hello.zig</code> code sample, the <code>main</code> function is declared
388 In the <code class="file">hello.zig</code> code sample, the <code>main</code> function is declared
291389 with the {#syntax#}!void{#endsyntax#} return type. This return type is known as an {#link|Error Union Type#}.
292390 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#}).
294393 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 code
394 <code>&lt;error set type&gt;</code>{#syntax#}!{#endsyntax#}<code>&lt;any data type&gt;</code>. In the code
296395 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 an
298 {#link|inferred error set type|Inferred Error Sets#}. The {#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).
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>.
396 When written this way, the error set type is an {#link|inferred error set type|Inferred Error Sets#}. The
397 {#syntax#}void{#endsyntax#} after the {#syntax#}!{#endsyntax#} operator
398 tells the compiler that the function will not return a value under normal circumstances (i.e. when no errors occur).
305399 </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>
306407 <p>
307 In Zig, a function's block of statements and expressions are surrounded by <code>{</code> and
308 <code>}</code> curly-braces. Inside of the <code>main</code> function are expressions that perform
309 the task of outputting <code>Hello, world!</code> to standard output.
408 In Zig, a function's block of statements and expressions are surrounded by an open curly-brace <code>{</code> and
409 close curly-brace <code>}</code>. Inside of the {#syntax#}main{#endsyntax#} function are expressions that perform
410 the task of outputting <samp>Hello, world!</samp> to standard output.
310411 </p>
311412 <p>
312 First, a constant identifier, <code>stdout</code>, is initialized to represent standard output's
313 writer. Then, the program tries to print the <code>Hello, world!</code>
413 First, a constant identifier, {#syntax#}stdout{#endsyntax#}, is initialized to represent standard output's
414 writer. Then, the program tries to print the <samp>Hello, world!</samp>
314415 message to standard output.
315416 </p>
316417 <p>
317418 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 after
419 to functions between an open parenthesis {#syntax#}({#endsyntax#} and a close parenthesis {#syntax#}){#endsyntax#} placed after
319420 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#}.
321422 </p>
322423 <p>
323 The two arguments passed to the <code>stdout.print()</code> function, <code>"Hello, {s}!\n"</code>
324 and <code>.{"world"}</code>, are evaluated at {#link|compile-time|comptime#}. The code sample is
424 The two arguments passed to the {#syntax#}stdout.print(){#endsyntax#} function, {#syntax#}"Hello, {s}!\n"{#endsyntax#}
425 and {#syntax#}.{"world"}{#endsyntax#}, are evaluated at {#link|compile-time|comptime#}. The code sample is
325426 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 argument
427 substitution in the {#syntax#}print{#endsyntax#} function. The curly-braces inside of the first argument
327428 are substituted with the compile-time known value inside of the second argument
328429 (known as an {#link|anonymous struct literal|Anonymous Struct Literals#}). The <code>\n</code>
329430 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#}.
331432 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 no
333 more statements or expressions left to execute in the <code>main</code> function, so the program exits.
433 {#syntax#}main{#endsyntax#} with the error. Otherwise, the program will continue. In this case, there are no
434 more statements or expressions left to execute in the {#syntax#}main{#endsyntax#} function, so the program exits.
334435 </p>
335436 <p>
336 In Zig, the standard output writer's <code>print</code> function is allowed to fail because
437 In Zig, the standard output writer's {#syntax#}print{#endsyntax#} function is allowed to fail because
337438 it is actually a function defined as part of a generic Writer. Consider a generic Writer that
338439 represents writing data to a file. When the disk is full, a write to the file will fail.
339440 However, we typically do not expect writing text to the standard output to fail. To avoid having
340441 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.
342443 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 of
344 <code>std.debug.print</code>.
444 on failure. The next code sample, <code class="file">hello_again.zig</code> demonstrates the use of
445 {#syntax#}std.debug.print{#endsyntax#}.
345446 </p>
346447 {#code_begin|exe|hello_again#}
347448const print = @import("std").debug.print;
......@@ -351,13 +452,13 @@ pub fn main() void {
351452}
352453 {#code_end#}
353454 <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.
355456 </p>
356457 {#see_also|Values|@import|Errors|Root Source File|Source Encoding#}
357458 {#header_close#}
358459 {#header_open|Zig Test#}
359460 <p>
360 <code>zig test</code> is a tool that can be used to quickly build and run Zig code
461 <kbd>zig test</kbd> is a tool that can be used to quickly build and run Zig code
361462 to make sure behavior meets expectations. {#syntax#}@import("builtin").is_test{#endsyntax#}
362463 is available for code to detect whether the current build is a test build.
363464 </p>
......@@ -387,7 +488,7 @@ test "unused function" { }
387488 undefined behavior. The implementation of {#syntax#}std.debug.assert{#endsyntax#} is as
388489 simple as:
389490 </p>
390 {#code_begin|syntax#}
491 {#code_begin|syntax|assert#}
391492pub fn assert(ok: bool) void {
392493 if (!ok) unreachable;
393494}
......@@ -396,7 +497,7 @@ pub fn assert(ok: bool) void {
396497 This means that when testing in ReleaseFast or ReleaseSmall mode, {#syntax#}assert{#endsyntax#}
397498 is not sufficient to check the result of a computation:
398499 </p>
399 {#code_begin|syntax#}
500 {#code_begin|syntax|assert_release_fast_mode#}
400501const std = @import("std");
401502const assert = std.debug.assert;
402503
......@@ -423,14 +524,13 @@ test "expect in release fast mode" {
423524 {#code_end#}
424525 <p>See the rest of the {#syntax#}std.testing{#endsyntax#} namespace for more available functions.</p>
425526 <p>
426 <code>zig test</code> 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>.
527 <kbd>zig test</kbd> has a few command line parameters which affect the compilation. See
528 <kbd>zig --help</kbd> for a full list. The most interesting one is <kbd>--test-filter [text]</kbd>.
428529 This makes the test build only include tests whose name contains the supplied filter text.
429530 Again, thanks to lazy analysis, this can allow you to narrow a build to only a few functions in
430531 isolation.
431532 </p>
432533 {#header_close#}
433
434534 {#header_open|Comments#}
435535 {#code_begin|test|comments#}
436536const expect = @import("std").testing.expect;
......@@ -555,184 +655,183 @@ pub fn main() void {
555655 {#header_open|Primitive Types#}
556656 <div class="table-wrapper">
557657 <table>
558 <tr>
559 <th>
560 Name
561 </th>
562 <th>
563 C Equivalent
564 </th>
565 <th>
566 Description
567 </th>
658 <caption>Primitive Types</caption>
659 <thead>
660 <tr>
661 <th scope="col">Type</th>
662 <th scope="col">C Equivalent</th>
663 <th scope="col">Description</th>
568664 </tr>
665 </thead>
666 <tbody>
569667 <tr>
570 <td>{#syntax#}i8{#endsyntax#}</td>
668 <th scope="row">{#syntax#}i8{#endsyntax#}</th>
571669 <td><code class="c">int8_t</code></td>
572670 <td>signed 8-bit integer</td>
573671 </tr>
574672 <tr>
575 <td>{#syntax#}u8{#endsyntax#}</td>
673 <th scope="row">{#syntax#}u8{#endsyntax#}</th>
576674 <td><code class="c">uint8_t</code></td>
577675 <td>unsigned 8-bit integer</td>
578676 </tr>
579677 <tr>
580 <td>{#syntax#}i16{#endsyntax#}</td>
678 <th scope="row">{#syntax#}i16{#endsyntax#}</th>
581679 <td><code class="c">int16_t</code></td>
582680 <td>signed 16-bit integer</td>
583681 </tr>
584682 <tr>
585 <td>{#syntax#}u16{#endsyntax#}</td>
683 <th scope="row">{#syntax#}u16{#endsyntax#}</th>
586684 <td><code class="c">uint16_t</code></td>
587685 <td>unsigned 16-bit integer</td>
588686 </tr>
589687 <tr>
590 <td>{#syntax#}i32{#endsyntax#}</td>
688 <th scope="row">{#syntax#}i32{#endsyntax#}</th>
591689 <td><code class="c">int32_t</code></td>
592690 <td>signed 32-bit integer</td>
593691 </tr>
594692 <tr>
595 <td>{#syntax#}u32{#endsyntax#}</td>
693 <th scope="row">{#syntax#}u32{#endsyntax#}</th>
596694 <td><code class="c">uint32_t</code></td>
597695 <td>unsigned 32-bit integer</td>
598696 </tr>
599697 <tr>
600 <td>{#syntax#}i64{#endsyntax#}</td>
698 <th scope="row">{#syntax#}i64{#endsyntax#}</th>
601699 <td><code class="c">int64_t</code></td>
602700 <td>signed 64-bit integer</td>
603701 </tr>
604702 <tr>
605 <td>{#syntax#}u64{#endsyntax#}</td>
703 <th scope="row">{#syntax#}u64{#endsyntax#}</th>
606704 <td><code class="c">uint64_t</code></td>
607705 <td>unsigned 64-bit integer</td>
608706 </tr>
609707 <tr>
610 <td>{#syntax#}i128{#endsyntax#}</td>
708 <th scope="row">{#syntax#}i128{#endsyntax#}</th>
611709 <td><code class="c">__int128</code></td>
612710 <td>signed 128-bit integer</td>
613711 </tr>
614712 <tr>
615 <td>{#syntax#}u128{#endsyntax#}</td>
713 <th scope="row">{#syntax#}u128{#endsyntax#}</th>
616714 <td><code class="c">unsigned __int128</code></td>
617715 <td>unsigned 128-bit integer</td>
618716 </tr>
619717 <tr>
620 <td>{#syntax#}isize{#endsyntax#}</td>
718 <th scope="row">{#syntax#}isize{#endsyntax#}</th>
621719 <td><code class="c">intptr_t</code></td>
622720 <td>signed pointer sized integer</td>
623721 </tr>
624722 <tr>
625 <td>{#syntax#}usize{#endsyntax#}</td>
723 <th scope="row">{#syntax#}usize{#endsyntax#}</th>
626724 <td><code class="c">uintptr_t</code></td>
627725 <td>unsigned pointer sized integer</td>
628726 </tr>
629727
630728 <tr>
631 <td>{#syntax#}c_short{#endsyntax#}</td>
729 <th scope="row">{#syntax#}c_short{#endsyntax#}</th>
632730 <td><code class="c">short</code></td>
633731 <td>for ABI compatibility with C</td>
634732 </tr>
635733 <tr>
636 <td>{#syntax#}c_ushort{#endsyntax#}</td>
734 <th scope="row">{#syntax#}c_ushort{#endsyntax#}</th>
637735 <td><code class="c">unsigned short</code></td>
638736 <td>for ABI compatibility with C</td>
639737 </tr>
640738 <tr>
641 <td>{#syntax#}c_int{#endsyntax#}</td>
739 <th scope="row">{#syntax#}c_int{#endsyntax#}</th>
642740 <td><code class="c">int</code></td>
643741 <td>for ABI compatibility with C</td>
644742 </tr>
645743 <tr>
646 <td>{#syntax#}c_uint{#endsyntax#}</td>
744 <th scope="row">{#syntax#}c_uint{#endsyntax#}</th>
647745 <td><code class="c">unsigned int</code></td>
648746 <td>for ABI compatibility with C</td>
649747 </tr>
650748 <tr>
651 <td>{#syntax#}c_long{#endsyntax#}</td>
749 <th scope="row">{#syntax#}c_long{#endsyntax#}</th>
652750 <td><code class="c">long</code></td>
653751 <td>for ABI compatibility with C</td>
654752 </tr>
655753 <tr>
656 <td>{#syntax#}c_ulong{#endsyntax#}</td>
754 <th scope="row">{#syntax#}c_ulong{#endsyntax#}</th>
657755 <td><code class="c">unsigned long</code></td>
658756 <td>for ABI compatibility with C</td>
659757 </tr>
660758 <tr>
661 <td>{#syntax#}c_longlong{#endsyntax#}</td>
759 <th scope="row">{#syntax#}c_longlong{#endsyntax#}</th>
662760 <td><code class="c">long long</code></td>
663761 <td>for ABI compatibility with C</td>
664762 </tr>
665763 <tr>
666 <td>{#syntax#}c_ulonglong{#endsyntax#}</td>
764 <th scope="row">{#syntax#}c_ulonglong{#endsyntax#}</th>
667765 <td><code class="c">unsigned long long</code></td>
668766 <td>for ABI compatibility with C</td>
669767 </tr>
670768 <tr>
671 <td>{#syntax#}c_longdouble{#endsyntax#}</td>
769 <th scope="row">{#syntax#}c_longdouble{#endsyntax#}</th>
672770 <td><code class="c">long double</code></td>
673771 <td>for ABI compatibility with C</td>
674772 </tr>
675773 <tr>
676 <td>{#syntax#}c_void{#endsyntax#}</td>
774 <th scope="row">{#syntax#}c_void{#endsyntax#}</th>
677775 <td><code class="c">void</code></td>
678776 <td>for ABI compatibility with C</td>
679777 </tr>
680778
681779 <tr>
682 <td>{#syntax#}f16{#endsyntax#}</td>
780 <th scope="row">{#syntax#}f16{#endsyntax#}</th>
683781 <td><code class="c">_Float16</code></td>
684782 <td>16-bit floating point (10-bit mantissa) IEEE-754-2008 binary16</td>
685783 </tr>
686784 <tr>
687 <td>{#syntax#}f32{#endsyntax#}</td>
785 <th scope="row">{#syntax#}f32{#endsyntax#}</th>
688786 <td><code class="c">float</code></td>
689787 <td>32-bit floating point (23-bit mantissa) IEEE-754-2008 binary32</td>
690788 </tr>
691789 <tr>
692 <td>{#syntax#}f64{#endsyntax#}</td>
790 <th scope="row">{#syntax#}f64{#endsyntax#}</th>
693791 <td><code class="c">double</code></td>
694792 <td>64-bit floating point (52-bit mantissa) IEEE-754-2008 binary64</td>
695793 </tr>
696794 <tr>
697 <td>{#syntax#}f128{#endsyntax#}</td>
795 <th scope="row">{#syntax#}f128{#endsyntax#}</th>
698796 <td><code class="c">_Float128</code></td>
699797 <td>128-bit floating point (112-bit mantissa) IEEE-754-2008 binary128</td>
700798 </tr>
701799 <tr>
702 <td>{#syntax#}bool{#endsyntax#}</td>
800 <th scope="row">{#syntax#}bool{#endsyntax#}</th>
703801 <td><code class="c">bool</code></td>
704802 <td>{#syntax#}true{#endsyntax#} or {#syntax#}false{#endsyntax#}</td>
705803 </tr>
706804 <tr>
707 <td>{#syntax#}void{#endsyntax#}</td>
805 <th scope="row">{#syntax#}void{#endsyntax#}</th>
708806 <td>(none)</td>
709807 <td>0 bit type</td>
710808 </tr>
711809 <tr>
712 <td>{#syntax#}noreturn{#endsyntax#}</td>
810 <th scope="row">{#syntax#}noreturn{#endsyntax#}</th>
713811 <td>(none)</td>
714812 <td>the type of {#syntax#}break{#endsyntax#}, {#syntax#}continue{#endsyntax#}, {#syntax#}return{#endsyntax#}, {#syntax#}unreachable{#endsyntax#}, and {#syntax#}while (true) {}{#endsyntax#}</td>
715813 </tr>
716814 <tr>
717 <td>{#syntax#}type{#endsyntax#}</td>
815 <th scope="row">{#syntax#}type{#endsyntax#}</th>
718816 <td>(none)</td>
719817 <td>the type of types</td>
720818 </tr>
721819 <tr>
722 <td>{#syntax#}anyerror{#endsyntax#}</td>
820 <th scope="row">{#syntax#}anyerror{#endsyntax#}</th>
723821 <td>(none)</td>
724822 <td>an error code</td>
725823 </tr>
726824 <tr>
727 <td>{#syntax#}comptime_int{#endsyntax#}</td>
825 <th scope="row">{#syntax#}comptime_int{#endsyntax#}</th>
728826 <td>(none)</td>
729827 <td>Only allowed for {#link|comptime#}-known values. The type of integer literals.</td>
730828 </tr>
731829 <tr>
732 <td>{#syntax#}comptime_float{#endsyntax#}</td>
830 <th scope="row">{#syntax#}comptime_float{#endsyntax#}</th>
733831 <td>(none)</td>
734832 <td>Only allowed for {#link|comptime#}-known values. The type of float literals.</td>
735833 </tr>
834 </tbody>
736835 </table>
737836 </div>
738837 <p>
......@@ -746,26 +845,27 @@ pub fn main() void {
746845 {#header_open|Primitive Values#}
747846 <div class="table-wrapper">
748847 <table>
848 <caption>Primitive Values</caption>
849 <thead>
749850 <tr>
750 <th>
751 Name
752 </th>
753 <th>
754 Description
755 </th>
851 <th scope="col">Name</th>
852 <th scope="col">Description</th>
756853 </tr>
854 </thead>
855 <tbody>
757856 <tr>
758 <td>{#syntax#}true{#endsyntax#} and {#syntax#}false{#endsyntax#}</td>
857 <th scope="row">{#syntax#}true{#endsyntax#} and {#syntax#}false{#endsyntax#}</th>
759858 <td>{#syntax#}bool{#endsyntax#} values</td>
760859 </tr>
761860 <tr>
762 <td>{#syntax#}null{#endsyntax#}</td>
861 <th scope="row">{#syntax#}null{#endsyntax#}</th>
763862 <td>used to set an optional type to {#syntax#}null{#endsyntax#}</td>
764863 </tr>
765864 <tr>
766 <td>{#syntax#}undefined{#endsyntax#}</td>
865 <th scope="row">{#syntax#}undefined{#endsyntax#}</th>
767866 <td>used to leave a value unspecified</td>
768867 </tr>
868 </tbody>
769869 </table>
770870 </div>
771871 {#see_also|Optionals|undefined#}
......@@ -796,7 +896,7 @@ pub fn main() void {
796896 in recent versions of the Unicode specification (as of Unicode 13.0).
797897 In Zig, a Unicode code point literal corresponds to the Unicode definition of a code point.
798898 </p>
799 {#code_begin|test#}
899 {#code_begin|test|string_literals_test#}
800900const expect = @import("std").testing.expect;
801901const mem = @import("std").mem;
802902
......@@ -817,46 +917,47 @@ test "string literals" {
817917 {#header_open|Escape Sequences#}
818918 <div class="table-wrapper">
819919 <table>
920 <caption>Escape Sequences</caption>
921 <thead>
820922 <tr>
821 <th>
822 Escape Sequence
823 </th>
824 <th>
825 Name
826 </th>
923 <th scope="col">Escape Sequence</th>
924 <th scope="col">Name</th>
827925 </tr>
926 </thead>
927 <tbody>
828928 <tr>
829 <td><code>\n</code></td>
929 <th scope="row"><code>\n</code></th>
830930 <td>Newline</td>
831931 </tr>
832932 <tr>
833 <td><code>\r</code></td>
933 <th scope="row"><code>\r</code></th>
834934 <td>Carriage Return</td>
835935 </tr>
836936 <tr>
837 <td><code>\t</code></td>
937 <th scope="row"><code>\t</code></th>
838938 <td>Tab</td>
839939 </tr>
840940 <tr>
841 <td><code>\\</code></td>
941 <th scope="row"><code>\\</code></th>
842942 <td>Backslash</td>
843943 </tr>
844944 <tr>
845 <td><code>\'</code></td>
945 <th scope="row"><code>\'</code></th>
846946 <td>Single Quote</td>
847947 </tr>
848948 <tr>
849 <td><code>\"</code></td>
949 <th scope="row"><code>\"</code></th>
850950 <td>Double Quote</td>
851951 </tr>
852952 <tr>
853 <td><code>\xNN</code></td>
953 <th scope="row"><code>\xNN</code></th>
854954 <td>hexadecimal 8-bit byte value (2 digits)</td>
855955 </tr>
856956 <tr>
857 <td><code>\u{NNNNNN}</code></td>
957 <th scope="row"><code>\u{NNNNNN}</code></th>
858958 <td>hexadecimal Unicode code point UTF-8 encoded (1 or more digits)</td>
859959 </tr>
960 </tbody>
860961 </table>
861962 </div>
862963 <p>Note that the maximum valid Unicode point is {#syntax#}0x10ffff{#endsyntax#}.</p>
......@@ -870,7 +971,7 @@ test "string literals" {
870971 However, if the next line begins with {#syntax#}\\{#endsyntax#} then a newline is appended and
871972 the string literal continues.
872973 </p>
873 {#code_begin|syntax#}
974 {#code_begin|syntax|multiline_string_literals#}
874975const hello_world_in_c =
875976 \\#include <stdio.h>
876977 \\
......@@ -902,7 +1003,7 @@ test "assignment" {
9021003 {#code_end#}
9031004 <p>{#syntax#}const{#endsyntax#} applies to all of the bytes that the identifier immediately addresses. {#link|Pointers#} have their own const-ness.</p>
9041005 <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#}
9061007const expect = @import("std").testing.expect;
9071008
9081009test "var" {
......@@ -923,7 +1024,7 @@ test "initialization" {
9231024 {#code_end#}
9241025 {#header_open|undefined#}
9251026 <p>Use {#syntax#}undefined{#endsyntax#} to leave variables uninitialized:</p>
926 {#code_begin|test#}
1027 {#code_begin|test|undefined_test#}
9271028const expect = @import("std").testing.expect;
9281029
9291030test "init with undefined" {
......@@ -1108,7 +1209,7 @@ test "comptime vars" {
11081209
11091210 {#header_open|Integers#}
11101211 {#header_open|Integer Literals#}
1111 {#code_begin|syntax#}
1212 {#code_begin|syntax|integer_literals#}
11121213const decimal_int = 98222;
11131214const hex_int = 0xff;
11141215const another_hex_int = 0xFF;
......@@ -1131,7 +1232,7 @@ const big_address = 0xFF80_0000_0000_0000;
11311232 However, once an integer value is no longer known at compile-time, it must have a
11321233 known size, and is vulnerable to undefined behavior.
11331234 </p>
1134 {#code_begin|syntax#}
1235 {#code_begin|syntax|runtime_vs_comptime#}
11351236fn divide(a: i32, b: i32) i32 {
11361237 return a / b;
11371238}
......@@ -1174,7 +1275,7 @@ fn divide(a: i32, b: i32) i32 {
11741275 Float literals {#link|coerce|Type Coercion#} to any floating point type,
11751276 and to any {#link|integer|Integers#} type when there is no fractional component.
11761277 </p>
1177 {#code_begin|syntax#}
1278 {#code_begin|syntax|float_literals#}
11781279const floating_point = 123.0E+77;
11791280const another_float = 123.0;
11801281const yet_another = 123.0e+77;
......@@ -1192,7 +1293,7 @@ const more_hex = 0x1234_5678.9ABC_CDEFp-10;
11921293 There is no syntax for NaN, infinity, or negative infinity. For these special values,
11931294 one must use the standard library:
11941295 </p>
1195 {#code_begin|syntax#}
1296 {#code_begin|syntax|float_special_values#}
11961297const std = @import("std");
11971298
11981299const inf = std.math.inf(f32);
......@@ -1245,23 +1346,19 @@ pub fn main() void {
12451346 {#header_open|Table of Operators#}
12461347 <div class="table-wrapper">
12471348 <table>
1349 <caption>Table of Operators</caption>
1350 <thead>
12481351 <tr>
1249 <th>
1250 Syntax
1251 </th>
1252 <th>
1253 Relevant Types
1254 </th>
1255 <th>
1256 Description
1257 </th>
1258 <th>
1259 Example
1260 </th>
1352 <th scope="col">Syntax</th>
1353 <th scope="col">Relevant Types</th>
1354 <th scope="col">Description</th>
1355 <th scope="col">Example</th>
12611356 </tr>
1357 </thead>
1358 <tbody>
12621359 <tr>
1263 <td><pre>{#syntax#}a + b
1264a += b{#endsyntax#}</pre></td>
1360 <th scope="row"><pre>{#syntax#}a + b
1361a += b{#endsyntax#}</pre></th>
12651362 <td>
12661363 <ul>
12671364 <li>{#link|Integers#}</li>
......@@ -1280,8 +1377,8 @@ a += b{#endsyntax#}</pre></td>
12801377 </td>
12811378 </tr>
12821379 <tr>
1283 <td><pre>{#syntax#}a +% b
1284a +%= b{#endsyntax#}</pre></td>
1380 <th scope="row"><pre>{#syntax#}a +% b
1381a +%= b{#endsyntax#}</pre></th>
12851382 <td>
12861383 <ul>
12871384 <li>{#link|Integers#}</li>
......@@ -1299,8 +1396,8 @@ a +%= b{#endsyntax#}</pre></td>
12991396 </td>
13001397 </tr>
13011398 <tr>
1302 <td><pre>{#syntax#}a - b
1303a -= b{#endsyntax#}</pre></td>
1399 <th scope="row"><pre>{#syntax#}a - b
1400a -= b{#endsyntax#}</pre></th>
13041401 <td>
13051402 <ul>
13061403 <li>{#link|Integers#}</li>
......@@ -1319,8 +1416,8 @@ a -= b{#endsyntax#}</pre></td>
13191416 </td>
13201417 </tr>
13211418 <tr>
1322 <td><pre>{#syntax#}a -% b
1323a -%= b{#endsyntax#}</pre></td>
1419 <th scope="row"><pre>{#syntax#}a -% b
1420a -%= b{#endsyntax#}</pre></th>
13241421 <td>
13251422 <ul>
13261423 <li>{#link|Integers#}</li>
......@@ -1338,7 +1435,7 @@ a -%= b{#endsyntax#}</pre></td>
13381435 </td>
13391436 </tr>
13401437 <tr>
1341 <td><pre>{#syntax#}-a{#endsyntax#}</pre></td>
1438 <th scope="row"><pre>{#syntax#}-a{#endsyntax#}</pre></th>
13421439 <td>
13431440 <ul>
13441441 <li>{#link|Integers#}</li>
......@@ -1356,7 +1453,7 @@ a -%= b{#endsyntax#}</pre></td>
13561453 </td>
13571454 </tr>
13581455 <tr>
1359 <td><pre>{#syntax#}-%a{#endsyntax#}</pre></td>
1456 <th scope="row"><pre>{#syntax#}-%a{#endsyntax#}</pre></th>
13601457 <td>
13611458 <ul>
13621459 <li>{#link|Integers#}</li>
......@@ -1373,8 +1470,8 @@ a -%= b{#endsyntax#}</pre></td>
13731470 </td>
13741471 </tr>
13751472 <tr>
1376 <td><pre>{#syntax#}a * b
1377a *= b{#endsyntax#}</pre></td>
1473 <th scope="row"><pre>{#syntax#}a * b
1474a *= b{#endsyntax#}</pre></th>
13781475 <td>
13791476 <ul>
13801477 <li>{#link|Integers#}</li>
......@@ -1393,8 +1490,8 @@ a *= b{#endsyntax#}</pre></td>
13931490 </td>
13941491 </tr>
13951492 <tr>
1396 <td><pre>{#syntax#}a *% b
1397a *%= b{#endsyntax#}</pre></td>
1493 <th scope="row"><pre>{#syntax#}a *% b
1494a *%= b{#endsyntax#}</pre></th>
13981495 <td>
13991496 <ul>
14001497 <li>{#link|Integers#}</li>
......@@ -1412,8 +1509,8 @@ a *%= b{#endsyntax#}</pre></td>
14121509 </td>
14131510 </tr>
14141511 <tr>
1415 <td><pre>{#syntax#}a / b
1416a /= b{#endsyntax#}</pre></td>
1512 <th scope="row"><pre>{#syntax#}a / b
1513a /= b{#endsyntax#}</pre></th>
14171514 <td>
14181515 <ul>
14191516 <li>{#link|Integers#}</li>
......@@ -1438,8 +1535,8 @@ a /= b{#endsyntax#}</pre></td>
14381535 </td>
14391536 </tr>
14401537 <tr>
1441 <td><pre>{#syntax#}a % b
1442a %= b{#endsyntax#}</pre></td>
1538 <th scope="row"><pre>{#syntax#}a % b
1539a %= b{#endsyntax#}</pre></th>
14431540 <td>
14441541 <ul>
14451542 <li>{#link|Integers#}</li>
......@@ -1462,8 +1559,8 @@ a %= b{#endsyntax#}</pre></td>
14621559 </td>
14631560 </tr>
14641561 <tr>
1465 <td><pre>{#syntax#}a << b
1466a <<= b{#endsyntax#}</pre></td>
1562 <th scope="row"><pre>{#syntax#}a << b
1563a <<= b{#endsyntax#}</pre></th>
14671564 <td>
14681565 <ul>
14691566 <li>{#link|Integers#}</li>
......@@ -1481,8 +1578,8 @@ a <<= b{#endsyntax#}</pre></td>
14811578 </td>
14821579 </tr>
14831580 <tr>
1484 <td><pre>{#syntax#}a >> b
1485a >>= b{#endsyntax#}</pre></td>
1581 <th scope="row"><pre>{#syntax#}a >> b
1582a >>= b{#endsyntax#}</pre></th>
14861583 <td>
14871584 <ul>
14881585 <li>{#link|Integers#}</li>
......@@ -1499,8 +1596,8 @@ a >>= b{#endsyntax#}</pre></td>
14991596 </td>
15001597 </tr>
15011598 <tr>
1502 <td><pre>{#syntax#}a & b
1503a &= b{#endsyntax#}</pre></td>
1599 <th scope="row"><pre>{#syntax#}a & b
1600a &= b{#endsyntax#}</pre></th>
15041601 <td>
15051602 <ul>
15061603 <li>{#link|Integers#}</li>
......@@ -1516,8 +1613,8 @@ a &= b{#endsyntax#}</pre></td>
15161613 </td>
15171614 </tr>
15181615 <tr>
1519 <td><pre>{#syntax#}a | b
1520a |= b{#endsyntax#}</pre></td>
1616 <th scope="row"><pre>{#syntax#}a | b
1617a |= b{#endsyntax#}</pre></th>
15211618 <td>
15221619 <ul>
15231620 <li>{#link|Integers#}</li>
......@@ -1533,8 +1630,8 @@ a |= b{#endsyntax#}</pre></td>
15331630 </td>
15341631 </tr>
15351632 <tr>
1536 <td><pre>{#syntax#}a ^ b
1537a ^= b{#endsyntax#}</pre></td>
1633 <th scope="row"><pre>{#syntax#}a ^ b
1634a ^= b{#endsyntax#}</pre></th>
15381635 <td>
15391636 <ul>
15401637 <li>{#link|Integers#}</li>
......@@ -1550,7 +1647,7 @@ a ^= b{#endsyntax#}</pre></td>
15501647 </td>
15511648 </tr>
15521649 <tr>
1553 <td><pre>{#syntax#}~a{#endsyntax#}</pre></td>
1650 <th scope="row"><pre>{#syntax#}~a{#endsyntax#}</pre></th>
15541651 <td>
15551652 <ul>
15561653 <li>{#link|Integers#}</li>
......@@ -1564,7 +1661,7 @@ a ^= b{#endsyntax#}</pre></td>
15641661 </td>
15651662 </tr>
15661663 <tr>
1567 <td><pre>{#syntax#}a orelse b{#endsyntax#}</pre></td>
1664 <th scope="row"><pre>{#syntax#}a orelse b{#endsyntax#}</pre></th>
15681665 <td>
15691666 <ul>
15701667 <li>{#link|Optionals#}</li>
......@@ -1582,7 +1679,7 @@ unwrapped == 1234{#endsyntax#}</pre>
15821679 </td>
15831680 </tr>
15841681 <tr>
1585 <td><pre>{#syntax#}a.?{#endsyntax#}</pre></td>
1682 <th scope="row"><pre>{#syntax#}a.?{#endsyntax#}</pre></th>
15861683 <td>
15871684 <ul>
15881685 <li>{#link|Optionals#}</li>
......@@ -1598,8 +1695,8 @@ value.? == 5678{#endsyntax#}</pre>
15981695 </td>
15991696 </tr>
16001697 <tr>
1601 <td><pre>{#syntax#}a catch b
1602a catch |err| b{#endsyntax#}</pre></td>
1698 <th scope="row"><pre>{#syntax#}a catch b
1699a catch |err| b{#endsyntax#}</pre></th>
16031700 <td>
16041701 <ul>
16051702 <li>{#link|Error Unions|Errors#}</li>
......@@ -1618,7 +1715,7 @@ unwrapped == 1234{#endsyntax#}</pre>
16181715 </td>
16191716 </tr>
16201717 <tr>
1621 <td><pre>{#syntax#}a and b{#endsyntax#}</pre></td>
1718 <th scope="row"><pre>{#syntax#}a and b{#endsyntax#}</pre></th>
16221719 <td>
16231720 <ul>
16241721 <li>{#link|bool|Primitive Types#}</li>
......@@ -1633,7 +1730,7 @@ unwrapped == 1234{#endsyntax#}</pre>
16331730 </td>
16341731 </tr>
16351732 <tr>
1636 <td><pre>{#syntax#}a or b{#endsyntax#}</pre></td>
1733 <th scope="row"><pre>{#syntax#}a or b{#endsyntax#}</pre></th>
16371734 <td>
16381735 <ul>
16391736 <li>{#link|bool|Primitive Types#}</li>
......@@ -1648,7 +1745,7 @@ unwrapped == 1234{#endsyntax#}</pre>
16481745 </td>
16491746 </tr>
16501747 <tr>
1651 <td><pre>{#syntax#}!a{#endsyntax#}</pre></td>
1748 <th scope="row"><pre>{#syntax#}!a{#endsyntax#}</pre></th>
16521749 <td>
16531750 <ul>
16541751 <li>{#link|bool|Primitive Types#}</li>
......@@ -1662,7 +1759,7 @@ unwrapped == 1234{#endsyntax#}</pre>
16621759 </td>
16631760 </tr>
16641761 <tr>
1665 <td><pre>{#syntax#}a == b{#endsyntax#}</pre></td>
1762 <th scope="row"><pre>{#syntax#}a == b{#endsyntax#}</pre></th>
16661763 <td>
16671764 <ul>
16681765 <li>{#link|Integers#}</li>
......@@ -1680,7 +1777,7 @@ unwrapped == 1234{#endsyntax#}</pre>
16801777 </td>
16811778 </tr>
16821779 <tr>
1683 <td><pre>{#syntax#}a == null{#endsyntax#}</pre></td>
1780 <th scope="row"><pre>{#syntax#}a == null{#endsyntax#}</pre></th>
16841781 <td>
16851782 <ul>
16861783 <li>{#link|Optionals#}</li>
......@@ -1695,7 +1792,7 @@ value == null{#endsyntax#}</pre>
16951792 </td>
16961793 </tr>
16971794 <tr>
1698 <td><pre>{#syntax#}a != b{#endsyntax#}</pre></td>
1795 <th scope="row"><pre>{#syntax#}a != b{#endsyntax#}</pre></th>
16991796 <td>
17001797 <ul>
17011798 <li>{#link|Integers#}</li>
......@@ -1713,7 +1810,7 @@ value == null{#endsyntax#}</pre>
17131810 </td>
17141811 </tr>
17151812 <tr>
1716 <td><pre>{#syntax#}a > b{#endsyntax#}</pre></td>
1813 <th scope="row"><pre>{#syntax#}a > b{#endsyntax#}</pre></th>
17171814 <td>
17181815 <ul>
17191816 <li>{#link|Integers#}</li>
......@@ -1729,7 +1826,7 @@ value == null{#endsyntax#}</pre>
17291826 </td>
17301827 </tr>
17311828 <tr>
1732 <td><pre>{#syntax#}a >= b{#endsyntax#}</pre></td>
1829 <th scope="row"><pre>{#syntax#}a >= b{#endsyntax#}</pre></th>
17331830 <td>
17341831 <ul>
17351832 <li>{#link|Integers#}</li>
......@@ -1745,7 +1842,7 @@ value == null{#endsyntax#}</pre>
17451842 </td>
17461843 </tr>
17471844 <tr>
1748 <td><pre>{#syntax#}a < b{#endsyntax#}</pre></td>
1845 <th scope="row"><pre>{#syntax#}a < b{#endsyntax#}</pre></th>
17491846 <td>
17501847 <ul>
17511848 <li>{#link|Integers#}</li>
......@@ -1761,7 +1858,7 @@ value == null{#endsyntax#}</pre>
17611858 </td>
17621859 </tr>
17631860 <tr>
1764 <td><pre>{#syntax#}a <= b{#endsyntax#}</pre></td>
1861 <th scope="row"><pre>{#syntax#}a <= b{#endsyntax#}</pre></th>
17651862 <td>
17661863 <ul>
17671864 <li>{#link|Integers#}</li>
......@@ -1777,7 +1874,7 @@ value == null{#endsyntax#}</pre>
17771874 </td>
17781875 </tr>
17791876 <tr>
1780 <td><pre>{#syntax#}a ++ b{#endsyntax#}</pre></td>
1877 <th scope="row"><pre>{#syntax#}a ++ b{#endsyntax#}</pre></th>
17811878 <td>
17821879 <ul>
17831880 <li>{#link|Arrays#}</li>
......@@ -1786,7 +1883,7 @@ value == null{#endsyntax#}</pre>
17861883 <td>
17871884 Array concatenation.
17881885 <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>
17901887 </ul>
17911888 </td>
17921889 <td>
......@@ -1798,7 +1895,7 @@ mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>
17981895 </td>
17991896 </tr>
18001897 <tr>
1801 <td><pre>{#syntax#}a ** b{#endsyntax#}</pre></td>
1898 <th scope="row"><pre>{#syntax#}a ** b{#endsyntax#}</pre></th>
18021899 <td>
18031900 <ul>
18041901 <li>{#link|Arrays#}</li>
......@@ -1807,7 +1904,7 @@ mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>
18071904 <td>
18081905 Array multiplication.
18091906 <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>
18111908 </ul>
18121909 </td>
18131910 <td>
......@@ -1817,7 +1914,7 @@ mem.eql(u8, pattern, "ababab"){#endsyntax#}</pre>
18171914 </td>
18181915 </tr>
18191916 <tr>
1820 <td><pre>{#syntax#}a.*{#endsyntax#}</pre></td>
1917 <th scope="row"><pre>{#syntax#}a.*{#endsyntax#}</pre></th>
18211918 <td>
18221919 <ul>
18231920 <li>{#link|Pointers#}</li>
......@@ -1833,7 +1930,7 @@ ptr.* == 1234{#endsyntax#}</pre>
18331930 </td>
18341931 </tr>
18351932 <tr>
1836 <td><pre>{#syntax#}&a{#endsyntax#}</pre></td>
1933 <th scope="row"><pre>{#syntax#}&a{#endsyntax#}</pre></th>
18371934 <td>
18381935 All types
18391936 </td>
......@@ -1847,7 +1944,7 @@ ptr.* == 1234{#endsyntax#}</pre>
18471944 </td>
18481945 </tr>
18491946 <tr>
1850 <td><pre>{#syntax#}a || b{#endsyntax#}</pre></td>
1947 <th scope="row"><pre>{#syntax#}a || b{#endsyntax#}</pre></th>
18511948 <td>
18521949 <ul>
18531950 <li>{#link|Error Set Type#}</li>
......@@ -1862,6 +1959,7 @@ const B = error{Two};
18621959(A || B) == error{One, Two}{#endsyntax#}</pre>
18631960 </td>
18641961 </tr>
1962 </tbody>
18651963 </table>
18661964 </div>
18671965 {#header_close#}
......@@ -2138,7 +2236,7 @@ test "null terminated array" {
21382236 </li>
21392237 </ul>
21402238 <p>Use {#syntax#}&x{#endsyntax#} to obtain a single-item pointer:</p>
2141 {#code_begin|test#}
2239 {#code_begin|test|single_item_pointer_test#}
21422240const expect = @import("std").testing.expect;
21432241
21442242test "address of syntax" {
......@@ -2182,7 +2280,7 @@ test "pointer array access" {
21822280 against this kind of undefined behavior. This is one reason
21832281 we prefer slices to pointers.
21842282 </p>
2185 {#code_begin|test#}
2283 {#code_begin|test|slice_bounds#}
21862284const expect = @import("std").testing.expect;
21872285
21882286test "pointer slicing" {
......@@ -2197,7 +2295,7 @@ test "pointer slicing" {
21972295 {#code_end#}
21982296 <p>Pointers work at compile-time too, as long as the code does not depend on
21992297 an undefined memory layout:</p>
2200 {#code_begin|test#}
2298 {#code_begin|test|comptime_pointers#}
22012299const expect = @import("std").testing.expect;
22022300
22032301test "comptime pointers" {
......@@ -2212,7 +2310,7 @@ test "comptime pointers" {
22122310 {#code_end#}
22132311 <p>To convert an integer address into a pointer, use {#syntax#}@intToPtr{#endsyntax#}.
22142312 To convert a pointer to an integer, use {#syntax#}@ptrToInt{#endsyntax#}:</p>
2215 {#code_begin|test#}
2313 {#code_begin|test|integer_pointer_conversion#}
22162314const expect = @import("std").testing.expect;
22172315
22182316test "@ptrToInt and @intToPtr" {
......@@ -2224,7 +2322,7 @@ test "@ptrToInt and @intToPtr" {
22242322 {#code_end#}
22252323 <p>Zig is able to preserve memory addresses in comptime code, as long as
22262324 the pointer is never dereferenced:</p>
2227 {#code_begin|test#}
2325 {#code_begin|test|comptime_pointer_conversion#}
22282326const expect = @import("std").testing.expect;
22292327
22302328test "comptime @intToPtr" {
......@@ -2244,7 +2342,7 @@ test "comptime @intToPtr" {
22442342 should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}.
22452343 In the following code, loads and stores with {#syntax#}mmio_ptr{#endsyntax#} are guaranteed to all happen
22462344 and in the same order as in source code:</p>
2247 {#code_begin|test#}
2345 {#code_begin|test|volatile#}
22482346const expect = @import("std").testing.expect;
22492347
22502348test "volatile" {
......@@ -2263,7 +2361,7 @@ test "volatile" {
22632361 operation that Zig cannot protect you against. Use {#syntax#}@ptrCast{#endsyntax#} only when other
22642362 conversions are not possible.
22652363 </p>
2266 {#code_begin|test#}
2364 {#code_begin|test|pointer_casting#}
22672365const std = @import("std");
22682366const expect = std.testing.expect;
22692367
......@@ -2301,7 +2399,7 @@ test "pointer child type" {
23012399 In Zig, a pointer type has an alignment value. If the value is equal to the
23022400 alignment of the underlying type, it can be omitted from the type:
23032401 </p>
2304 {#code_begin|test#}
2402 {#code_begin|test|variable_alignment#}
23052403const std = @import("std");
23062404const expect = std.testing.expect;
23072405
......@@ -2323,7 +2421,7 @@ test "variable alignment" {
23232421 You can specify alignment on variables and functions. If you do this, then
23242422 pointers to them get the specified alignment:
23252423 </p>
2326 {#code_begin|test#}
2424 {#code_begin|test|variable_func_alignment#}
23272425const expect = @import("std").testing.expect;
23282426
23292427var foo: u8 align(4) = 100;
......@@ -2660,7 +2758,7 @@ test "linked list" {
26602758 Each struct field may have an expression indicating the default field value. Such expressions
26612759 are executed at {#link|comptime#}, and allow the field to be omitted in a struct literal expression:
26622760 </p>
2663 {#code_begin|test#}
2761 {#code_begin|test|default_field_values#}
26642762const Foo = struct {
26652763 a: i32 = 1234,
26662764 b: i32,
......@@ -2709,7 +2807,7 @@ test "default struct initialization fields" {
27092807 in a {#link|@bitCast#} or a {#link|@ptrCast#} to reinterpret memory.
27102808 This even works at {#link|comptime#}:
27112809 </p>
2712 {#code_begin|test#}
2810 {#code_begin|test|packed_structs#}
27132811const std = @import("std");
27142812const native_endian = @import("builtin").target.cpu.arch.endian();
27152813const expect = std.testing.expect;
......@@ -2750,7 +2848,7 @@ fn doTheTest() !void {
27502848 <p>
27512849 Zig allows the address to be taken of a non-byte-aligned field:
27522850 </p>
2753 {#code_begin|test#}
2851 {#code_begin|test|pointer_to_non-byte_aligned_field#}
27542852const std = @import("std");
27552853const expect = std.testing.expect;
27562854
......@@ -2806,7 +2904,7 @@ fn bar(x: *const u3) u3 {
28062904 <p>
28072905 Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer:
28082906 </p>
2809 {#code_begin|test#}
2907 {#code_begin|test|pointer_to_non-bit_aligned_field#}
28102908const std = @import("std");
28112909const expect = std.testing.expect;
28122910
......@@ -2830,7 +2928,7 @@ test "pointer to non-bit-aligned field" {
28302928 <p>
28312929 This can be observed with {#link|@bitOffsetOf#} and {#link|offsetOf#}:
28322930 </p>
2833 {#code_begin|test#}
2931 {#code_begin|test|test_bitOffsetOf_offsetOf#}
28342932const std = @import("std");
28352933const expect = std.testing.expect;
28362934
......@@ -2875,7 +2973,7 @@ test "overaligned pointer to packed struct" {
28752973 <p>
28762974 It's also possible to set alignment of struct fields:
28772975 </p>
2878 {#code_begin|test#}
2976 {#code_begin|test|test_aligned_struct_fields#}
28792977const std = @import("std");
28802978const expectEqual = std.testing.expectEqual;
28812979
......@@ -3129,7 +3227,7 @@ export fn entry(foo: Foo) void { _ = foo; }
31293227 <p>
31303228 Enum literals allow specifying the name of an enum field without specifying the enum type:
31313229 </p>
3132 {#code_begin|test#}
3230 {#code_begin|test|test_enum_literals#}
31333231const std = @import("std");
31343232const expect = std.testing.expect;
31353233
......@@ -3171,7 +3269,7 @@ test "switch using enum literals" {
31713269 A switch on a non-exhaustive enum can include a '_' prong as an alternative to an {#syntax#}else{#endsyntax#} prong
31723270 with the difference being that it makes it a compile error if all the known tag names are not handled by the switch.
31733271 </p>
3174 {#code_begin|test#}
3272 {#code_begin|test|test_switch_non-exhaustive#}
31753273const std = @import("std");
31763274const expect = std.testing.expect;
31773275
......@@ -3224,7 +3322,7 @@ test "simple union" {
32243322}
32253323 {#code_end#}
32263324 <p>You can activate another field by assigning the entire union:</p>
3227 {#code_begin|test#}
3325 {#code_begin|test|test_simple_union#}
32283326const std = @import("std");
32293327const expect = std.testing.expect;
32303328
......@@ -3253,7 +3351,7 @@ test "simple union" {
32533351 to use with {#link|switch#} expressions.
32543352 Tagged unions coerce to their tag type: {#link|Type Coercion: unions and enums#}.
32553353 </p>
3256 {#code_begin|test#}
3354 {#code_begin|test|test_switch_tagged_union#}
32573355const std = @import("std");
32583356const expect = std.testing.expect;
32593357
......@@ -3291,7 +3389,7 @@ test "coerce to enum" {
32913389 <p>In order to modify the payload of a tagged union in a switch expression,
32923390 place a {#syntax#}*{#endsyntax#} before the variable name to make it a pointer:
32933391 </p>
3294 {#code_begin|test#}
3392 {#code_begin|test|test_switch_modify_tagged_union#}
32953393const std = @import("std");
32963394const expect = std.testing.expect;
32973395
......@@ -3320,7 +3418,7 @@ test "modify tagged union in switch" {
33203418 Unions can be made to infer the enum tag type.
33213419 Further, unions can have methods just like structs and enums.
33223420 </p>
3323 {#code_begin|test#}
3421 {#code_begin|test|test_union_method#}
33243422const std = @import("std");
33253423const expect = std.testing.expect;
33263424
......@@ -3352,7 +3450,7 @@ test "union method" {
33523450 {#link|@tagName#} can be used to return a {#link|comptime#}
33533451 {#syntax#}[:0]const u8{#endsyntax#} value representing the field name:
33543452 </p>
3355 {#code_begin|test#}
3453 {#code_begin|test|test_tagName#}
33563454const std = @import("std");
33573455const expect = std.testing.expect;
33583456
......@@ -3377,7 +3475,7 @@ test "@tagName" {
33773475
33783476 {#header_open|packed union#}
33793477 <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>
33813479 {#header_close#}
33823480
33833481 {#header_open|Anonymous Union Literals#}
......@@ -3448,7 +3546,7 @@ test "access variable after block scope" {
34483546 <p>Blocks are expressions. When labeled, {#syntax#}break{#endsyntax#} can be used
34493547 to return a value from the block:
34503548 </p>
3451 {#code_begin|test#}
3549 {#code_begin|test|test_labeled_break#}
34523550const std = @import("std");
34533551const expect = std.testing.expect;
34543552
......@@ -3482,7 +3580,7 @@ test "inside test block" {
34823580 Because of this, when you read Zig code you can rely on an identifier always meaning the same thing,
34833581 within the scope it is defined. Note that you can, however use the same name if the scopes are separate:
34843582 </p>
3485 {#code_begin|test#}
3583 {#code_begin|test|test_scopes#}
34863584test "separate scopes" {
34873585 {
34883586 const pi = 3.14;
......@@ -3569,7 +3667,7 @@ test "switch inside function" {
35693667 done by placing a {#syntax#}*{#endsyntax#} before the capture variable name,
35703668 turning it into a pointer.
35713669 </p>
3572 {#code_begin|test#}
3670 {#code_begin|test|test_switch_tagged_union#}
35733671const expect = @import("std").testing.expect;
35743672
35753673test "switch on tagged union" {
......@@ -3636,7 +3734,7 @@ test "exhaustive switching" {
36363734 {#link|Enum Literals#} can be useful to use with {#syntax#}switch{#endsyntax#} to avoid
36373735 repetitively specifying {#link|enum#} or {#link|union#} types:
36383736 </p>
3639 {#code_begin|test#}
3737 {#code_begin|test|test_exhaustive_switch#}
36403738const std = @import("std");
36413739const expect = std.testing.expect;
36423740
......@@ -3761,7 +3859,7 @@ fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {
37613859 {#header_open|Labeled while#}
37623860 <p>When a {#syntax#}while{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}
37633861 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>
3764 {#code_begin|test#}
3862 {#code_begin|test|test_nested_break#}
37653863test "nested break" {
37663864 outer: while (true) {
37673865 while (true) {
......@@ -3866,7 +3964,7 @@ fn eventuallyErrorSequence() anyerror!u32 {
38663964 allows the code to do some things which only work at compile time,
38673965 such as use types as first class values.
38683966 </p>
3869 {#code_begin|test#}
3967 {#code_begin|test|test_inline_while#}
38703968const expect = @import("std").testing.expect;
38713969
38723970test "inline while loop" {
......@@ -3969,7 +4067,7 @@ test "for else" {
39694067 {#header_open|Labeled for#}
39704068 <p>When a {#syntax#}for{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}
39714069 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>
3972 {#code_begin|test#}
4070 {#code_begin|test|test_nested_break#}
39734071const std = @import("std");
39744072const expect = std.testing.expect;
39754073
......@@ -4005,7 +4103,7 @@ test "nested continue" {
40054103 The capture value and iterator value of inlined for loops are
40064104 compile-time known.
40074105 </p>
4008 {#code_begin|test#}
4106 {#code_begin|test|test_inline_loop#}
40094107const expect = @import("std").testing.expect;
40104108
40114109test "inline for loop" {
......@@ -4278,16 +4376,16 @@ test "errdefer unwinding" {
42784376 {#header_close#}
42794377 {#header_open|unreachable#}
42804378 <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>,
42824380 {#syntax#}unreachable{#endsyntax#} emits a call to {#syntax#}panic{#endsyntax#} with the message <code>reached unreachable code</code>.
42834381 </p>
42844382 <p>
42854383 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#} mode
4384 will never be hit to perform optimizations. However, <kbd>zig test</kbd> even in {#syntax#}ReleaseFast{#endsyntax#} mode
42874385 still emits {#syntax#}unreachable{#endsyntax#} as calls to {#syntax#}panic{#endsyntax#}.
42884386 </p>
42894387 {#header_open|Basics#}
4290 {#code_begin|test#}
4388 {#code_begin|test|test_unreachable#}
42914389// unreachable is used to assert that control flow will never happen upon a
42924390// particular location:
42934391test "basic math" {
......@@ -4343,7 +4441,7 @@ test "type of unreachable" {
43434441 <p>When resolving types together, such as {#syntax#}if{#endsyntax#} clauses or {#syntax#}switch{#endsyntax#} prongs,
43444442 the {#syntax#}noreturn{#endsyntax#} type is compatible with every other type. Consider:
43454443 </p>
4346 {#code_begin|test#}
4444 {#code_begin|test|test_noreturn#}
43474445fn foo(condition: bool, b: u32) void {
43484446 const a = if (condition) b else return;
43494447 _ = a;
......@@ -4354,7 +4452,7 @@ test "noreturn" {
43544452}
43554453 {#code_end#}
43564454 <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#}
43584456 {#target_windows#}
43594457pub 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 { }
44514549 as parameters, Zig may choose to copy and pass by value, or pass by reference, whichever way
44524550 Zig decides will be faster. This is made possible, in part, by the fact that parameters are immutable.
44534551 </p>
4454 {#code_begin|test#}
4552 {#code_begin|test|pass_by_reference_or_value#}
44554553const Point = struct {
44564554 x: i32,
44574555 y: i32,
......@@ -4481,7 +4579,7 @@ test "pass struct to function" {
44814579 In this case the parameter types will be inferred when the function is called.
44824580 Use {#link|@TypeOf#} and {#link|@typeInfo#} to get information about the inferred type.
44834581 </p>
4484 {#code_begin|test#}
4582 {#code_begin|test|test_fn_type_inference#}
44854583const expect = @import("std").testing.expect;
44864584
44874585fn addFortyTwo(x: anytype) @TypeOf(x) {
......@@ -4499,7 +4597,7 @@ test "fn type inference" {
44994597
45004598 {#header_close#}
45014599 {#header_open|Function Reflection#}
4502 {#code_begin|test#}
4600 {#code_begin|test|test_fn_reflection#}
45034601const expect = @import("std").testing.expect;
45044602
45054603test "fn reflection" {
......@@ -4524,7 +4622,7 @@ test "fn reflection" {
45244622 <p>
45254623 You can {#link|coerce|Type Coercion#} an error from a subset to a superset:
45264624 </p>
4527 {#code_begin|test#}
4625 {#code_begin|test|coercing_subset_to_superset#}
45284626const std = @import("std");
45294627
45304628const FileOpenError = error {
......@@ -4608,7 +4706,7 @@ const err = (error {FileNotFound}).FileNotFound;
46084706 <p>
46094707 Here is a function to parse a string into a 64-bit integer:
46104708 </p>
4611 {#code_begin|test#}
4709 {#code_begin|test|error_union_parsing_u64#}
46124710const std = @import("std");
46134711const maxInt = std.math.maxInt;
46144712
......@@ -4791,7 +4889,7 @@ fn createFoo(param: i32) !Foo {
47914889
47924890 <p>An error union is created with the {#syntax#}!{#endsyntax#} binary operator.
47934891 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#}
47954893const expect = @import("std").testing.expect;
47964894
47974895test "error union" {
......@@ -4823,7 +4921,7 @@ test "error union" {
48234921 {#syntax#}LinuxFileOpenError || WindowsFileOpenError{#endsyntax#} for the error set of opening
48244922 files.
48254923 </p>
4826 {#code_begin|test#}
4924 {#code_begin|test|test_merging_error_sets#}
48274925const A = error{
48284926 NotDir,
48294927
......@@ -4859,7 +4957,7 @@ test "merge error sets" {
48594957 Because many functions in Zig return a possible error, Zig supports inferring the error set.
48604958 To infer the error set for a function, use this syntax:
48614959 </p>
4862{#code_begin|test#}
4960{#code_begin|test|inferred_error_sets#}
48634961// With an inferred error set
48644962pub fn add_inferred(comptime T: type, a: T, b: T) !T {
48654963 var answer: T = undefined;
......@@ -5173,7 +5271,7 @@ fn doAThing(optional_foo: ?*Foo) void {
51735271 {#header_open|Optional Type#}
51745272 <p>An optional is created by putting {#syntax#}?{#endsyntax#} in front of a type. You can use compile-time
51755273 reflection to access the child type of an optional:</p>
5176 {#code_begin|test#}
5274 {#code_begin|test|test_optional_type#}
51775275const expect = @import("std").testing.expect;
51785276
51795277test "optional type" {
......@@ -5200,7 +5298,7 @@ const optional_value: ?i32 = null;
52005298 {#header_open|Optional Pointers#}
52015299 <p>An optional pointer is guaranteed to be the same size as a pointer. The {#syntax#}null{#endsyntax#} of
52025300 the optional is guaranteed to be address 0.</p>
5203 {#code_begin|test#}
5301 {#code_begin|test|test_optional_pointer#}
52045302const expect = @import("std").testing.expect;
52055303
52065304test "optional pointers" {
......@@ -5232,7 +5330,7 @@ test "optional pointers" {
52325330 <p>
52335331 Type coercion occurs when one type is expected, but different type is provided:
52345332 </p>
5235 {#code_begin|test#}
5333 {#code_begin|test|type_coercion#}
52365334test "type coercion - variable declaration" {
52375335 var a: u8 = 1;
52385336 var b: u16 = a;
......@@ -5272,7 +5370,7 @@ test "type coercion - @as builtin" {
52725370 <p>
52735371 These casts are no-ops at runtime since the value representation does not change.
52745372 </p>
5275 {#code_begin|test#}
5373 {#code_begin|test|no_op_casts#}
52765374test "type coercion - const qualification" {
52775375 var a: i32 = 1;
52785376 var b: *i32 = &a;
......@@ -5284,7 +5382,7 @@ fn foo(_: *const i32) void {}
52845382 <p>
52855383 In addition, pointers coerce to const optional pointers:
52865384 </p>
5287 {#code_begin|test#}
5385 {#code_begin|test|pointer_coerce_const_optional#}
52885386const std = @import("std");
52895387const expect = std.testing.expect;
52905388const mem = std.mem;
......@@ -5301,7 +5399,7 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
53015399 {#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise
53025400 {#link|Floats#} coerce to float types which can represent every value of the old type.
53035401 </p>
5304 {#code_begin|test#}
5402 {#code_begin|test|test_integer_widening#}
53055403const std = @import("std");
53065404const expect = std.testing.expect;
53075405const mem = std.mem;
......@@ -5429,7 +5527,7 @@ test "*T to *[1]T" {
54295527 <p>
54305528 The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type.
54315529 </p>
5432 {#code_begin|test#}
5530 {#code_begin|test|test_coerce_optionals#}
54335531const std = @import("std");
54345532const expect = std.testing.expect;
54355533
......@@ -5442,7 +5540,7 @@ test "coerce to optionals" {
54425540}
54435541 {#code_end#}
54445542 <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#}
54465544const std = @import("std");
54475545const expect = std.testing.expect;
54485546
......@@ -5459,7 +5557,7 @@ test "coerce to optionals wrapped in error union" {
54595557 <p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#}
54605558 coerce to the error union type:
54615559 </p>
5462 {#code_begin|test#}
5560 {#code_begin|test|test_coerce_to_error_union#}
54635561const std = @import("std");
54645562const expect = std.testing.expect;
54655563
......@@ -5476,7 +5574,7 @@ test "coercion to error unions" {
54765574 <p>When a number is {#link|comptime#}-known to be representable in the destination type,
54775575 it may be coerced:
54785576 </p>
5479 {#code_begin|test#}
5577 {#code_begin|test|test_coerce_large_to_small#}
54805578const std = @import("std");
54815579const expect = std.testing.expect;
54825580
......@@ -5492,7 +5590,7 @@ test "coercing large integer type to smaller one when value is comptime known to
54925590 when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as
54935591 {#link|void#}:
54945592 </p>
5495 {#code_begin|test#}
5593 {#code_begin|test|test_coerce_unions_enums#}
54965594const std = @import("std");
54975595const expect = std.testing.expect;
54985596
......@@ -5525,7 +5623,7 @@ test "coercion between unions and enums" {
55255623 regardless of const.</p>
55265624 <p>TODO document the reasoning for this</p>
55275625 <p>TODO document whether vice versa should work and why</p>
5528 {#code_begin|test#}
5626 {#code_begin|test|coerce_zero_bit_types#}
55295627test "coercion of zero bit types" {
55305628 var x: void = {};
55315629 var y: *void = x;
......@@ -5715,7 +5813,7 @@ export fn entry() void {
57155813 {#syntax#}Map(Key, Value){#endsyntax#}, one can pass {#syntax#}void{#endsyntax#} for the {#syntax#}Value{#endsyntax#}
57165814 type to make it into a {#syntax#}Set{#endsyntax#}:
57175815 </p>
5718 {#code_begin|test#}
5816 {#code_begin|test|void_in_hashmap#}
57195817const std = @import("std");
57205818const expect = std.testing.expect;
57215819
......@@ -5755,7 +5853,7 @@ fn foo() i32 {
57555853}
57565854 {#code_end#}
57575855 <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#}
57595857test "void is ignored" {
57605858 returnsVoid();
57615859}
......@@ -5774,7 +5872,7 @@ fn foo() i32 {
57745872
57755873 {#header_open|Pointers to Zero Bit Types#}
57765874 <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#}
57785876const std = @import("std");
57795877const expect = std.testing.expect;
57805878
......@@ -5826,10 +5924,10 @@ test "using std namespace" {
58265924 {#code_end#}
58275925 <p>
58285926 {#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 the
5927 API of a file or package. For example, one might have <code class="file">c.zig</code> with all of the
58305928 {#link|C imports|Import from C Header File#}:
58315929 </p>
5832 <pre>{#syntax#}
5930 {#syntax_block|zig|c.zig#}
58335931pub usingnamespace @cImport({
58345932 @cInclude("epoxy/gl.h");
58355933 @cInclude("GLFW/glfw3.h");
......@@ -5837,7 +5935,7 @@ pub usingnamespace @cImport({
58375935 @cDefine("STBI_NO_STDIO", "");
58385936 @cInclude("stb_image.h");
58395937});
5840 {#endsyntax#}</pre>
5938 {#end_syntax_block#}
58415939 <p>
58425940 The above example demonstrates using {#syntax#}pub{#endsyntax#} to qualify the
58435941 {#syntax#}usingnamespace{#endsyntax#} additionally makes the imported declarations
......@@ -5923,7 +6021,7 @@ test "try to compare bools" {
59236021 value is known at compile-time. This means that we actually could make this work for the bool type
59246022 if we wanted to:
59256023 </p>
5926 {#code_begin|test#}
6024 {#code_begin|test|comptime_max_with_bool#}
59276025fn max(comptime T: type, a: T, b: T) T {
59286026 if (T == bool) {
59296027 return a or b;
......@@ -6086,7 +6184,7 @@ test "foo" {
60866184 <p>
60876185 Let's look at an example:
60886186 </p>
6089 {#code_begin|test#}
6187 {#code_begin|test|fibonacci_recursion#}
60906188const expect = @import("std").testing.expect;
60916189
60926190fn fibonacci(index: u32) u32 {
......@@ -6179,7 +6277,7 @@ test "fibonacci" {
61796277 {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to
61806278 initialize complex static data. For example:
61816279 </p>
6182 {#code_begin|test#}
6280 {#code_begin|test|N_primes#}
61836281const first_25_primes = firstNPrimes(25);
61846282const 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 {
64806578 <p>
64816579 Dissecting the syntax:
64826580 </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.
64846582// the `asm` keyword begins the expression.
64856583_ = asm
64866584// `volatile` is an optional modifier that tells Zig this
......@@ -6535,7 +6633,7 @@ volatile (
65356633// output. In this example we list $rcx and $r11 because it is known the
65366634// kernel syscall does not preserve these registers.
65376635 : "rcx", "r11"
6538);{#endsyntax#}</pre>
6636);{#end_syntax_block#}
65396637 <p>
65406638 For i386 and x86_64 targets, the syntax is AT&amp;T syntax, rather than the more
65416639 popular Intel syntax. This is due to technical constraints; assembly parsing is
......@@ -6661,7 +6759,7 @@ test "global assembly" {
66616759 return to the callsite (in the case of the first suspension),
66626760 or resumer (in the case of subsequent suspensions).
66636761 </p>
6664 {#code_begin|test#}
6762 {#code_begin|test|suspend_no_resume#}
66656763const std = @import("std");
66666764const expect = std.testing.expect;
66676765
......@@ -6688,7 +6786,7 @@ fn func() void {
66886786 {#syntax#}resume{#endsyntax#} operation on a different thread.
66896787 {#link|@frame#} provides access to the async function frame pointer.
66906788 </p>
6691 {#code_begin|test#}
6789 {#code_begin|test|async_suspend_block#}
66926790const std = @import("std");
66936791const expect = std.testing.expect;
66946792
......@@ -6726,7 +6824,7 @@ fn testSuspendBlock() void {
67266824 However, the async function can be directly resumed from the suspend block, in which case it
67276825 never returns to its resumer and continues executing.
67286826 </p>
6729 {#code_begin|test#}
6827 {#code_begin|test|resume_from_suspend#}
67306828const std = @import("std");
67316829const expect = std.testing.expect;
67326830
......@@ -6762,7 +6860,7 @@ fn testResumeFromSuspend(my_result: *i32) void {
67626860 execution would continue at the most recent {#syntax#}async{#endsyntax#} callsite or {#syntax#}resume{#endsyntax#} callsite,
67636861 and the return value of the async function would be lost.
67646862 </p>
6765 {#code_begin|test#}
6863 {#code_begin|test|async_await#}
67666864const std = @import("std");
67676865const expect = std.testing.expect;
67686866
......@@ -6806,7 +6904,7 @@ fn func() void {
68066904 does not suspend; instead it copies the
68076905 return value directly from the target function's frame.
68086906 </p>
6809 {#code_begin|test#}
6907 {#code_begin|test|async_await_sequence#}
68106908const std = @import("std");
68116909const expect = std.testing.expect;
68126910
......@@ -7084,7 +7182,7 @@ comptime {
70847182 read after {#link|await|Async and Await#} completes. Any result location provided to
70857183 {#syntax#}await{#endsyntax#} will copy the result from {#syntax#}result_ptr{#endsyntax#}.
70867184 </p>
7087 {#code_begin|test#}
7185 {#code_begin|test|async_struct_field_fn_pointer#}
70887186const std = @import("std");
70897187const expect = std.testing.expect;
70907188
......@@ -7526,7 +7624,7 @@ test "main" {
75267624 not encountered by analysis, the
75277625 program compiles successfully and the generated executable prints:
75287626 </p>
7529 {#code_begin|test#}
7627 {#code_begin|test|without_compileLog#}
75307628const print = @import("std").debug.print;
75317629
75327630const num1 = blk: {
......@@ -7758,7 +7856,7 @@ export fn @"A function name that is a complete sentence."() void {}
77587856 <pre>{#syntax#}@field(lhs: anytype, comptime field_name: []const u8) (field){#endsyntax#}</pre>
77597857 <p>Performs field access by a compile-time string. Works on both fields and declarations.
77607858 </p>
7761 {#code_begin|test#}
7859 {#code_begin|test|field_decl_access_by_string#}
77627860const std = @import("std");
77637861
77647862const Point = struct {
......@@ -7843,7 +7941,7 @@ test "decl access by string" {
78437941 This type is suitable to be used as the return type of {#link|async|Async and Await#} which
78447942 allows one to, for example, heap-allocate an async function frame:
78457943 </p>
7846 {#code_begin|test#}
7944 {#code_begin|test|heap_allocated_frame#}
78477945const std = @import("std");
78487946
78497947test "heap allocated frame" {
......@@ -7889,7 +7987,7 @@ fn func() void {
78897987 Returns whether or not a {#link|struct#}, {#link|enum#}, or {#link|union#} has a declaration
78907988 matching {#syntax#}name{#endsyntax#}.
78917989 </p>
7892 {#code_begin|test#}
7990 {#code_begin|test|hasDecl#}
78937991const std = @import("std");
78947992const expect = std.testing.expect;
78957993
......@@ -8104,7 +8202,7 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>
81048202 designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use
81058203 something like {#syntax#}@import("std").heap.WasmPageAllocator{#endsyntax#}.
81068204 </p>
8107 {#code_begin|test#}
8205 {#code_begin|test|wasmMemoryGrow#}
81088206const std = @import("std");
81098207const native_arch = @import("builtin").target.cpu.arch;
81108208const expect = std.testing.expect;
......@@ -8291,7 +8389,7 @@ test "foo" {
82918389}
82928390 {#code_end#}
82938391 <p>Now we use {#syntax#}@setEvalBranchQuota{#endsyntax#}:</p>
8294 {#code_begin|test#}
8392 {#code_begin|test|setEvalBranchQuota#}
82958393test "foo" {
82968394 comptime {
82978395 @setEvalBranchQuota(1001);
......@@ -8490,7 +8588,7 @@ test "@setRuntimeSafety" {
84908588 Produces a vector of length {#syntax#}len{#endsyntax#} where each element is the value
84918589 {#syntax#}scalar{#endsyntax#}:
84928590 </p>
8493 {#code_begin|test#}
8591 {#code_begin|test|vector_splat#}
84948592const std = @import("std");
84958593const expect = std.testing.expect;
84968594
......@@ -8524,7 +8622,7 @@ test "vector @splat" {
85248622 <li>{#syntax#}.Min{#endsyntax#}, {#syntax#}.Max{#endsyntax#},
85258623 {#syntax#}.Add{#endsyntax#}, {#syntax#}.Mul{#endsyntax#} are
85268624 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>
85288626 </ul>
85298627 <p>
85308628 Note that {#syntax#}.Add{#endsyntax#} and {#syntax#}.Mul{#endsyntax#}
......@@ -8532,7 +8630,7 @@ test "vector @splat" {
85328630 types the operation associativity is preserved, unless the float mode is
85338631 set to {#syntax#}Optimized{#endsyntax#}.
85348632 </p>
8535 {#code_begin|test#}
8633 {#code_begin|test|vector_reduce#}
85368634const std = @import("std");
85378635const expect = std.testing.expect;
85388636
......@@ -8554,7 +8652,7 @@ test "vector @reduce" {
85548652 <p>
85558653 Returns a {#syntax#}SourceLocation{#endsyntax#} struct representing the function's name and location in the source code. This must be called in a function.
85568654 </p>
8557 {#code_begin|test#}
8655 {#code_begin|test|source_location#}
85588656const std = @import("std");
85598657const expect = std.testing.expect;
85608658
......@@ -8568,7 +8666,7 @@ fn doTheTest() !void {
85688666 try expect(src.line == 9);
85698667 try expect(src.column == 17);
85708668 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"));
85728670}
85738671 {#code_end#}
85748672 {#header_close#}
......@@ -8749,7 +8847,7 @@ fn doTheTest() !void {
87498847 Returns the innermost struct, enum, or union that this function call is inside.
87508848 This can be useful for an anonymous struct that needs to refer to itself:
87518849 </p>
8752 {#code_begin|test#}
8850 {#code_begin|test|this_innermost#}
87538851const std = @import("std");
87548852const expect = std.testing.expect;
87558853
......@@ -8884,7 +8982,7 @@ test "integer truncation" {
88848982 <p>
88858983 The expressions are evaluated, however they are guaranteed to have no <em>runtime</em> side-effects:
88868984 </p>
8887 {#code_begin|test#}
8985 {#code_begin|test|no_runtime_side_effects#}
88888986const std = @import("std");
88898987const expect = std.testing.expect;
88908988
......@@ -8925,9 +9023,9 @@ fn foo(comptime T: type, ptr: *T) T {
89259023 <li>{#link|ReleaseSmall#}</li>
89269024 </ul>
89279025 <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:
89299027 </p>
8930 {#code_begin|syntax#}
9028 {#code_begin|syntax|build#}
89319029const Builder = @import("std").build.Builder;
89329030
89339031pub fn build(b: *Builder) void {
......@@ -8939,11 +9037,13 @@ pub fn build(b: *Builder) void {
89399037 <p>
89409038 This causes these options to be available:
89419039 </p>
8942 <pre><code class="shell"> -Drelease-safe=[bool] optimizations on and safety on
8943 -Drelease-fast=[bool] optimizations on and safety off
8944 -Drelease-small=[bool] size optimizations on and safety off</code></pre>
9040 <dl>
9041 <dt><kbd>-Drelease-safe=[bool]</kbd></dt><dd>Optimizations on and safety on</dd>
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>
89459045 {#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#}
89479047 <ul>
89489048 <li>Fast compilation speed</li>
89499049 <li>Safety checks enabled</li>
......@@ -8953,7 +9053,7 @@ pub fn build(b: *Builder) void {
89539053 </ul>
89549054 {#header_close#}
89559055 {#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#}
89579057 <ul>
89589058 <li>Fast runtime performance</li>
89599059 <li>Safety checks disabled</li>
......@@ -8963,7 +9063,7 @@ pub fn build(b: *Builder) void {
89639063 </ul>
89649064 {#header_close#}
89659065 {#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#}
89679067 <ul>
89689068 <li>Medium runtime performance</li>
89699069 <li>Safety checks enabled</li>
......@@ -8973,7 +9073,7 @@ pub fn build(b: *Builder) void {
89739073 </ul>
89749074 {#header_close#}
89759075 {#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#}
89779077 <ul>
89789078 <li>Medium runtime performance</li>
89799079 <li>Safety checks disabled</li>
......@@ -8986,7 +9086,7 @@ pub fn build(b: *Builder) void {
89869086 {#header_close#}
89879087
89889088 {#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>
89909090 <ul>
89919091 <li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li>
89929092 <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>
......@@ -9197,7 +9297,7 @@ pub fn main() void {
91979297 <li>{#syntax#}-%{#endsyntax#} (wraparound negation)</li>
91989298 <li>{#syntax#}*%{#endsyntax#} (wraparound multiplication)</li>
91999299 </ul>
9200 {#code_begin|test#}
9300 {#code_begin|test|wraparound_semantics#}
92019301const std = @import("std");
92029302const expect = std.testing.expect;
92039303const minInt = std.math.minInt;
......@@ -9935,14 +10035,14 @@ const separator = if (builtin.os.tag == builtin.Os.windows) '\\' else '/';
993510035 <li>Custom tasks.</li>
993610036 </ul>
993710037 <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>
993910039 to see a command-line usage help menu. This will include project-specific
994010040 options that were declared in the build.zig script.
994110041 </p>
994210042
994310043 {#header_open|Building an Executable#}
9944 <p>This <code>build.zig</code> file is automatically generated
9945 by <code>zig init-exe</code>.</p>
10044 <p>This <code class="file">build.zig</code> file is automatically generated
10045 by <kbd>zig init-exe</kbd>.</p>
994610046 {#code_begin|syntax|build#}
994710047const Builder = @import("std").build.Builder;
994810048
......@@ -9975,8 +10075,8 @@ pub fn build(b: *Builder) void {
997510075 {#header_close#}
997610076
997710077 {#header_open|Building a Library#}
9978 <p>This <code>build.zig</code> file is automatically generated
9979 by <code>zig init-lib</code>.</p>
10078 <p>This <code class="file">build.zig</code> file is automatically generated
10079 by <kbd>zig init-lib</kbd>.</p>
998010080 {#code_begin|syntax|build#}
998110081const Builder = @import("std").build.Builder;
998210082
......@@ -10035,7 +10135,7 @@ lib.addCSourceFile("src/lib.c", &[_][]const u8{
1003510135 {#header_open|Import from C Header File#}
1003610136 <p>
1003710137 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:
1003910139 </p>
1004010140 {#code_begin|exe#}
1004110141 {#link_libc#}
......@@ -10051,7 +10151,7 @@ pub fn main() void {
1005110151 <p>
1005210152 The {#syntax#}@cImport{#endsyntax#} function takes an expression as a parameter.
1005310153 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:
1005510155 </p>
1005610156 {#code_begin|syntax#}
1005710157const builtin = @import("builtin");
......@@ -10072,66 +10172,65 @@ const c = @cImport({
1007210172 {#header_close#}
1007310173
1007410174 {#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>.
1007610176 It requires a single filename as an argument. It may also take a set of optional flags that are
1007710177 forwarded to clang. It writes the translated file to stdout.
1007810178 {#header_open|Command line flags#}
1007910179 <ul>
1008010180 <li>
10081 <code class="shell">-I</code>:
10181 <kbd>-I</kbd>:
1008210182 Specify a search directory for include files. May be used multiple times. Equivalent to
1008310183 <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;
10085 use <code>-I.</code> to include it.
10184 clang's <kbd>-I</kbd> flag</a>. The current directory is <em>not</em> included by default;
10185 use <kbd>-I.</kbd> to include it.
1008610186 </li>
1008710187 <li>
10088 <code class="shell">-D</code>: Define a preprocessor macro. Equivalent to
10188 <kbd>-D</kbd>: Define a preprocessor macro. Equivalent to
1008910189 <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>.
1009110191 </li>
1009210192 <li>
10093 <code class="shell">-cflags [flags] --</code>: Pass arbitrary additional
10193 <kbd>-cflags [flags] --</kbd>: Pass arbitrary additional
1009410194 <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>
1009610196 </li>
1009710197 <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.
1009910199 If no target is specified, the current host target will be used.
1010010200 </li>
1010110201 </ul>
1010210202 {#header_close#}
1010310203 {#header_open|Using -target and -cflags#}
1010410204 <p>
10105 <strong>Important!</strong> When translating C code with <code class="shell">zig translate-c</code>,
10106 you <strong>must</strong> use the same <code>-target</code> triple that you will use when compiling
10107 the translated code. In addition, you <strong>must</strong> ensure that the <code>-cflags</code> used,
10108 if any, match the cflags used by code on the target system. Using the incorrect <code>-target</code>
10109 or <code>-cflags</code> could result in clang or Zig parse failures, or subtle ABI incompatibilities
10205 <strong>Important!</strong> When translating C code with <kbd>zig translate-c</kbd>,
10206 you <strong>must</strong> use the same <kbd>-target</kbd> triple that you will use when compiling
10207 the translated code. In addition, you <strong>must</strong> ensure that the <kbd>-cflags</kbd> used,
10208 if any, match the cflags used by code on the target system. Using the incorrect <kbd>-target</kbd>
10209 or <kbd>-cflags</kbd> could result in clang or Zig parse failures, or subtle ABI incompatibilities
1011010210 when linking with C code.
1011110211 </p>
10112 <p class="file">varytarget.h</p>
10113 <pre><code class="c">long FOO = __LONG_MAX__;</code></pre>
10114 <pre><code class="shell">$ zig translate-c -target <strong>thumb-freestanding-gnueabihf</strong> varytarget.h|grep FOO
10115pub export var FOO: c_long = <strong>2147483647</strong>;</code></pre>
10116 <pre><code class="shell">$ zig translate-c -target <strong>x86_64-macos-gnu</strong> varytarget.h|grep FOO
10117pub export var FOO: c_long = <strong>9223372036854775807</strong>;</code></pre>
10118 <p class="file">varycflags.h</p>
10119 <pre><code class="c">enum FOO { BAR };
10120int do_something(enum FOO foo);</code></pre>
10121 <pre><code class="shell">$ zig translate-c varycflags.h|grep -B1 do_something
10122pub const enum_FOO = <strong>c_uint</strong>;
10123pub extern fn do_something(foo: enum_FOO) c_int;</code></pre>
10124 <pre><code class="shell">$ zig translate-c <strong>-cflags -fshort-enums --</strong> varycflags.h|grep -B1 do_something
10125pub const enum_FOO = <strong>u8</strong>;
10126pub extern fn do_something(foo: enum_FOO) c_int;</code></pre>
10212 {#syntax_block|c|varytarget.h#}long FOO = __LONG_MAX__;{#end_syntax_block#}
10213 {#shell_samp#}$ zig translate-c -target <em>thumb-freestanding-gnueabihf</em> varytarget.h|grep FOO
10214pub export var FOO: c_long = <em>2147483647</em>;
10215$ zig translate-c -target <em>x86_64-macos-gnu</em> varytarget.h|grep FOO
10216pub export var FOO: c_long = <em>9223372036854775807</em>;{#end_shell_samp#}
10217 {#syntax_block|c|varycflags.h#}enum FOO { BAR };
10218int do_something(enum FOO foo);
10219 {#end_syntax_block#}
10220 {#shell_samp#}$ zig translate-c varycflags.h|grep -B1 do_something
10221pub const enum_FOO = <em>c_uint</em>;
10222pub extern fn do_something(foo: enum_FOO) c_int;
10223$ zig translate-c <em>-cflags -fshort-enums --</em> varycflags.h|grep -B1 do_something
10224pub const enum_FOO = <em>u8</em>;
10225pub extern fn do_something(foo: enum_FOO) c_int;{#end_shell_samp#}
1012710226 {#header_close#}
1012810227 {#header_open|@cImport vs translate-c#}
10129 <p>{#syntax#}@cImport{#endsyntax#} and <code class="shell">zig translate-c</code> use the same underlying
10228 <p>{#syntax#}@cImport{#endsyntax#} and <kbd>zig translate-c</kbd> use the same underlying
1013010229 C translation functionality, so on a technical level they are equivalent. In practice,
1013110230 {#syntax#}@cImport{#endsyntax#} is useful as a way to quickly and easily access numeric constants, typedefs,
1013210231 and record types without needing any extra setup. If you need to pass {#link|cflags|Using -target and -cflags#}
1013310232 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 editing
10233 <kbd>zig translate-c</kbd> and save the results to a file. Common reasons for editing
1013510234 the generated code include: changing {#syntax#}anytype{#endsyntax#} parameters in function-like macros to more
1013610235 specific types; changing {#syntax#}[*c]T{#endsyntax#} pointers to {#syntax#}[*]T{#endsyntax#} or
1013710236 {#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>
1014210241 {#header_close#}
1014310242 {#header_open|C Translation Caching#}
1014410243 <p>
10145 The C translation feature (whether used via <code class="shell">zig translate-c</code> or
10244 The C translation feature (whether used via <kbd>zig translate-c</kbd> or
1014610245 {#syntax#}@cImport{#endsyntax#}) integrates with the Zig caching system. Subsequent runs with
1014710246 the same source file, target, and cflags will use the cache instead of repeatedly translating
1014810247 the same code.
1014910248 </p>
1015010249 <p>
1015110250 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:
1015310252 </p>
1015410253 {#code_begin|exe|verbose#}
1015510254 {#link_libc#}
......@@ -10163,10 +10262,10 @@ pub fn main() void {
1016310262}
1016410263 {#code_end#}
1016510264 <p>
10166 <code class="shell">cimport.h</code> contains the file to translate (constructed from calls to
10265 <code class="file">cimport.h</code> contains the file to translate (constructed from calls to
1016710266 {#syntax#}@cInclude{#endsyntax#}, {#syntax#}@cDefine{#endsyntax#}, and {#syntax#}@cUndef{#endsyntax#}),
10168 <code class="shell">cimport.h.d</code> is the list of file dependencies, and
10169 <code class="shell">cimport.zig</code> contains the translated output.
10267 <code class="file">cimport.h.d</code> is the list of file dependencies, and
10268 <code class="file">cimport.zig</code> contains the translated output.
1017010269 </p>
1017110270 {#see_also|Import from C Header File|C Translation CLI|@cInclude|@cImport#}
1017210271 {#header_close#}
......@@ -10206,22 +10305,22 @@ pub fn main() void {
1020610305 Zig.
1020710306 </p>
1020810307 <p>Consider the following example:</p>
10209 <p class="file">macro.c</p>
10210 <pre><code class="c">#define MAKELOCAL(NAME, INIT) int NAME = INIT
10308 {#syntax_block|c|macro.c#}#define MAKELOCAL(NAME, INIT) int NAME = INIT
1021110309int foo(void) {
1021210310 MAKELOCAL(a, 1);
1021310311 MAKELOCAL(b, 2);
1021410312 return a + b;
10215}</code></pre>
10216<pre><code class="shell">$ zig translate-c macro.c > macro.zig
10217</code></pre>
10218 <p class="file">macro.zig</p>
10219 <pre>{#syntax#}pub export fn foo() c_int {
10313}
10314 {#end_syntax_block#}
10315 {#shell_samp#}$ zig translate-c macro.c > macro.zig{#end_shell_samp#}
10316 {#code_begin|syntax|macro#}
10317pub export fn foo() c_int {
1022010318 var a: c_int = 1;
1022110319 var b: c_int = 2;
1022210320 return a + b;
1022310321}
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#}
1022510324 <p>Note that {#syntax#}foo{#endsyntax#} was translated correctly despite using a non-translateable
1022610325 macro. {#syntax#}MAKELOCAL{#endsyntax#} was demoted to {#syntax#}@compileError{#endsyntax#} since
1022710326 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
1027210371 to call into. The {#syntax#}export{#endsyntax#} keyword in front of functions, variables, and types causes them to
1027310372 be part of the library API:
1027410373 </p>
10275 <p class="file">mathtest.zig</p>
10276 {#code_begin|syntax#}
10374 {#code_begin|syntax|mathtest#}
1027710375export fn add(a: i32, b: i32) i32 {
1027810376 return a + b;
1027910377}
1028010378 {#code_end#}
1028110379 <p>To make a static library:</p>
10282 <pre><code class="shell">$ zig build-lib mathtest.zig
10283</code></pre>
10380 {#shell_samp#}$ zig build-lib mathtest.zig{#end_shell_samp#}
1028410381 <p>To make a shared library:</p>
10285 <pre><code class="shell">$ zig build-lib mathtest.zig -dynamic
10286</code></pre>
10382 {#shell_samp#}$ zig build-lib mathtest.zig -dynamic{#end_shell_samp#}
1028710383 <p>Here is an example with the {#link|Zig Build System#}:</p>
10288 <p class="file">test.c</p>
10289 <pre><code class="cpp">// This header is generated by zig from mathtest.zig
10384 {#syntax_block|c|test.c#}// This header is generated by zig from mathtest.zig
1029010385#include "mathtest.h"
10291#include &lt;stdio.h&gt;
10386#include <stdio.h>
1029210387
1029310388int main(int argc, char **argv) {
1029410389 int32_t result = add(42, 1337);
1029510390 printf("%d\n", result);
1029610391 return 0;
10297}</code></pre>
10298 <p class="file">build.zig</p>
10299 {#code_begin|syntax#}
10392}
10393 {#end_syntax_block#}
10394 {#code_begin|syntax|build#}
1030010395const Builder = @import("std").build.Builder;
1030110396
1030210397pub fn build(b: *Builder) void {
......@@ -10315,18 +10410,15 @@ pub fn build(b: *Builder) void {
1031510410 test_step.dependOn(&run_cmd.step);
1031610411}
1031710412 {#code_end#}
10318 <p class="file">terminal</p>
10319 <pre><code class="shell">$ zig build test
103201379
10321</code></pre>
10413 {#shell_samp#}$ zig build test
104141379{#end_shell_samp#}
1032210415 {#see_also|export#}
1032310416 {#header_close#}
1032410417 {#header_open|Mixing Object Files#}
1032510418 <p>
1032610419 You can mix Zig object files with any other object files that respect the C ABI. Example:
1032710420 </p>
10328 <p class="file">base64.zig</p>
10329 {#code_begin|syntax#}
10421 {#code_begin|syntax|base64#}
1033010422const base64 = @import("std").base64;
1033110423
1033210424export fn decode_base_64(
......@@ -10343,12 +10435,11 @@ export fn decode_base_64(
1034310435 return decoded_size;
1034410436}
1034510437 {#code_end#}
10346 <p class="file">test.c</p>
10347 <pre><code class="cpp">// This header is generated by zig from base64.zig
10438 {#syntax_block|c|test.c#}// This header is generated by zig from base64.zig
1034810439#include "base64.h"
1034910440
10350#include &lt;string.h&gt;
10351#include &lt;stdio.h&gt;
10441#include <string.h>
10442#include <stdio.h>
1035210443
1035310444int main(int argc, char **argv) {
1035410445 const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz";
......@@ -10359,9 +10450,9 @@ int main(int argc, char **argv) {
1035910450 puts(buf);
1036010451
1036110452 return 0;
10362}</code></pre>
10363 <p class="file">build.zig</p>
10364 {#code_begin|syntax#}
10453}
10454 {#end_syntax_block#}
10455 {#code_begin|syntax|build#}
1036510456const Builder = @import("std").build.Builder;
1036610457
1036710458pub fn build(b: *Builder) void {
......@@ -10374,10 +10465,9 @@ pub fn build(b: *Builder) void {
1037410465 exe.install();
1037510466}
1037610467 {#code_end#}
10377 <p class="file">terminal</p>
10378 <pre><code class="shell">$ zig build
10468 {#shell_samp#}$ zig build
1037910469$ ./zig-out/bin/test
10380all your base are belong to us</code></pre>
10470all your base are belong to us{#end_shell_samp#}
1038110471 {#see_also|Targets|Zig Build System#}
1038210472 {#header_close#}
1038310473 {#header_close#}
......@@ -10395,9 +10485,7 @@ export fn add(a: i32, b: i32) void {
1039510485 print(a + b);
1039610486}
1039710487 {#code_end#}
10398 {#header_close#}
10399 <p class="file">test.js</p>
10400 <pre><code>const fs = require('fs');
10488 {#syntax_block|javascript|test.js#}const fs = require('fs');
1040110489const source = fs.readFileSync("./math.wasm");
1040210490const typedArray = new Uint8Array(source);
1040310491
......@@ -10407,9 +10495,10 @@ WebAssembly.instantiate(typedArray, {
1040710495 }}).then(result =&gt; {
1040810496 const add = result.instance.exports.add;
1040910497 add(1, 2);
10410});</code></pre>
10411 <pre><code>$ node test.js
10412The result is 3</code></pre>
10498});{#end_syntax_block#}
10499 {#shell_samp#}$ node test.js
10500The result is 3{#end_shell_samp#}
10501 {#header_close#}
1041310502 {#header_open|WASI#}
1041410503 <p>Zig's support for WebAssembly System Interface (WASI) is under active development.
1041510504 Example of using the standard library and reading command line arguments:</p>
......@@ -10428,10 +10517,10 @@ pub fn main() !void {
1042810517 }
1042910518}
1043010519 {#code_end#}
10431 <pre><code>$ wasmtime args.wasm 123 hello
10520 {#shell_samp#}$ wasmtime args.wasm 123 hello
10432105210: args.wasm
10433105221: 123
104342: hello</code></pre>
105232: hello{#end_shell_samp#}
1043510524 <p>A more interesting example would be extracting the list of preopens from the runtime.
1043610525 This is now supported in the standard library via {#syntax#}std.fs.wasi.PreopenList{#endsyntax#}:</p>
1043710526 {#code_begin|exe|preopens#}
......@@ -10453,9 +10542,9 @@ pub fn main() !void {
1045310542 }
1045410543}
1045510544 {#code_end#}
10456 <pre><code>$ wasmtime --dir=. preopens.wasm
10545 {#shell_samp#}$ wasmtime --dir=. preopens.wasm
10457105460: Preopen{ .fd = 3, .type = PreopenType{ .Dir = '.' } }
10458</code></pre>
10547 {#end_shell_samp#}
1045910548 {#header_close#}
1046010549 {#header_close#}
1046110550 {#header_open|Targets#}
......@@ -10464,7 +10553,7 @@ pub fn main() !void {
1046410553 what it looks like to execute <code>zig targets</code> on a Linux x86_64
1046510554 computer:
1046610555 </p>
10467 <pre><code class="shell">$ zig targets
10556 {#shell_samp#}$ zig targets
1046810557Architectures:
1046910558 arm
1047010559 v8_4a
......@@ -10701,7 +10790,7 @@ Available libcs:
1070110790 wasm32-wasi-musl
1070210791 x86_64-linux-gnu
1070310792 x86_64-linux-gnux32
10704 x86_64-linux-musl</code></pre>
10793 x86_64-linux-musl{#end_shell_samp#}
1070510794 <p>
1070610795 The Zig Standard Library ({#syntax#}@import("std"){#endsyntax#}) has architecture, environment, and operating system
1070710796 abstractions, and thus takes additional work to support more platforms.
......@@ -10771,9 +10860,9 @@ coding style.
1077110860 <p>
1077210861 File names fall into two categories: types and namespaces. If the file
1077310862 (implicitly a struct) has top level fields, it should be named like any
10774 other struct with fields using {#syntax#}TitleCase{#endsyntax#}. Otherwise,
10775 it should use {#syntax#}snake_case{#endsyntax#}. Directory names should be
10776 {#syntax#}snake_case{#endsyntax#}.
10863 other struct with fields using <code class="file">TitleCase</code>. Otherwise,
10864 it should use <code class="file">snake_case</code>. Directory names should be
10865 <code class="file">snake_case</code>.
1077710866 </p>
1077810867 <p>
1077910868 These are general rules of thumb; if it makes sense to do something different,
......@@ -10782,7 +10871,7 @@ coding style.
1078210871 </p>
1078310872 {#header_close#}
1078410873 {#header_open|Examples#}
10785 <pre>{#syntax#}
10874 {#syntax_block|zig|style_example.zig#}
1078610875const namespace_name = @import("dir_name/file_name.zig");
1078710876const TypeName = @import("dir_name/TypeName.zig");
1078810877var global_var: i32 = undefined;
......@@ -10826,9 +10915,9 @@ const XmlParser = struct {
1082610915
1082710916// The initials BE (Big Endian) are just another word in Zig identifier names.
1082810917fn readU32Be() u32 {}
10829 {#endsyntax#}</pre>
10918 {#end_syntax_block#}
1083010919 <p>
10831 See the Zig Standard Library for more examples.
10920 See the {#link|Zig Standard Library#} for more examples.
1083210921 </p>
1083310922 {#header_close#}
1083410923 {#header_open|Doc Comment Guidance#}
......@@ -10863,7 +10952,7 @@ fn readU32Be() u32 {}
1086310952 but use of hard tabs is discouraged. See {#link|Grammar#}.
1086410953 </p>
1086510954 <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.
1086710956 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.
1086810957 </p>
1086910958 <p>
......@@ -10881,18 +10970,18 @@ fn readU32Be() u32 {}
1088110970 {#header_open|Keyword Reference#}
1088210971 <div class="table-wrapper">
1088310972 <table>
10973 <caption>Keywords</caption>
10974 <thead>
1088410975 <tr>
10885 <th>
10886 Keyword
10887 </th>
10888 <th>
10889 Description
10890 </th>
10976 <th scope="col">Keyword</th>
10977 <th scope="col">Description</th>
1089110978 </tr>
10979 </thead>
10980 <tbody>
1089210981 <tr>
10893 <td>
10982 <th scope="row">
1089410983 <pre>{#syntax#}align{#endsyntax#}</pre>
10895 </td>
10984 </th>
1089610985 <td>
1089710986 {#syntax#}align{#endsyntax#} can be used to specify the alignment of a pointer.
1089810987 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 {}
1090210991 </td>
1090310992 </tr>
1090410993 <tr>
10905 <td>
10994 <th scope="row">
1090610995 <pre>{#syntax#}allowzero{#endsyntax#}</pre>
10907 </td>
10996 </th>
1090810997 <td>
1090910998 The pointer attribute {#syntax#}allowzero{#endsyntax#} allows a pointer to have address zero.
1091010999 <ul>
......@@ -10913,9 +11002,9 @@ fn readU32Be() u32 {}
1091311002 </td>
1091411003 </tr>
1091511004 <tr>
10916 <td>
11005 <th scope="row">
1091711006 <pre>{#syntax#}and{#endsyntax#}</pre>
10918 </td>
11007 </th>
1091911008 <td>
1092011009 The boolean operator {#syntax#}and{#endsyntax#}.
1092111010 <ul>
......@@ -10924,9 +11013,9 @@ fn readU32Be() u32 {}
1092411013 </td>
1092511014 </tr>
1092611015 <tr>
10927 <td>
11016 <th scope="row">
1092811017 <pre>{#syntax#}anyframe{#endsyntax#}</pre>
10929 </td>
11018 </th>
1093011019 <td>
1093111020 {#syntax#}anyframe{#endsyntax#} can be used as a type for variables which hold pointers to function frames.
1093211021 <ul>
......@@ -10935,9 +11024,9 @@ fn readU32Be() u32 {}
1093511024 </td>
1093611025 </tr>
1093711026 <tr>
10938 <td>
11027 <th scope="row">
1093911028 <pre>{#syntax#}anytype{#endsyntax#}</pre>
10940 </td>
11029 </th>
1094111030 <td>
1094211031 Function parameters and struct fields can be declared with {#syntax#}anytype{#endsyntax#} in place of the type.
1094311032 The type will be inferred where the function is called or the struct is instantiated.
......@@ -10947,9 +11036,9 @@ fn readU32Be() u32 {}
1094711036 </td>
1094811037 </tr>
1094911038 <tr>
10950 <td>
11039 <th scope="row">
1095111040 <pre>{#syntax#}asm{#endsyntax#}</pre>
10952 </td>
11041 </th>
1095311042 <td>
1095411043 {#syntax#}asm{#endsyntax#} begins an inline assembly expression. This allows for directly controlling the machine code generated on compilation.
1095511044 <ul>
......@@ -10958,9 +11047,9 @@ fn readU32Be() u32 {}
1095811047 </td>
1095911048 </tr>
1096011049 <tr>
10961 <td>
11050 <th scope="row">
1096211051 <pre>{#syntax#}async{#endsyntax#}</pre>
10963 </td>
11052 </th>
1096411053 <td>
1096511054 {#syntax#}async{#endsyntax#} can be used before a function call to get a pointer to the function's frame when it suspends.
1096611055 <ul>
......@@ -10969,9 +11058,9 @@ fn readU32Be() u32 {}
1096911058 </td>
1097011059 </tr>
1097111060 <tr>
10972 <td>
11061 <th scope="row">
1097311062 <pre>{#syntax#}await{#endsyntax#}</pre>
10974 </td>
11063 </th>
1097511064 <td>
1097611065 {#syntax#}await{#endsyntax#} can be used to suspend the current function until the frame provided after the {#syntax#}await{#endsyntax#} completes.
1097711066 {#syntax#}await{#endsyntax#} copies the value returned from the target function's frame to the caller.
......@@ -10981,9 +11070,9 @@ fn readU32Be() u32 {}
1098111070 </td>
1098211071 </tr>
1098311072 <tr>
10984 <td>
11073 <th scope="row">
1098511074 <pre>{#syntax#}break{#endsyntax#}</pre>
10986 </td>
11075 </th>
1098711076 <td>
1098811077 {#syntax#}break{#endsyntax#} can be used with a block label to return a value from the block.
1098911078 It can also be used to exit a loop before iteration completes naturally.
......@@ -10993,9 +11082,9 @@ fn readU32Be() u32 {}
1099311082 </td>
1099411083 </tr>
1099511084 <tr>
10996 <td>
11085 <th scope="row">
1099711086 <pre>{#syntax#}catch{#endsyntax#}</pre>
10998 </td>
11087 </th>
1099911088 <td>
1100011089 {#syntax#}catch{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to an error.
1100111090 The expression after the {#syntax#}catch{#endsyntax#} can optionally capture the error value.
......@@ -11005,9 +11094,9 @@ fn readU32Be() u32 {}
1100511094 </td>
1100611095 </tr>
1100711096 <tr>
11008 <td>
11097 <th scope="row">
1100911098 <pre>{#syntax#}comptime{#endsyntax#}</pre>
11010 </td>
11099 </th>
1101111100 <td>
1101211101 {#syntax#}comptime{#endsyntax#} before a declaration can be used to label variables or function parameters as known at compile time.
1101311102 It can also be used to guarantee an expression is run at compile time.
......@@ -11017,9 +11106,9 @@ fn readU32Be() u32 {}
1101711106 </td>
1101811107 </tr>
1101911108 <tr>
11020 <td>
11109 <th scope="row">
1102111110 <pre>{#syntax#}const{#endsyntax#}</pre>
11022 </td>
11111 </th>
1102311112 <td>
1102411113 {#syntax#}const{#endsyntax#} declares a variable that can not be modified.
1102511114 Used as a pointer attribute, it denotes the value referenced by the pointer cannot be modified.
......@@ -11029,9 +11118,9 @@ fn readU32Be() u32 {}
1102911118 </td>
1103011119 </tr>
1103111120 <tr>
11032 <td>
11121 <th scope="row">
1103311122 <pre>{#syntax#}continue{#endsyntax#}</pre>
11034 </td>
11123 </th>
1103511124 <td>
1103611125 {#syntax#}continue{#endsyntax#} can be used in a loop to jump back to the beginning of the loop.
1103711126 <ul>
......@@ -11040,9 +11129,9 @@ fn readU32Be() u32 {}
1104011129 </td>
1104111130 </tr>
1104211131 <tr>
11043 <td>
11132 <th scope="row">
1104411133 <pre>{#syntax#}defer{#endsyntax#}</pre>
11045 </td>
11134 </th>
1104611135 <td>
1104711136 {#syntax#}defer{#endsyntax#} will execute an expression when control flow leaves the current block.
1104811137 <ul>
......@@ -11051,9 +11140,9 @@ fn readU32Be() u32 {}
1105111140 </td>
1105211141 </tr>
1105311142 <tr>
11054 <td>
11143 <th scope="row">
1105511144 <pre>{#syntax#}else{#endsyntax#}</pre>
11056 </td>
11145 </th>
1105711146 <td>
1105811147 {#syntax#}else{#endsyntax#} can be used to provide an alternate branch for {#syntax#}if{#endsyntax#}, {#syntax#}switch{#endsyntax#},
1105911148 {#syntax#}while{#endsyntax#}, and {#syntax#}for{#endsyntax#} expressions.
......@@ -11066,9 +11155,9 @@ fn readU32Be() u32 {}
1106611155 </td>
1106711156 </tr>
1106811157 <tr>
11069 <td>
11158 <th scope="row">
1107011159 <pre>{#syntax#}enum{#endsyntax#}</pre>
11071 </td>
11160 </th>
1107211161 <td>
1107311162 {#syntax#}enum{#endsyntax#} defines an enum type.
1107411163 <ul>
......@@ -11077,9 +11166,9 @@ fn readU32Be() u32 {}
1107711166 </td>
1107811167 </tr>
1107911168 <tr>
11080 <td>
11169 <th scope="row">
1108111170 <pre>{#syntax#}errdefer{#endsyntax#}</pre>
11082 </td>
11171 </th>
1108311172 <td>
1108411173 {#syntax#}errdefer{#endsyntax#} will execute an expression when control flow leaves the current block if the function returns an error.
1108511174 <ul>
......@@ -11088,9 +11177,9 @@ fn readU32Be() u32 {}
1108811177 </td>
1108911178 </tr>
1109011179 <tr>
11091 <td>
11180 <th scope="row">
1109211181 <pre>{#syntax#}error{#endsyntax#}</pre>
11093 </td>
11182 </th>
1109411183 <td>
1109511184 {#syntax#}error{#endsyntax#} defines an error type.
1109611185 <ul>
......@@ -11099,9 +11188,9 @@ fn readU32Be() u32 {}
1109911188 </td>
1110011189 </tr>
1110111190 <tr>
11102 <td>
11191 <th scope="row">
1110311192 <pre>{#syntax#}export{#endsyntax#}</pre>
11104 </td>
11193 </th>
1110511194 <td>
1110611195 {#syntax#}export{#endsyntax#} makes a function or variable externally visible in the generated object file.
1110711196 Exported functions default to the C calling convention.
......@@ -11111,9 +11200,9 @@ fn readU32Be() u32 {}
1111111200 </td>
1111211201 </tr>
1111311202 <tr>
11114 <td>
11203 <th scope="row">
1111511204 <pre>{#syntax#}extern{#endsyntax#}</pre>
11116 </td>
11205 </th>
1111711206 <td>
1111811207 {#syntax#}extern{#endsyntax#} can be used to declare a function or variable that will be resolved at link time, when linking statically
1111911208 or at runtime, when linking dynamically.
......@@ -11123,9 +11212,9 @@ fn readU32Be() u32 {}
1112311212 </td>
1112411213 </tr>
1112511214 <tr>
11126 <td>
11215 <th scope="row">
1112711216 <pre>{#syntax#}false{#endsyntax#}</pre>
11128 </td>
11217 </th>
1112911218 <td>
1113011219 The boolean value {#syntax#}false{#endsyntax#}.
1113111220 <ul>
......@@ -11134,9 +11223,9 @@ fn readU32Be() u32 {}
1113411223 </td>
1113511224 </tr>
1113611225 <tr>
11137 <td>
11226 <th scope="row">
1113811227 <pre>{#syntax#}fn{#endsyntax#}</pre>
11139 </td>
11228 </th>
1114011229 <td>
1114111230 {#syntax#}fn{#endsyntax#} declares a function.
1114211231 <ul>
......@@ -11145,9 +11234,9 @@ fn readU32Be() u32 {}
1114511234 </td>
1114611235 </tr>
1114711236 <tr>
11148 <td>
11237 <th scope="row">
1114911238 <pre>{#syntax#}for{#endsyntax#}</pre>
11150 </td>
11239 </th>
1115111240 <td>
1115211241 A {#syntax#}for{#endsyntax#} expression can be used to iterate over the elements of a slice, array, or tuple.
1115311242 <ul>
......@@ -11156,9 +11245,9 @@ fn readU32Be() u32 {}
1115611245 </td>
1115711246 </tr>
1115811247 <tr>
11159 <td>
11248 <th scope="row">
1116011249 <pre>{#syntax#}if{#endsyntax#}</pre>
11161 </td>
11250 </th>
1116211251 <td>
1116311252 An {#syntax#}if{#endsyntax#} expression can test boolean expressions, optional values, or error unions.
1116411253 For optional values or error unions, the if expression can capture the unwrapped value.
......@@ -11168,9 +11257,9 @@ fn readU32Be() u32 {}
1116811257 </td>
1116911258 </tr>
1117011259 <tr>
11171 <td>
11260 <th scope="row">
1117211261 <pre>{#syntax#}inline{#endsyntax#}</pre>
11173 </td>
11262 </th>
1117411263 <td>
1117511264 {#syntax#}inline{#endsyntax#} can be used to label a loop expression such that it will be unrolled at compile time.
1117611265 It can also be used to force a function to be inlined at all call sites.
......@@ -11180,9 +11269,9 @@ fn readU32Be() u32 {}
1118011269 </td>
1118111270 </tr>
1118211271 <tr>
11183 <td>
11272 <th scope="row">
1118411273 <pre>{#syntax#}noalias{#endsyntax#}</pre>
11185 </td>
11274 </th>
1118611275 <td>
1118711276 The {#syntax#}noalias{#endsyntax#} keyword.
1118811277 <ul>
......@@ -11191,9 +11280,9 @@ fn readU32Be() u32 {}
1119111280 </td>
1119211281 </tr>
1119311282 <tr>
11194 <td>
11283 <th scope="row">
1119511284 <pre>{#syntax#}nosuspend{#endsyntax#}</pre>
11196 </td>
11285 </th>
1119711286 <td>
1119811287 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.
1119911288 In particular, inside a {#syntax#}nosuspend{#endsyntax#} scope:
......@@ -11209,9 +11298,9 @@ fn readU32Be() u32 {}
1120911298 </td>
1121011299 </tr>
1121111300 <tr>
11212 <td>
11301 <th scope="row">
1121311302 <pre>{#syntax#}null{#endsyntax#}</pre>
11214 </td>
11303 </th>
1121511304 <td>
1121611305 The optional value {#syntax#}null{#endsyntax#}.
1121711306 <ul>
......@@ -11220,9 +11309,9 @@ fn readU32Be() u32 {}
1122011309 </td>
1122111310 </tr>
1122211311 <tr>
11223 <td>
11312 <th scope="row">
1122411313 <pre>{#syntax#}or{#endsyntax#}</pre>
11225 </td>
11314 </th>
1122611315 <td>
1122711316 The boolean operator {#syntax#}or{#endsyntax#}.
1122811317 <ul>
......@@ -11231,9 +11320,9 @@ fn readU32Be() u32 {}
1123111320 </td>
1123211321 </tr>
1123311322 <tr>
11234 <td>
11323 <th scope="row">
1123511324 <pre>{#syntax#}orelse{#endsyntax#}</pre>
11236 </td>
11325 </th>
1123711326 <td>
1123811327 {#syntax#}orelse{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to null.
1123911328 <ul>
......@@ -11242,9 +11331,9 @@ fn readU32Be() u32 {}
1124211331 </td>
1124311332 </tr>
1124411333 <tr>
11245 <td>
11334 <th scope="row">
1124611335 <pre>{#syntax#}packed{#endsyntax#}</pre>
11247 </td>
11336 </th>
1124811337 <td>
1124911338 The {#syntax#}packed{#endsyntax#} keyword before a struct definition changes the struct's in-memory layout
1125011339 to the guaranteed {#syntax#}packed{#endsyntax#} layout.
......@@ -11254,9 +11343,9 @@ fn readU32Be() u32 {}
1125411343 </td>
1125511344 </tr>
1125611345 <tr>
11257 <td>
11346 <th scope="row">
1125811347 <pre>{#syntax#}pub{#endsyntax#}</pre>
11259 </td>
11348 </th>
1126011349 <td>
1126111350 The {#syntax#}pub{#endsyntax#} in front of a top level declaration makes the declaration available
1126211351 to reference from a different file than the one it is declared in.
......@@ -11266,9 +11355,9 @@ fn readU32Be() u32 {}
1126611355 </td>
1126711356 </tr>
1126811357 <tr>
11269 <td>
11358 <th scope="row">
1127011359 <pre>{#syntax#}resume{#endsyntax#}</pre>
11271 </td>
11360 </th>
1127211361 <td>
1127311362 {#syntax#}resume{#endsyntax#} will continue execution of a function frame after the point the function was suspended.
1127411363 <ul>
......@@ -11277,9 +11366,9 @@ fn readU32Be() u32 {}
1127711366 </td>
1127811367 </tr>
1127911368 <tr>
11280 <td>
11369 <th scope="row">
1128111370 <pre>{#syntax#}return{#endsyntax#}</pre>
11282 </td>
11371 </th>
1128311372 <td>
1128411373 {#syntax#}return{#endsyntax#} exits a function with a value.
1128511374 <ul>
......@@ -11288,9 +11377,9 @@ fn readU32Be() u32 {}
1128811377 </td>
1128911378 </tr>
1129011379 <tr>
11291 <td>
11380 <th scope="row">
1129211381 <pre>{#syntax#}linksection{#endsyntax#}</pre>
11293 </td>
11382 </th>
1129411383 <td>
1129511384 The {#syntax#}linksection{#endsyntax#} keyword.
1129611385 <ul>
......@@ -11299,9 +11388,9 @@ fn readU32Be() u32 {}
1129911388 </td>
1130011389 </tr>
1130111390 <tr>
11302 <td>
11391 <th scope="row">
1130311392 <pre>{#syntax#}struct{#endsyntax#}</pre>
11304 </td>
11393 </th>
1130511394 <td>
1130611395 {#syntax#}struct{#endsyntax#} defines a struct.
1130711396 <ul>
......@@ -11310,9 +11399,9 @@ fn readU32Be() u32 {}
1131011399 </td>
1131111400 </tr>
1131211401 <tr>
11313 <td>
11402 <th scope="row">
1131411403 <pre>{#syntax#}suspend{#endsyntax#}</pre>
11315 </td>
11404 </th>
1131611405 <td>
1131711406 {#syntax#}suspend{#endsyntax#} will cause control flow to return to the call site or resumer of the function.
1131811407 {#syntax#}suspend{#endsyntax#} can also be used before a block within a function,
......@@ -11323,9 +11412,9 @@ fn readU32Be() u32 {}
1132311412 </td>
1132411413 </tr>
1132511414 <tr>
11326 <td>
11415 <th scope="row">
1132711416 <pre>{#syntax#}switch{#endsyntax#}</pre>
11328 </td>
11417 </th>
1132911418 <td>
1133011419 A {#syntax#}switch{#endsyntax#} expression can be used to test values of a common type.
1133111420 {#syntax#}switch{#endsyntax#} cases can capture field values of a {#link|Tagged union#}.
......@@ -11335,9 +11424,9 @@ fn readU32Be() u32 {}
1133511424 </td>
1133611425 </tr>
1133711426 <tr>
11338 <td>
11427 <th scope="row">
1133911428 <pre>{#syntax#}test{#endsyntax#}</pre>
11340 </td>
11429 </th>
1134111430 <td>
1134211431 The {#syntax#}test{#endsyntax#} keyword can be used to denote a top-level block of code
1134311432 used to make sure behavior meets expectations.
......@@ -11347,9 +11436,9 @@ fn readU32Be() u32 {}
1134711436 </td>
1134811437 </tr>
1134911438 <tr>
11350 <td>
11439 <th scope="row">
1135111440 <pre>{#syntax#}threadlocal{#endsyntax#}</pre>
11352 </td>
11441 </th>
1135311442 <td>
1135411443 {#syntax#}threadlocal{#endsyntax#} can be used to specify a variable as thread-local.
1135511444 <ul>
......@@ -11358,9 +11447,9 @@ fn readU32Be() u32 {}
1135811447 </td>
1135911448 </tr>
1136011449 <tr>
11361 <td>
11450 <th scope="row">
1136211451 <pre>{#syntax#}true{#endsyntax#}</pre>
11363 </td>
11452 </th>
1136411453 <td>
1136511454 The boolean value {#syntax#}true{#endsyntax#}.
1136611455 <ul>
......@@ -11369,9 +11458,9 @@ fn readU32Be() u32 {}
1136911458 </td>
1137011459 </tr>
1137111460 <tr>
11372 <td>
11461 <th scope="row">
1137311462 <pre>{#syntax#}try{#endsyntax#}</pre>
11374 </td>
11463 </th>
1137511464 <td>
1137611465 {#syntax#}try{#endsyntax#} evaluates an error union expression.
1137711466 If it is an error, it returns from the current function with the same error.
......@@ -11382,9 +11471,9 @@ fn readU32Be() u32 {}
1138211471 </td>
1138311472 </tr>
1138411473 <tr>
11385 <td>
11474 <th scope="row">
1138611475 <pre>{#syntax#}undefined{#endsyntax#}</pre>
11387 </td>
11476 </th>
1138811477 <td>
1138911478 {#syntax#}undefined{#endsyntax#} can be used to leave a value uninitialized.
1139011479 <ul>
......@@ -11393,9 +11482,9 @@ fn readU32Be() u32 {}
1139311482 </td>
1139411483 </tr>
1139511484 <tr>
11396 <td>
11485 <th scope="row">
1139711486 <pre>{#syntax#}union{#endsyntax#}</pre>
11398 </td>
11487 </th>
1139911488 <td>
1140011489 {#syntax#}union{#endsyntax#} defines a union.
1140111490 <ul>
......@@ -11404,23 +11493,23 @@ fn readU32Be() u32 {}
1140411493 </td>
1140511494 </tr>
1140611495 <tr>
11407 <td>
11496 <th scope="row">
1140811497 <pre>{#syntax#}unreachable{#endsyntax#}</pre>
11409 </td>
11498 </th>
1141011499 <td>
1141111500 {#syntax#}unreachable{#endsyntax#} can be used to assert that control flow will never happen upon a particular location.
1141211501 Depending on the build mode, {#syntax#}unreachable{#endsyntax#} may emit a panic.
1141311502 <ul>
11414 <li>Emits a panic in {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, or when using <code>zig test</code>.</li>
11415 <li>Does not emit a panic in {#syntax#}ReleaseFast{#endsyntax#} mode, unless <code>zig test</code> is being used.</li>
11503 <li>Emits a panic in {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, or when using <kbd>zig test</kbd>.</li>
11504 <li>Does not emit a panic in {#syntax#}ReleaseFast{#endsyntax#} mode, unless <kbd>zig test</kbd> is being used.</li>
1141611505 <li>See also {#link|unreachable#}</li>
1141711506 </ul>
1141811507 </td>
1141911508 </tr>
1142011509 <tr>
11421 <td>
11510 <th scope="row">
1142211511 <pre>{#syntax#}usingnamespace{#endsyntax#}</pre>
11423 </td>
11512 </th>
1142411513 <td>
1142511514 {#syntax#}usingnamespace{#endsyntax#} is a top-level declaration that imports all the public declarations of the operand,
1142611515 which must be a struct, union, or enum, into the current scope.
......@@ -11430,9 +11519,9 @@ fn readU32Be() u32 {}
1143011519 </td>
1143111520 </tr>
1143211521 <tr>
11433 <td>
11522 <th scope="row">
1143411523 <pre>{#syntax#}var{#endsyntax#}</pre>
11435 </td>
11524 </th>
1143611525 <td>
1143711526 {#syntax#}var{#endsyntax#} declares a variable that may be modified.
1143811527 <ul>
......@@ -11441,9 +11530,9 @@ fn readU32Be() u32 {}
1144111530 </td>
1144211531 </tr>
1144311532 <tr>
11444 <td>
11533 <th scope="row">
1144511534 <pre>{#syntax#}volatile{#endsyntax#}</pre>
11446 </td>
11535 </th>
1144711536 <td>
1144811537 {#syntax#}volatile{#endsyntax#} can be used to denote loads or stores of a pointer have side effects.
1144911538 It can also modify an inline assembly expression to denote it has side effects.
......@@ -11453,9 +11542,9 @@ fn readU32Be() u32 {}
1145311542 </td>
1145411543 </tr>
1145511544 <tr>
11456 <td>
11545 <th scope="row">
1145711546 <pre>{#syntax#}while{#endsyntax#}</pre>
11458 </td>
11547 </th>
1145911548 <td>
1146011549 A {#syntax#}while{#endsyntax#} expression can be used to repeatedly test a boolean, optional, or error union expression,
1146111550 and cease looping when that expression evaluates to false, null, or an error, respectively.
......@@ -11464,6 +11553,7 @@ fn readU32Be() u32 {}
1146411553 </ul>
1146511554 </td>
1146611555 </tr>
11556 </tbody>
1146711557 </table>
1146811558 </div>
1146911559 {#header_close#}
......@@ -12034,7 +12124,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_allowzero / KEYWORD_and / KEYWORD_anyframe
1203412124 <li>Together we serve the users.</li>
1203512125 </ul>
1203612126 {#header_close#}
12037 </div></div>
12127 </main></div>
1203812128 </div>
1203912129 </body>
1204012130</html>