authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2023-07-14 16:27:09+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-07-14 16:27:09+02:00
loga187141056687231c7fd2c333280e6fc20062d11
tree6ebfe705527d02500129628d3998cc0d9310fa16
parent3022c525ec87c391842ec339916037e12b3a7b5c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Autodoc tokenizer (#16409)

* autodoc: init work to refactor exprName * autodoc: Implement more expressions in exprName refactor * autodoc: more work * autodoc: More exprName to ex refactoring * autodoc: Remove whitespace flag from renderer; Add pre tags in value and variable drawing in renderContainer * autodoc: add inline styling to pre blocks * autodoc: move renderer code to main.js * autodoc: More exprName to ex refactoring; Fn signatures rendered with new code * autodoc: Fix function rendering. Add more things to ex * autodoc: nuke exprName --------- Co-authored-by: Krzysztof Wolicki <der.teufel.mail@gmail.com>

4 files changed, 1376 insertions(+), 1542 deletions(-)

lib/docs/index.html+34-10
......@@ -297,6 +297,13 @@
297297 overflow-x: auto;
298298 }
299299
300 .docs pre.inline {
301 background-color: var(--bg-color);
302 padding: 0;
303 display: inline;
304 }
305
306
300307 .docs code {
301308 font-family: var(--mono);
302309 font-size: 1em;
......@@ -685,15 +692,23 @@
685692 </style>
686693
687694 <style>
688 pre{
695 pre {
689696 --zig-keyword: #333;
690 --zig-identifier: 'black';
697 --zig-builtin: #0086b3;
698 --zig-identifier: 'black';
699 --zig-string-literal: #d14;
700 --zig-type: #458;
701 --zig-fn: #900;
691702 }
692703
693704 @media (prefers-color-scheme: dark) {
694705 pre {
695 --zig-keyword: 'white';
696 --zig-identifier: 'purple';
706 --zig-keyword: #eee;
707 --zig-builtin: #ff894c;
708 --zig-identifier: 'purple';
709 --zig-string-literal: #2e5;
710 --zig-type: #68f;
711 --zig-fn: #e33;
697712 }
698713 }
699714
......@@ -748,7 +763,7 @@
748763 .zig_keyword_anytype,
749764 .zig_keyword_fn
750765 {
751 color: #333;
766 color: var(--zig-keyword);
752767 font-weight: bold;
753768 }
754769
......@@ -757,12 +772,12 @@
757772 .zig_multiline_string_literal_line,
758773 .zig_char_literal
759774 {
760 color: #d14;
775 color: var(--zig-string-literal);
761776 }
762777
763778 .zig_builtin
764779 {
765 color: #0086b3;
780 color: var(--zig-builtin);
766781 }
767782
768783 .zig_doc_comment,
......@@ -772,15 +787,24 @@
772787 }
773788
774789 .zig_identifier {
775 color: white;
790 color: var(--zig-identifier);
776791 font-weight: bold;
777792 }
778793
779 .zig_number_literal {
780 color: #008080;
794 .zig_number_literal,
795 .zig_special {
796 color: #ff8080;
781797 }
782798
799 .zig_type {
800 color: var(--zig-type);
801 font-weight: bold;
802 }
783803
804 .zig_fn {
805 color: var(--zig-fn);
806 font-weight: bold;
807 }
784808
785809 </style>
786810 </head>
lib/docs/main.js+1110-1336
......@@ -7,7 +7,7 @@ const NAV_MODES = {
77 GUIDES: "#G;",
88};
99
10(function () {
10(function() {
1111 const domBanner = document.getElementById("banner");
1212 const domMain = document.getElementById("main");
1313 const domStatus = document.getElementById("status");
......@@ -59,7 +59,7 @@ const NAV_MODES = {
5959 const domDocs = document.getElementById("docs");
6060 const domGuidesSection = document.getElementById("guides");
6161 const domActiveGuide = document.getElementById("activeGuide");
62
62
6363 const domListSearchResults = document.getElementById("listSearchResults");
6464 const domSectSearchNoResults = document.getElementById("sectSearchNoResults");
6565 const domSectInfo = document.getElementById("sectInfo");
......@@ -133,7 +133,7 @@ const NAV_MODES = {
133133 // map of decl index to list of comptime fn calls
134134 // let nodesToCallsMap = indexNodesToCalls();
135135
136 let guidesSearchIndex = {};
136 let guidesSearchIndex = {};
137137 window.guideSearch = guidesSearchIndex;
138138 parseGuides();
139139
......@@ -248,7 +248,7 @@ const NAV_MODES = {
248248 } else if (type.kind === typeKinds.Union) {
249249 name = "union";
250250 } else {
251 console.log("TODO: unhalndled case in typeShortName");
251 console.log("TODO: unhandled case in typeShortName");
252252 return null;
253253 }
254254
......@@ -313,8 +313,8 @@ const NAV_MODES = {
313313
314314 function resolveGenericRet(genericFunc) {
315315 if (genericFunc.generic_ret == null) return null;
316 let result = resolveValue({expr: genericFunc.generic_ret});
317
316 let result = resolveValue({ expr: genericFunc.generic_ret });
317
318318 let i = 0;
319319 while (true) {
320320 i += 1;
......@@ -437,32 +437,32 @@ const NAV_MODES = {
437437 const section_list = zigAnalysis.guide_sections;
438438 resizeDomList(domGuidesList, section_list.length, '<div><h2><span></span></h2><ul class="modules"></ul></div>');
439439 for (let j = 0; j < section_list.length; j += 1) {
440 const section = section_list[j];
441 const domSectionName = domGuidesList.children[j].children[0].children[0];
442 const domGuides = domGuidesList.children[j].children[1];
443 domSectionName.textContent = section.name;
444 resizeDomList(domGuides, section.guides.length, '<li><a href="#"></a></li>');
445 for (let i = 0; i < section.guides.length; i += 1) {
446 const guide = section.guides[i];
447 let liDom = domGuides.children[i];
448 let aDom = liDom.children[0];
449 aDom.textContent = guide.title;
450 aDom.setAttribute("href", NAV_MODES.GUIDES + guide.name);
451 if (guide.name === curNav.activeGuide) {
452 aDom.classList.add("active");
453 } else {
454 aDom.classList.remove("active");
455 }
440 const section = section_list[j];
441 const domSectionName = domGuidesList.children[j].children[0].children[0];
442 const domGuides = domGuidesList.children[j].children[1];
443 domSectionName.textContent = section.name;
444 resizeDomList(domGuides, section.guides.length, '<li><a href="#"></a></li>');
445 for (let i = 0; i < section.guides.length; i += 1) {
446 const guide = section.guides[i];
447 let liDom = domGuides.children[i];
448 let aDom = liDom.children[0];
449 aDom.textContent = guide.title;
450 aDom.setAttribute("href", NAV_MODES.GUIDES + guide.name);
451 if (guide.name === curNav.activeGuide) {
452 aDom.classList.add("active");
453 } else {
454 aDom.classList.remove("active");
456455 }
456 }
457457 }
458
458
459459 if (section_list.length > 0) {
460460 domGuidesMenu.classList.remove("hidden");
461461 }
462462
463
463
464464 if (curNavSearch !== "") {
465 return renderSearchGuides();
465 return renderSearchGuides();
466466 }
467467
468468 // main content
......@@ -476,8 +476,8 @@ const NAV_MODES = {
476476 break outer;
477477 }
478478 }
479 }
480
479 }
480
481481 if (activeGuide == undefined) {
482482 const root_file_idx = zigAnalysis.modules[zigAnalysis.rootMod].file;
483483 const root_file_name = getFile(root_file_idx).name;
......@@ -564,7 +564,7 @@ Happy writing!
564564 renderModList();
565565
566566 if (curNavSearch !== "") {
567 return renderSearchAPI();
567 return renderSearchAPI();
568568 }
569569
570570 let rootMod = zigAnalysis.modules[zigAnalysis.rootMod];
......@@ -660,7 +660,8 @@ Happy writing!
660660 if (!decl.decltest) return;
661661 const astNode = getAstNode(decl.decltest);
662662 domSectDocTests.classList.remove("hidden");
663 domDocTestsCode.innerHTML = generate_html_for_src(astNode.code);
663 domDocTestsCode.innerHTML = renderTokens(
664 DecoratedTokenizer(astNode.code, decl));
664665 }
665666
666667 function renderUnknownDecl(decl) {
......@@ -707,11 +708,7 @@ Happy writing!
707708 console.assert("type" in value.expr);
708709 let typeObj = getType(value.expr.type);
709710
710 domFnProtoCode.innerHTML = exprName(value.expr, {
711 wantHtml: true,
712 wantLink: true,
713 fnDecl,
714 });
711 domFnProtoCode.innerHTML = renderTokens(ex(value.expr, { fnDecl: fnDecl }));
715712
716713 domFnSourceLink.innerHTML = "[<a target=\"_blank\" href=\"" + sourceFileLink(fnDecl) + "\">src</a>]";
717714
......@@ -840,15 +837,21 @@ Happy writing!
840837
841838 let value = typeObj.params[i];
842839 let preClass = docsNonEmpty ? ' class="fieldHasDocs"' : "";
843 let html = "<pre" + preClass + ">" + escapeHtml(fieldNode.name) + ": ";
844 if (isVarArgs && i === typeObj.params.length - 1) {
845 html += "...";
846 } else {
847 let name = exprName(value, { wantHtml: false, wantLink: false });
848 html += '<span class="tok-kw">' + name + "</span>";
849 }
840 let html = "<pre" + preClass + ">" + renderTokens((function*() {
841 yield Tok.identifier(fieldNode.name);
842 yield Tok.colon;
843 yield Tok.space;
844 if (isVarArgs && i === typeObj.params.length - 1) {
845 yield Tok.period;
846 yield Tok.period;
847 yield Tok.period;
848 } else {
849 yield* ex(value, {});
850 }
851 yield Tok.comma;
852 }()));
850853
851 html += ",</pre>";
854 html += "</pre>";
852855
853856 if (docsNonEmpty) {
854857 html += '<div class="fieldDocs">' + markdown(docs) + "</div>";
......@@ -932,7 +935,7 @@ Happy writing!
932935 domSectMainMod.classList.remove("hidden");
933936 }
934937
935 list.sort(function (a, b) {
938 list.sort(function(a, b) {
936939 return operatorCompare(a.name.toLowerCase(), b.name.toLowerCase());
937940 });
938941
......@@ -1054,823 +1057,578 @@ Happy writing!
10541057 return walkResultTypeRef(resolved);
10551058 }
10561059
1057 function exprName(expr, opts) {
1058 switch (Object.keys(expr)[0]) {
1059 default:
1060 throw "this expression is not implemented yet";
1061 case "bool": {
1062 if (expr.bool) {
1063 return "true";
1060 function* DecoratedTokenizer(src, context) {
1061 let tok_it = Tokenizer(src);
1062 for (let t of tok_it) {
1063 if (t.tag == Tag.identifier) {
1064 const link = detectDeclPath(t.src, context);
1065 if (link) {
1066 t.link = link;
10641067 }
1065 return "false";
1066 }
1067 case "&": {
1068 return "&" + exprName(zigAnalysis.exprs[expr["&"]], opts);
10691068 }
1070 case "compileError": {
1071 let compileError = expr.compileError;
1072 return "@compileError(" + exprName(zigAnalysis.exprs[compileError], opts) + ")";
1073 }
1074 case "enumLiteral": {
1075 let literal = expr.enumLiteral;
1076 return "." + literal;
1077 }
1078 case "void": {
1079 return "void";
1069
1070 yield t;
1071 }
1072 }
1073
1074
1075 function renderSingleToken(t) {
1076
1077 if (t.tag == Tag.whitespace) {
1078 return t.src;
1079 }
1080
1081 let src = t.src;
1082 // if (t.tag == Tag.identifier) {
1083 // src = escapeHtml(src);
1084 // }
1085 let result = "";
1086 if (t.tag == Tag.identifier && isSimpleType(t.src)) {
1087 result = `<span class="zig_type">${src}</span>`;
1088 } else if (t.tag == Tag.identifier && isSpecialIndentifier(t.src)) {
1089 result = `<span class="zig_special">${src}</span>`;
1090 } else if (t.tag == Tag.identifier && t.fnDecl) {
1091 result = `<span class="zig_fn">${src}</span>`;
1092 } else {
1093 result = `<span class="zig_${t.tag}">${src}</span>`;
1094 }
1095
1096 if (t.link) {
1097 result = `<a href="${t.link}">` + result + "</a>";
1098 }
1099
1100 return result;
1101 }
1102
1103 function renderTokens(tok_it) {
1104 var html = [];
1105
1106 const max_iter = 100000;
1107 let i = 0;
1108 for (const t of tok_it) {
1109 i += 1;
1110 if (i > max_iter)
1111 throw "too many iterations";
1112
1113 if (t.tag == Tag.eof)
1114 break;
1115
1116 html.push(renderSingleToken(t));
1117 }
1118
1119 return html.join("");
1120 }
1121
1122 function* ex(expr, opts) {
1123 switch (Object.keys(expr)[0]) {
1124 default:
1125 throw "this expression is not implemented yet: " + Object.keys(expr)[0];
1126 case "comptimeExpr": {
1127 const src = zigAnalysis.comptimeExprs[expr.comptimeExpr].code;
1128 yield* DecoratedTokenizer(src);
1129 return;
10801130 }
1081 case "unreachable": {
1082 return "unreachable";
1131 case "declName": {
1132 yield { src: expr.declName, tag: Tag.identifier };
1133 return;
10831134 }
1084 case "slice": {
1085 let payloadHtml = "";
1086 const lhsExpr = zigAnalysis.exprs[expr.slice.lhs];
1087 const startExpr = zigAnalysis.exprs[expr.slice.start];
1088 let decl = exprName(lhsExpr, opts);
1089 let start = exprName(startExpr, opts);
1090 let end = "";
1091 let sentinel = "";
1092 if (expr.slice["end"]) {
1093 const endExpr = zigAnalysis.exprs[expr.slice.end];
1094 let end_ = exprName(endExpr, opts);
1095 end += end_;
1135 case "declRef": {
1136 const name = getDecl(expr.declRef).name;
1137 const canonPath = getCanonDeclPath(expr.declRef);
1138 if (canonPath) {
1139 const link = navLink(canonPath.modNames, canonPath.declNames);
1140 yield { src: name, tag: Tag.identifier, link };
1141 } else {
1142 yield { src: name, tag: Tag.identifier };
10961143 }
1097 if (expr.slice["sentinel"]) {
1098 const sentinelExpr = zigAnalysis.exprs[expr.slice.sentinel];
1099 let sentinel_ = exprName(sentinelExpr, opts);
1100 sentinel += " :" + sentinel_;
1144 return;
1145 }
1146 case "refPath": {
1147 for (let i = 0; i < expr.refPath.length; i += 1) {
1148 if (i > 0) yield Tok.period;
1149 yield* ex(expr.refPath[i]);
11011150 }
1102 payloadHtml += decl + "[" + start + ".." + end + sentinel + "]";
1103 return payloadHtml;
1151 return;
1152 }
1153 case "fieldRef": {
1154 const field_idx = expr.fieldRef.index;
1155 const type = getType(expr.fieldRef.type);
1156 const field = getAstNode(type.src).fields[field_idx];
1157 const name = getAstNode(field).name;
1158 yield { src: name, tag: Tag.identifier };
1159 return;
11041160 }
1105 case "sliceLength": {
1106 let payloadHtml = "";
1107 const lhsExpr = zigAnalysis.exprs[expr.sliceLength.lhs];
1108 const startExpr = zigAnalysis.exprs[expr.sliceLength.start];
1109 const lenExpr = zigAnalysis.exprs[expr.sliceLength.len];
1110 let decl = exprName(lhsExpr, opts);
1111 let start = exprName(startExpr, opts);
1112 let len = exprName(lenExpr, opts);
1113 let sentinel = "";
1114 if (expr.sliceLength["sentinel"]) {
1115 const sentinelExpr = zigAnalysis.exprs[expr.sliceLength.sentinel];
1116 let sentinel_ = exprName(sentinelExpr, options);
1117 sentinel += " :" + sentinel_;
1161 case "bool": {
1162 if (expr.bool) {
1163 yield { src: "true", tag: Tag.identifier };
1164 return;
11181165 }
1119 payloadHtml += decl + "[" + start + "..][0.." + len + sentinel + "]";
1120 return payloadHtml;
1166 yield { src: "false", tag: Tag.identifier };
1167 return;
11211168 }
1122 case "sliceIndex": {
1123 const sliceIndex = zigAnalysis.exprs[expr.sliceIndex];
1124 return exprName(sliceIndex, opts, opts);
1169 case "&": {
1170 yield { src: "&", tag: Tag.ampersand };
1171 yield* ex(zigAnalysis.exprs[expr["&"]], opts);
1172 return;
11251173 }
1126 case "cmpxchg": {
1127 const typeIndex = zigAnalysis.exprs[expr.cmpxchg.type];
1128 const ptrIndex = zigAnalysis.exprs[expr.cmpxchg.ptr];
1129 const expectedValueIndex =
1130 zigAnalysis.exprs[expr.cmpxchg.expected_value];
1131 const newValueIndex = zigAnalysis.exprs[expr.cmpxchg.new_value];
1132 const successOrderIndex = zigAnalysis.exprs[expr.cmpxchg.success_order];
1133 const failureOrderIndex = zigAnalysis.exprs[expr.cmpxchg.failure_order];
1134
1135 const type = exprName(typeIndex, opts);
1136 const ptr = exprName(ptrIndex, opts);
1137 const expectedValue = exprName(expectedValueIndex, opts);
1138 const newValue = exprName(newValueIndex, opts);
1139 const successOrder = exprName(successOrderIndex, opts);
1140 const failureOrder = exprName(failureOrderIndex, opts);
1141
1142 let fnName = "@";
1143
1144 switch (expr.cmpxchg.name) {
1145 case "cmpxchg_strong": {
1146 fnName += "cmpxchgStrong";
1147 break;
1148 }
1149 case "cmpxchg_weak": {
1150 fnName += "cmpxchgWeak";
1174 case "call": {
1175
1176 let call = zigAnalysis.calls[expr.call];
1177
1178 switch (Object.keys(call.func)[0]) {
1179 default:
1180 throw "TODO";
1181 case "declRef":
1182 case "refPath": {
1183 yield* ex(call.func, opts);
11511184 break;
11521185 }
1153 default: {
1154 console.log("There's only cmpxchg_strong and cmpxchg_weak");
1186 }
1187 yield Tok.l_paren;
1188
1189 for (let i = 0; i < call.args.length; i++) {
1190 if (i != 0) {
1191 yield Tok.comma;
1192 yield Tok.space;
11551193 }
1194 yield* ex(call.args[i], opts);
11561195 }
11571196
1158 return (
1159 fnName +
1160 "(" +
1161 type +
1162 ", " +
1163 ptr +
1164 ", " +
1165 expectedValue +
1166 ", " +
1167 newValue +
1168 ", " +
1169 "." +
1170 successOrder +
1171 ", " +
1172 "." +
1173 failureOrder +
1174 ")"
1175 );
1197 yield Tok.r_paren;
1198 return;
11761199 }
1177 case "cmpxchgIndex": {
1178 const cmpxchgIndex = zigAnalysis.exprs[expr.cmpxchgIndex];
1179 return exprName(cmpxchgIndex, opts);
1200 case "sizeOf": {
1201 const sizeOf = zigAnalysis.exprs[expr.sizeOf];
1202 yield { src: "@sizeOf", tag: Tag.builtin };
1203 yield { src: "(", tag: Tag.l_paren };
1204 yield* ex(sizeOf, opts);
1205 yield { src: ")", tag: Tag.r_paren };
1206 return;
11801207 }
1181 case "switchOp": {
1182 let condExpr = zigAnalysis.exprs[expr.switchOp.cond_index];
1183 let ast = getAstNode(expr.switchOp.src);
1184 let file_name = expr.switchOp.file_name;
1185 let outer_decl_index = expr.switchOp.outer_decl;
1186 let outer_decl = getType(outer_decl_index);
1187 let line = 0;
1188 // console.log(expr.switchOp)
1189 // console.log(outer_decl)
1190 while (outer_decl_index !== 0 && outer_decl.line_number > 0) {
1191 line += outer_decl.line_number;
1192 outer_decl_index = outer_decl.outer_decl;
1193 outer_decl = getType(outer_decl_index);
1194 // console.log(outer_decl)
1195 }
1196 line += ast.line + 1;
1197 let payloadHtml = "";
1198 let cond = exprName(condExpr, opts);
1199
1200 payloadHtml +=
1201 "</br>" +
1202 "node_name: " +
1203 ast.name +
1204 "</br>" +
1205 "file: " +
1206 file_name +
1207 "</br>" +
1208 "line: " +
1209 line +
1210 "</br>";
1211 payloadHtml +=
1212 "switch(" +
1213 cond +
1214 ") {" +
1215 '<a href="/src/' +
1216 file_name +
1217 "#L" +
1218 line +
1219 '">' +
1220 "..." +
1221 "</a>}";
1222 return payloadHtml;
1208
1209 case "as": {
1210 const exprArg = zigAnalysis.exprs[expr.as.exprArg];
1211 yield* ex(exprArg, opts);
1212 return;
12231213 }
1224 case "switchIndex": {
1225 const switchIndex = zigAnalysis.exprs[expr.switchIndex];
1226 return exprName(switchIndex, opts);
1214
1215 case "int": {
1216 yield { src: expr.int, tag: Tag.number_literal };
1217 return;
12271218 }
1228 case "fieldRef": {
1229 const field_idx = expr.fieldRef.index;
1230 const type = getType(expr.fieldRef.type);
1231 const field = getAstNode(type.src).fields[field_idx];
1232 const name = getAstNode(field).name;
1233 return name;
1219
1220 case "int_big": {
1221 if (expr.int_big.negated) {
1222 yield { src: "-", tag: Tag.minus };
1223 }
1224 yield { src: expr.int_big.value, tag: Tag.number_literal };
1225 return;
12341226 }
1235 case "intFromEnum": {
1236 const intFromEnum = zigAnalysis.exprs[expr.intFromEnum];
1237 return "@intFromEnum(" + exprName(intFromEnum, opts) + ")";
1227
1228 case "float": {
1229 yield { src: expr.float, tag: Tag.number_literal };
1230 return;
12381231 }
1239 case "bitSizeOf": {
1240 const bitSizeOf = zigAnalysis.exprs[expr.bitSizeOf];
1241 return "@bitSizeOf(" + exprName(bitSizeOf, opts) + ")";
1232
1233 case "float128": {
1234 yield { src: expr.float128, tag: Tag.number_literal };
1235 return;
12421236 }
1243 case "sizeOf": {
1244 const sizeOf = zigAnalysis.exprs[expr.sizeOf];
1245 return "@sizeOf(" + exprName(sizeOf, opts) + ")";
1237
1238 case "array": {
1239 yield { src: ".", tag: Tag.period };
1240 yield Tok.l_brace;
1241 for (let i = 0; i < expr.array.length; i++) {
1242 if (i != 0) {
1243 yield { src: ",", tag: Tag.comma };
1244 yield Tok.space;
1245 }
1246 let elem = zigAnalysis.exprs[expr.array[i]];
1247 yield* ex(elem, opts);
1248 }
1249 yield Tok.r_brace;
1250 return;
12461251 }
1247 case "builtinIndex": {
1248 const builtinIndex = zigAnalysis.exprs[expr.builtinIndex];
1249 return exprName(builtinIndex, opts);
1252
1253 case "compileError": {
1254 yield { src: "@compileError", tag: Tag.builtin };
1255 yield Tok.l_paren;
1256 yield* ex(zigAnalysis.exprs[expr.compileError], opts);
1257 yield Tok.r_paren;
1258 return;
12501259 }
1251 case "builtin": {
1252 const param_expr = zigAnalysis.exprs[expr.builtin.param];
1253 let param = exprName(param_expr, opts);
1254
1255 let payloadHtml = "@";
1256 switch (expr.builtin.name) {
1257 case "align_of": {
1258 payloadHtml += "alignOf";
1259 break;
1260 }
1261 case "int_from_bool": {
1262 payloadHtml += "intFromBool";
1263 break;
1264 }
1265 case "embed_file": {
1266 payloadHtml += "embedFile";
1267 break;
1268 }
1269 case "error_name": {
1270 payloadHtml += "errorName";
1271 break;
1272 }
1273 case "panic": {
1274 payloadHtml += "panic";
1275 break;
1276 }
1277 case "set_runtime_safety": {
1278 payloadHtml += "setRuntimeSafety";
1279 break;
1280 }
1281 case "sqrt": {
1282 payloadHtml += "sqrt";
1283 break;
1284 }
1285 case "sin": {
1286 payloadHtml += "sin";
1287 break;
1260
1261 case "string": {
1262 yield { src: '"' + expr.string + '"', tag: Tag.string_literal };
1263 return;
1264 }
1265
1266 case "struct": {
1267 yield Tok.period;
1268 yield Tok.l_brace;
1269 yield Tok.space;
1270
1271 for (let i = 0; i < expr.struct.length; i++) {
1272 const fv = expr.struct[i];
1273 const field_name = fv.name;
1274 const field_value = ex(fv.val.expr, opts);
1275 yield Tok.period;
1276 yield { src: field_name, tag: Tag.identifier };
1277 yield Tok.space;
1278 yield Tok.eql;
1279 yield Tok.space;
1280 yield* field_value;
1281 if (i !== expr.struct.length - 1) {
1282 yield Tok.comma;
1283 yield Tok.space;
1284 } else {
1285 yield Tok.space;
12881286 }
1289 case "cos": {
1290 payloadHtml += "cos";
1287 }
1288 yield Tok.r_brace;
1289 return;
1290 }
1291
1292 case "binOpIndex": {
1293 const binOp = zigAnalysis.exprs[expr.binOpIndex];
1294 yield* ex(binOp, opts);
1295 return;
1296 }
1297
1298 case "binOp": {
1299 const lhsOp = zigAnalysis.exprs[expr.binOp.lhs];
1300 const rhsOp = zigAnalysis.exprs[expr.binOp.rhs];
1301
1302 if (lhsOp["binOpIndex"] !== undefined) {
1303 yield Tok.l_paren;
1304 yield* ex(lhsOp, opts);
1305 yield Tok.r_paren;
1306 } else {
1307 yield* ex(lhsOp, opts);
1308 }
1309
1310 yield Tok.space;
1311
1312 switch (expr.binOp.name) {
1313 case "add": {
1314 yield { src: "+", tag: Tag.plus };
12911315 break;
12921316 }
1293 case "tan": {
1294 payloadHtml += "tan";
1317 case "addwrap": {
1318 yield { src: "+%", tag: Tag.plus_percent };
12951319 break;
12961320 }
1297 case "exp": {
1298 payloadHtml += "exp";
1321 case "add_sat": {
1322 yield { src: "+|", tag: Tag.plus_pipe };
12991323 break;
13001324 }
1301 case "exp2": {
1302 payloadHtml += "exp2";
1325 case "sub": {
1326 yield { src: "-", tag: Tag.minus };
13031327 break;
13041328 }
1305 case "log": {
1306 payloadHtml += "log";
1329 case "subwrap": {
1330 yield { src: "-%", tag: Tag.minus_percent };
13071331 break;
13081332 }
1309 case "log2": {
1310 payloadHtml += "log2";
1333 case "sub_sat": {
1334 yield { src: "-|", tag: Tag.minus_pipe };
13111335 break;
13121336 }
1313 case "log10": {
1314 payloadHtml += "log10";
1337 case "mul": {
1338 yield { src: "*", tag: Tag.asterisk };
13151339 break;
13161340 }
1317 case "fabs": {
1318 payloadHtml += "fabs";
1341 case "mulwrap": {
1342 yield { src: "*%", tag: Tag.asterisk_percent };
13191343 break;
13201344 }
1321 case "floor": {
1322 payloadHtml += "floor";
1345 case "mul_sat": {
1346 yield { src: "*|", tag: Tag.asterisk_pipe };
13231347 break;
13241348 }
1325 case "ceil": {
1326 payloadHtml += "ceil";
1349 case "div": {
1350 yield { src: "/", tag: Tag.slash };
13271351 break;
13281352 }
1329 case "trunc": {
1330 payloadHtml += "trunc";
1353 case "shl": {
1354 yield { src: "<<", tag: Tag.angle_bracket_angle_bracket_left };
13311355 break;
13321356 }
1333 case "round": {
1334 payloadHtml += "round";
1357 case "shl_sat": {
1358 yield { src: "<<|", tag: Tag.angle_bracket_angle_bracket_left_pipe };
13351359 break;
13361360 }
1337 case "tag_name": {
1338 payloadHtml += "tagName";
1361 case "shr": {
1362 yield { src: ">>", tag: Tag.angle_bracket_angle_bracket_right };
13391363 break;
13401364 }
1341 case "reify": {
1342 payloadHtml += "Type";
1365 case "bit_or": {
1366 yield { src: "|", tag: Tag.pipe };
13431367 break;
13441368 }
1345 case "type_name": {
1346 payloadHtml += "typeName";
1369 case "bit_and": {
1370 yield { src: "&", tag: Tag.ampersand };
13471371 break;
13481372 }
1349 case "frame_type": {
1350 payloadHtml += "Frame";
1373 case "array_cat": {
1374 yield { src: "++", tag: Tag.plus_plus };
13511375 break;
13521376 }
1353 case "frame_size": {
1354 payloadHtml += "frameSize";
1377 case "array_mul": {
1378 yield { src: "**", tag: Tag.asterisk_asterisk };
13551379 break;
13561380 }
1357 case "work_item_id": {
1358 payloadHtml += "workItemId";
1381 case "cmp_eq": {
1382 yield { src: "==", tag: Tag.equal_equal };
13591383 break;
13601384 }
1361 case "work_group_size": {
1362 payloadHtml += "workGroupSize";
1385 case "cmp_neq": {
1386 yield { src: "!=", tag: Tag.bang_equal };
13631387 break;
13641388 }
1365 case "work_group_id": {
1366 payloadHtml += "workGroupId";
1389 case "cmp_gt": {
1390 yield { src: ">", tag: Tag.angle_bracket_right };
13671391 break;
13681392 }
1369 case "int_from_ptr": {
1370 payloadHtml += "intFromPtr";
1393 case "cmp_gte": {
1394 yield { src: ">=", tag: Tag.angle_bracket_right_equal };
13711395 break;
13721396 }
1373 case "int_from_error": {
1374 payloadHtml += "intFromError";
1397 case "cmp_lt": {
1398 yield { src: "<", tag: Tag.angle_bracket_left };
13751399 break;
13761400 }
1377 case "error_to_int": {
1378 payloadHtml += "errorFromInt";
1401 case "cmp_lte": {
1402 yield { src: "<=", tag: Tag.angle_bracket_left_equal };
13791403 break;
13801404 }
1381 case "max": {
1382 payloadHtml += "max";
1405 case "bool_br_and": {
1406 yield { src: "and", tag: Tag.keyword_and };
13831407 break;
13841408 }
1385 case "min": {
1386 payloadHtml += "min";
1409 case "bool_br_or": {
1410 yield { src: "or", tag: Tag.keyword_or };
13871411 break;
13881412 }
1389 case "bit_not": {
1390 return "~" + param;
1391 }
1392 case "bool_not": {
1393 return "!" + param;
1394 }
1395 case "clz": {
1396 return "@clz(T" + ", " + param + ")";
1397 }
1398 case "ctz": {
1399 return "@ctz(T" + ", " + param + ")";
1400 }
1401 case "pop_count": {
1402 return "@popCount(T" + ", " + param + ")";
1403 }
1404 case "byte_swap": {
1405 return "@byteSwap(T" + ", " + param + ")";
1406 }
1407 case "bit_reverse": {
1408 return "@bitReverse(T" + ", " + param + ")";
1409 }
1410 case "truncate": {
1411 return "@truncate(" + param + ")";
1412 }
14131413 default:
1414 console.log("builtin function not handled yet or doesn't exist!");
1414 console.log("operator not handled yet or doesn't exist!");
14151415 }
1416 return payloadHtml + "(" + param + ")";
1416
1417 yield Tok.space;
1418
1419 if (rhsOp["binOpIndex"] !== undefined) {
1420 yield Tok.l_paren;
1421 yield* ex(rhsOp, opts);
1422 yield Tok.r_paren;
1423 } else {
1424 yield* ex(rhsOp, opts);
1425 }
1426 return;
14171427 }
1428
14181429 case "builtinBinIndex": {
14191430 const builtinBinIndex = zigAnalysis.exprs[expr.builtinBinIndex];
1420 return exprName(builtinBinIndex, opts);
1431 yield* ex(builtinBinIndex, opts);
1432 return;
14211433 }
1434
14221435 case "builtinBin": {
14231436 const lhsOp = zigAnalysis.exprs[expr.builtinBin.lhs];
14241437 const rhsOp = zigAnalysis.exprs[expr.builtinBin.rhs];
1425 let lhs = exprName(lhsOp, opts);
1426 let rhs = exprName(rhsOp, opts);
14271438
1428 let payloadHtml = "@";
1439 let builtinName = "@";
14291440 switch (expr.builtinBin.name) {
14301441 case "int_from_float": {
1431 payloadHtml += "intFromFloat";
1442 builtinName += "intFromFloat";
14321443 break;
14331444 }
14341445 case "float_from_int": {
1435 payloadHtml += "floatFromInt";
1446 builtinName += "floatFromInt";
14361447 break;
14371448 }
14381449 case "ptr_from_int": {
1439 payloadHtml += "ptrFromInt";
1450 builtinName += "ptrFromInt";
14401451 break;
14411452 }
14421453 case "enum_from_int": {
1443 payloadHtml += "enumFromInt";
1454 builtinName += "enumFromInt";
14441455 break;
14451456 }
14461457 case "float_cast": {
1447 payloadHtml += "floatCast";
1458 builtinName += "floatCast";
14481459 break;
14491460 }
14501461 case "int_cast": {
1451 payloadHtml += "intCast";
1462 builtinName += "intCast";
14521463 break;
14531464 }
14541465 case "ptr_cast": {
1455 payloadHtml += "ptrCast";
1466 builtinName += "ptrCast";
14561467 break;
14571468 }
14581469 case "const_cast": {
1459 payloadHtml += "constCast";
1470 builtinName += "constCast";
14601471 break;
14611472 }
14621473 case "volatile_cast": {
1463 payloadHtml += "volatileCast";
1474 builtinName += "volatileCast";
14641475 break;
14651476 }
14661477 case "truncate": {
1467 payloadHtml += "truncate";
1478 builtinName += "truncate";
14681479 break;
14691480 }
14701481 case "has_decl": {
1471 payloadHtml += "hasDecl";
1482 builtinName += "hasDecl";
14721483 break;
14731484 }
14741485 case "has_field": {
1475 payloadHtml += "hasField";
1486 builtinName += "hasField";
14761487 break;
14771488 }
14781489 case "bit_reverse": {
1479 payloadHtml += "bitReverse";
1490 builtinName += "bitReverse";
14801491 break;
14811492 }
14821493 case "div_exact": {
1483 payloadHtml += "divExact";
1494 builtinName += "divExact";
14841495 break;
14851496 }
14861497 case "div_floor": {
1487 payloadHtml += "divFloor";
1498 builtinName += "divFloor";
14881499 break;
14891500 }
14901501 case "div_trunc": {
1491 payloadHtml += "divTrunc";
1502 builtinName += "divTrunc";
14921503 break;
14931504 }
14941505 case "mod": {
1495 payloadHtml += "mod";
1506 builtinName += "mod";
14961507 break;
14971508 }
14981509 case "rem": {
1499 payloadHtml += "rem";
1510 builtinName += "rem";
15001511 break;
15011512 }
15021513 case "mod_rem": {
1503 payloadHtml += "rem";
1514 builtinName += "rem";
15041515 break;
15051516 }
15061517 case "shl_exact": {
1507 payloadHtml += "shlExact";
1518 builtinName += "shlExact";
15081519 break;
15091520 }
15101521 case "shr_exact": {
1511 payloadHtml += "shrExact";
1522 builtinName += "shrExact";
15121523 break;
15131524 }
15141525 case "bitcast": {
1515 payloadHtml += "bitCast";
1526 builtinName += "bitCast";
15161527 break;
15171528 }
15181529 case "align_cast": {
1519 payloadHtml += "alignCast";
1530 builtinName += "alignCast";
15201531 break;
15211532 }
15221533 case "vector_type": {
1523 payloadHtml += "Vector";
1534 builtinName += "Vector";
15241535 break;
15251536 }
15261537 case "reduce": {
1527 payloadHtml += "reduce";
1538 builtinName += "reduce";
15281539 break;
15291540 }
15301541 case "splat": {
1531 payloadHtml += "splat";
1542 builtinName += "splat";
15321543 break;
15331544 }
15341545 case "offset_of": {
1535 payloadHtml += "offsetOf";
1546 builtinName += "offsetOf";
15361547 break;
15371548 }
15381549 case "bit_offset_of": {
1539 payloadHtml += "bitOffsetOf";
1550 builtinName += "bitOffsetOf";
15401551 break;
15411552 }
15421553 default:
15431554 console.log("builtin function not handled yet or doesn't exist!");
15441555 }
1545 return payloadHtml + "(" + lhs + ", " + rhs + ")";
1546 }
1547 case "binOpIndex": {
1548 const binOpIndex = zigAnalysis.exprs[expr.binOpIndex];
1549 return exprName(binOpIndex, opts);
1550 }
1551 case "binOp": {
1552 const lhsOp = zigAnalysis.exprs[expr.binOp.lhs];
1553 const rhsOp = zigAnalysis.exprs[expr.binOp.rhs];
1554 let lhs = exprName(lhsOp, opts);
1555 let rhs = exprName(rhsOp, opts);
1556
1557 let print_lhs = "";
1558 let print_rhs = "";
15591556
1560 if (lhsOp["binOpIndex"]) {
1561 print_lhs = "(" + lhs + ")";
1562 } else {
1563 print_lhs = lhs;
1564 }
1565 if (rhsOp["binOpIndex"]) {
1566 print_rhs = "(" + rhs + ")";
1567 } else {
1568 print_rhs = rhs;
1569 }
1570
1571 let operator = "";
1572
1573 switch (expr.binOp.name) {
1574 case "add": {
1575 operator += "+";
1576 break;
1577 }
1578 case "addwrap": {
1579 operator += "+%";
1580 break;
1581 }
1582 case "add_sat": {
1583 operator += "+|";
1584 break;
1585 }
1586 case "sub": {
1587 operator += "-";
1588 break;
1589 }
1590 case "subwrap": {
1591 operator += "-%";
1592 break;
1593 }
1594 case "sub_sat": {
1595 operator += "-|";
1596 break;
1597 }
1598 case "mul": {
1599 operator += "*";
1600 break;
1601 }
1602 case "mulwrap": {
1603 operator += "*%";
1604 break;
1605 }
1606 case "mul_sat": {
1607 operator += "*|";
1608 break;
1609 }
1610 case "div": {
1611 operator += "/";
1612 break;
1613 }
1614 case "shl": {
1615 operator += "<<";
1616 break;
1617 }
1618 case "shl_sat": {
1619 operator += "<<|";
1620 break;
1621 }
1622 case "shr": {
1623 operator += ">>";
1624 break;
1625 }
1626 case "bit_or": {
1627 operator += "|";
1628 break;
1629 }
1630 case "bit_and": {
1631 operator += "&";
1632 break;
1633 }
1634 case "array_cat": {
1635 operator += "++";
1636 break;
1637 }
1638 case "array_mul": {
1639 operator += "**";
1640 break;
1641 }
1642 case "cmp_eq": {
1643 operator += "==";
1644 break;
1645 }
1646 case "cmp_neq": {
1647 operator += "!=";
1648 break;
1649 }
1650 case "cmp_gt": {
1651 operator += ">";
1652 break;
1653 }
1654 case "cmp_gte": {
1655 operator += ">=";
1656 break;
1657 }
1658 case "cmp_lt": {
1659 operator += "<";
1660 break;
1661 }
1662 case "cmp_lte": {
1663 operator += "<=";
1664 break;
1665 }
1666 case "bool_br_and": {
1667 operator += "and";
1668 break;
1669 }
1670 case "bool_br_or": {
1671 operator += "or";
1672 break;
1673 }
1674 default:
1675 console.log("operator not handled yet or doesn't exist!");
1676 }
1677
1678 return print_lhs + " " + operator + " " + print_rhs;
1679 }
1680 case "errorSets": {
1681 const errUnionObj = getType(expr.errorSets);
1682 let lhs = exprName(errUnionObj.lhs, opts);
1683 let rhs = exprName(errUnionObj.rhs, opts);
1684 return lhs + " || " + rhs;
1685 }
1686 case "errorUnion": {
1687 const errUnionObj = getType(expr.errorUnion);
1688 let lhs = exprName(errUnionObj.lhs, opts);
1689 let rhs = exprName(errUnionObj.rhs, opts);
1690 return lhs + "!" + rhs;
1691 }
1692 case "struct": {
1693 // const struct_name =
1694 // zigAnalysis.decls[expr.struct[0].val.typeRef.refPath[0].declRef].name;
1695 const struct_name = ".";
1696 let struct_body = "";
1697 struct_body += struct_name + "{ ";
1698 for (let i = 0; i < expr.struct.length; i++) {
1699 const fv = expr.struct[i];
1700 const field_name = fv.name;
1701 const field_value = exprName(fv.val.expr, opts);
1702 // TODO: commented out because it seems not needed. if it deals
1703 // with a corner case, please add a comment when re-enabling it.
1704 // let field_value = exprArg[Object.keys(exprArg)[0]];
1705 // if (field_value instanceof Object) {
1706 // value_field = exprName(value_field)
1707 // zigAnalysis.decls[value_field[0].val.typeRef.refPath[0].declRef]
1708 // .name;
1709 // }
1710 struct_body += "." + field_name + " = " + field_value;
1711 if (i !== expr.struct.length - 1) {
1712 struct_body += ", ";
1713 } else {
1714 struct_body += " ";
1715 }
1716 }
1717 struct_body += "}";
1718 return struct_body;
1719 }
1720 case "typeOf_peer": {
1721 let payloadHtml = "@TypeOf(";
1722 for (let i = 0; i < expr.typeOf_peer.length; i++) {
1723 let elem = zigAnalysis.exprs[expr.typeOf_peer[i]];
1724 payloadHtml += exprName(elem, { wantHtml: true, wantLink: true });
1725 if (i !== expr.typeOf_peer.length - 1) {
1726 payloadHtml += ", ";
1727 }
1728 }
1729 payloadHtml += ")";
1730 return payloadHtml;
1731 }
1732 case "alignOf": {
1733 const alignRefArg = zigAnalysis.exprs[expr.alignOf];
1734 let payloadHtml =
1735 "@alignOf(" +
1736 exprName(alignRefArg, { wantHtml: true, wantLink: true }) +
1737 ")";
1738 return payloadHtml;
1557 yield { src: builtinName, tag: Tag.builtin };
1558 yield Tok.l_paren;
1559 yield* ex(lhsOp, opts);
1560 yield Tok.comma;
1561 yield Tok.space;
1562 yield* ex(rhsOp, opts);
1563 yield Tok.r_paren;
1564 return;
17391565 }
1740 case "typeOf": {
1741 const typeRefArg = zigAnalysis.exprs[expr.typeOf];
1742 let payloadHtml =
1743 "@TypeOf(" +
1744 exprName(typeRefArg, { wantHtml: true, wantLink: true }) +
1745 ")";
1746 return payloadHtml;
1566
1567 case "enumLiteral": {
1568 let literal = expr.enumLiteral;
1569 yield Tok.period;
1570 yield { src: literal, tag: Tag.identifier };
1571 return;
17471572 }
1748 case "typeInfo": {
1749 const typeRefArg = zigAnalysis.exprs[expr.typeInfo];
1750 let payloadHtml =
1751 "@typeInfo(" +
1752 exprName(typeRefArg, { wantHtml: true, wantLink: true }) +
1753 ")";
1754 return payloadHtml;
1573
1574 case "void": {
1575 yield { src: "void", tag: Tag.identifier };
1576 return;
17551577 }
1578
17561579 case "null": {
1757 if (opts.wantHtml) {
1758 return '<span class="tok-null">null</span>';
1759 } else {
1760 return "null";
1761 }
1762 }
1763 case "array": {
1764 let payloadHtml = ".{";
1765 for (let i = 0; i < expr.array.length; i++) {
1766 if (i != 0) payloadHtml += ", ";
1767 let elem = zigAnalysis.exprs[expr.array[i]];
1768 payloadHtml += exprName(elem, opts);
1769 }
1770 return payloadHtml + "}";
1771 }
1772 case "comptimeExpr": {
1773 return generate_html_for_src(zigAnalysis.comptimeExprs[expr.comptimeExpr].code);
1580 yield { src: "null", tag: Tag.identifier };
1581 return;
17741582 }
1775 case "call": {
1776 let call = zigAnalysis.calls[expr.call];
1777 let payloadHtml = "";
1778
1779 switch (Object.keys(call.func)[0]) {
1780 default:
1781 throw "TODO";
1782 case "declRef":
1783 case "refPath": {
1784 payloadHtml += exprName(call.func, opts);
1785 break;
1786 }
1787 }
1788 payloadHtml += "(";
17891583
1790 for (let i = 0; i < call.args.length; i++) {
1791 if (i != 0) payloadHtml += ", ";
1792 payloadHtml += exprName(call.args[i], opts);
1793 }
1794
1795 payloadHtml += ")";
1796 return payloadHtml;
1797 }
1798 case "as": {
1799 // @Check : this should be done in backend because there are legit @as() calls
1800 // const typeRefArg = zigAnalysis.exprs[expr.as.typeRefArg];
1801 const exprArg = zigAnalysis.exprs[expr.as.exprArg];
1802 // return "@as(" + exprName(typeRefArg, opts) +
1803 // ", " + exprName(exprArg, opts) + ")";
1804 return exprName(exprArg, opts);
1584 case "undefined": {
1585 yield { src: "undefined", tag: Tag.identifier };
1586 return;
18051587 }
1806 case "declRef": {
1807 const name = getDecl(expr.declRef).name;
18081588
1809 if (opts.wantHtml) {
1810 let payloadHtml = "";
1811 if (opts.wantLink) {
1812 payloadHtml += '<a href="' + findDeclNavLink(name) + '">';
1813 }
1814 payloadHtml +=
1815 '<span class="tok-kw" style="color:lightblue;">' +
1816 name +
1817 "</span>";
1818 if (opts.wantLink) payloadHtml += "</a>";
1819 return payloadHtml;
1820 } else {
1821 return name;
1822 }
1823 }
1824 case "refPath": {
1825 let firstComponent = expr.refPath[0];
1826 let name = exprName(firstComponent, opts);
1827 let url = undefined;
1828 if (opts.wantLink && "declRef" in firstComponent) {
1829 url = findDeclNavLink(getDecl(firstComponent.declRef).name);
1830 }
1831 for (let i = 1; i < expr.refPath.length; i++) {
1832 let component = undefined;
1833 if ("string" in expr.refPath[i]) {
1834 component = expr.refPath[i].string;
1835 } else {
1836 component = exprName(expr.refPath[i], { ...opts, wantLink: false });
1837 if (opts.wantLink && "declRef" in expr.refPath[i]) {
1838 url += "." + getDecl(expr.refPath[i].declRef).name;
1839 component = '<a href="' + url + '">' +
1840 component +
1841 "</a>";
1842 }
1843 }
1844 name += "." + component;
1845 }
1846 return name;
1847 }
1848 case "int": {
1849 return "" + expr.int;
1850 }
1851 case "float": {
1852 return "" + expr.float.toFixed(2);
1853 }
1854 case "float128": {
1855 return "" + expr.float128.toFixed(2);
1589 case "anytype": {
1590 yield { src: "anytype", tag: Tag.keyword_anytype };
1591 return;
18561592 }
1857 case "undefined": {
1858 return "undefined";
1593
1594 case "this": {
1595 yield { src: "@This", tag: Tag.builtin };
1596 yield Tok.l_paren;
1597 yield Tok.r_paren;
1598 return;
18591599 }
1860 case "string": {
1861 return '"' + escapeHtml(expr.string) + '"';
1600
1601 case "typeInfo": {
1602 const arg = zigAnalysis.exprs[expr.typeInfo];
1603 yield { src: "@typeInfo", tag: Tag.builtin };
1604 yield Tok.l_paren;
1605 yield* ex(arg, opts);
1606 yield Tok.r_paren;
1607 return;
18621608 }
18631609
1864 case "int_big": {
1865 return (expr.int_big.negated ? "-" : "") + expr.int_big.value;
1610 case "switchIndex": {
1611 const switchIndex = zigAnalysis.exprs[expr.switchIndex];
1612 yield* ex(switchIndex, opts);
1613 return;
18661614 }
18671615
1868 case "anytype": {
1869 return "anytype";
1616 case "errorSets": {
1617 const errSetsObj = getType(expr.errorSets);
1618 yield* ex(errSetsObj.lhs, opts);
1619 yield Tok.space;
1620 yield { src: "||", tag: Tag.pipe_pipe };
1621 yield Tok.space;
1622 yield* ex(errSetsObj.rhs, opts);
1623 return;
18701624 }
18711625
1872 case "this": {
1873 return "@This()";
1626 case "errorUnion": {
1627 const errUnionObj = getType(expr.errorUnion);
1628 yield* ex(errUnionObj.lhs, opts);
1629 yield { src: "!", tag: Tag.bang };
1630 yield* ex(errUnionObj.rhs, opts);
1631 return;
18741632 }
18751633
18761634 case "type": {
......@@ -1880,416 +1638,389 @@ Happy writing!
18801638 if (typeof typeObj === "number") typeObj = getType(typeObj);
18811639 switch (typeObj.kind) {
18821640 default:
1883 throw "TODO";
1641 throw "TODO: " + typeObj.kind;
1642 case typeKinds.Type: {
1643 yield { src: typeObj.name, tag: Tag.identifier };
1644 return;
1645 }
1646 case typeKinds.Void: {
1647 yield { src: "void", tag: Tag.identifier };
1648 return;
1649 }
1650 case typeKinds.NoReturn: {
1651 yield { src: "noreturn", tag: Tag.identifier };
1652 return;
1653 }
1654 case typeKinds.ComptimeExpr: {
1655 yield { src: "anyopaque", tag: Tag.identifier };
1656 return;
1657 }
1658 case typeKinds.Bool: {
1659 yield { src: "bool", tag: Tag.identifier };
1660 return;
1661 }
1662 case typeKinds.ComptimeInt: {
1663 yield { src: "comptime_int", tag: Tag.identifier };
1664 return;
1665 }
1666 case typeKinds.ComptimeFloat: {
1667 yield { src: "comptime_float", tag: Tag.identifier };
1668 return;
1669 }
1670 case typeKinds.Int: {
1671 yield { src: typeObj.name, tag: Tag.identifier };
1672 return;
1673 }
1674 case typeKinds.Float: {
1675 yield { src: typeObj.name, tag: Tag.identifier };
1676 return;
1677 }
1678 case typeKinds.Array: {
1679 yield Tok.l_bracket;
1680 yield* ex(typeObj.len, opts);
1681 if (typeObj.sentinel) {
1682 yield Tok.colon;
1683 yield* ex(typeObj.sentinel, opts);
1684 }
1685 yield Tok.r_bracket;
1686 yield* ex(typeObj.child, opts);
1687 return;
1688 }
1689 case typeKinds.Optional: {
1690 yield { src: "?", tag: Tag.question_mark };
1691 yield* ex(typeObj.child, opts);
1692 return;
1693 }
1694 case typeKinds.Pointer: {
1695 let ptrObj = typeObj;
1696 switch (ptrObj.size) {
1697 default:
1698 console.log("TODO: implement unhandled pointer size case");
1699 case pointerSizeEnum.One:
1700 yield { src: "*", tag: Tag.asterisk };
1701 break;
1702 case pointerSizeEnum.Many:
1703 yield Tok.l_bracket;
1704 yield { src: "*", tag: Tag.asterisk };
1705 if (ptrObj.sentinel !== null) {
1706 yield Tok.colon;
1707 yield* ex(ptrObj.sentinel, opts);
1708 }
1709 yield Tok.r_bracket;
1710 break;
1711 case pointerSizeEnum.Slice:
1712 if (ptrObj.is_ref) {
1713 yield { src: "*", tag: Tag.asterisk };
1714 }
1715 yield Tok.l_bracket;
1716 if (ptrObj.sentinel !== null) {
1717 yield Tok.colon;
1718 yield* ex(ptrObj.sentinel, opts);
1719 }
1720 yield Tok.r_bracket;
1721 break;
1722 case pointerSizeEnum.C:
1723 yield Tok.l_bracket;
1724 yield { src: "*", tag: Tag.asterisk };
1725 yield { src: "c", tag: Tag.identifier };
1726 if (typeObj.sentinel !== null) {
1727 yield Tok.colon;
1728 yield* ex(ptrObj.sentinel, opts);
1729 }
1730 yield Tok.r_bracket;
1731 break;
1732 }
1733 if (!ptrObj.is_mutable) {
1734 yield Tok.const;
1735 yield Tok.space;
1736 }
1737 if (ptrObj.is_allowzero) {
1738 yield { src: "allowzero", tag: Tag.keyword_allowzero };
1739 yield Tok.space;
1740 }
1741 if (ptrObj.is_volatile) {
1742 yield { src: "volatile", tag: Tag.keyword_volatile };
1743 }
1744 if (ptrObj.has_addrspace) {
1745 yield { src: "addrspace", tag: Tag.keyword_addrspace };
1746 yield Tok.l_paren;
1747 yield Tok.period;
1748 yield Tok.r_paren;
1749 }
1750 if (ptrObj.has_align) {
1751 yield { src: "align", tag: Tag.keyword_align };
1752 yield Tok.l_paren;
1753 yield* ex(ptrObj.align, opts);
1754 if (ptrObj.hostIntBytes !== undefined && ptrObj.hostIntBytes !== null) {
1755 yield Tok.colon;
1756 yield* ex(ptrObj.bitOffsetInHost, opts);
1757 yield Tok.colon;
1758 yield* ex(ptrObj.hostIntBytes, opts);
1759 }
1760 yield Tok.r_paren;
1761 yield Tok.space;
1762 }
1763 yield* ex(ptrObj.child, opts);
1764 return;
1765 }
18841766 case typeKinds.Struct: {
18851767 let structObj = typeObj;
1886 let name = "";
1887 let layout = "";
18881768 if (structObj.layout !== null) {
18891769 switch (structObj.layout.enumLiteral) {
18901770 case "Packed": {
1891 layout = "packed ";
1771 yield { src: "packed", tag: Tag.keyword_packed };
18921772 break;
18931773 }
18941774 case "Extern": {
1895 layout = "extern ";
1775 yield { src: "extern", tag: Tag.keyword_extern };
18961776 break;
18971777 }
18981778 }
1779 yield Tok.space;
18991780 }
1900 if (opts.wantHtml) {
1901 name = "<span class='tok-kw'>" + layout + "struct</span>";
1902 } else {
1903 name = layout + "struct";
1904 }
1781 yield { src: "struct", tag: Tag.keyword_struct };
19051782 if (structObj.backing_int !== null) {
1906 name += "(" + exprName(structObj.backing_int, opts) + ")";
1783 yield Tok.l_paren;
1784 yield* ex(structObj.backing_int, opts);
1785 yield Tok.r_paren;
19071786 }
1908 name += " { ";
1909 if (structObj.field_types.length > 1 && opts.wantHtml) { name += "</br>"; }
1910 let indent = "";
1911 if (structObj.field_types.length > 1 && opts.wantHtml) {
1912 indent = "&nbsp;&nbsp;&nbsp;&nbsp;"
1787 yield Tok.space;
1788 yield Tok.l_brace;
1789
1790 if (structObj.field_types.length > 1) {
1791 yield Tok.enter;
1792 } else {
1793 yield Tok.space;
19131794 }
1914 if (opts.indent && structObj.field_types.length > 1) {
1915 indent = opts.indent + indent;
1795
1796 let indent = 0;
1797 if (structObj.field_types.length > 1) {
1798 indent = 1;
19161799 }
1917 let structNode = getAstNode(structObj.src);
1918 let field_end = ",";
1919 if (structObj.field_types.length > 1 && opts.wantHtml) {
1920 field_end += "</br>";
1921 } else {
1922 field_end += " ";
1800 if (opts.indent && structObj.field_types.length > 1) {
1801 indent += opts.ident;
19231802 }
19241803
1804 let structNode = getAstNode(structObj.src);
19251805 for (let i = 0; i < structObj.field_types.length; i += 1) {
19261806 let fieldNode = getAstNode(structNode.fields[i]);
19271807 let fieldName = fieldNode.name;
1928 let html = indent;
1929 if (!structObj.is_tuple) {
1930 html += escapeHtml(fieldName);
1808
1809 for (let j = 0; j < indent; j += 1) {
1810 yield Tok.tab;
19311811 }
19321812
1933 let fieldTypeExpr = structObj.field_types[i];
1934 if (!structObj.is_tuple) {
1935 html += ": ";
1813 if (!typeObj.is_tuple) {
1814 yield { src: fieldName, tag: Tag.identifier };
19361815 }
19371816
1938 html += exprName(fieldTypeExpr, { ...opts, indent: indent });
1817 let fieldTypeExpr = structObj.field_types[i];
1818 if (!typeObj.is_tuple) {
1819 yield Tok.colon;
1820 yield Tok.space;
1821 }
1822 yield* ex(fieldTypeExpr, { ...opts, indent: indent });
19391823
19401824 if (structObj.field_defaults[i] !== null) {
1941 html += " = " + exprName(structObj.field_defaults[i], opts);
1825 yield Tok.space;
1826 yield Tok.eql;
1827 yield Tok.space;
1828 yield* ex(structObj.field_defaults[i], opts);
19421829 }
19431830
1944 html += field_end;
1945
1946 name += html;
1947 }
1948 if (opts.indent && structObj.field_types.length > 1) {
1949 name += opts.indent;
1831 if (structObj.field_types.length > 1) {
1832 yield Tok.comma;
1833 yield Tok.enter;
1834 } else {
1835 yield Tok.space;
1836 }
19501837 }
1951 name += "}";
1952 return name;
1838 yield Tok.r_brace;
1839 return;
19531840 }
19541841 case typeKinds.Enum: {
19551842 let enumObj = typeObj;
1956 let name = "";
1957 if (opts.wantHtml) {
1958 name = "<span class='tok-kw'>enum</span>";
1959 } else {
1960 name = "enum";
1961 }
1843 yield { src: "enum", tag: Tag.keyword_enum };
19621844 if (enumObj.tag) {
1963 name += "(" + exprName(enumObj.tag, opts) + ")";
1845 yield Tok.l_paren;
1846 yield* ex(enumObj.tag, opts);
1847 yield Tok.r_paren;
19641848 }
1965 name += " { ";
1849 yield Tok.space;
1850 yield Tok.l_brace;
1851
19661852 let enumNode = getAstNode(enumObj.src);
19671853 let fields_len = enumNode.fields.length;
19681854 if (enumObj.nonexhaustive) {
19691855 fields_len += 1;
19701856 }
1971 if (fields_len > 1 && opts.wantHtml) { name += "</br>"; }
1972 let indent = "";
1857
1858 if (fields_len > 1) {
1859 yield Tok.enter;
1860 } else {
1861 yield Tok.space;
1862 }
1863
1864 let indent = 0;
19731865 if (fields_len > 1) {
1974 if (opts.wantHtml) {
1975 indent = "&nbsp;&nbsp;&nbsp;&nbsp;";
1976 } else {
1977 indent = " ";
1978 }
1866 indent = 1;
19791867 }
19801868 if (opts.indent) {
1981 indent = opts.indent + indent;
1982 }
1983 let field_end = ",";
1984 if (fields_len > 1 && opts.wantHtml) {
1985 field_end += "</br>";
1986 } else {
1987 field_end += " ";
1869 indent += opts.indent;
19881870 }
1871
19891872 for (let i = 0; i < enumNode.fields.length; i += 1) {
19901873 let fieldNode = getAstNode(enumNode.fields[i]);
19911874 let fieldName = fieldNode.name;
1992 let html = indent + escapeHtml(fieldName);
1875
1876 for (let j = 0; j < indent; j += 1) yield Tok.tab;
1877 yield { src: fieldName, tag: Tag.identifier };
19931878
19941879 if (enumObj.values[i] !== null) {
1995 html += " = " + exprName(enumObj.values[i], opts);
1880 yield Tok.space;
1881 yield Tok.eql;
1882 yield Tok.space;
1883 yield* ex(enumObj.values[i], opts);
19961884 }
19971885
1998 html += field_end;
1999
2000 name += html;
1886 if (fields_len > 1) {
1887 yield Tok.comma;
1888 yield Tok.enter;
1889 }
20011890 }
2002 if (enumObj.nonexhaustive) {
2003 name += indent + "_" + field_end;
1891 for (let j = 0; j < indent; j += 1) yield Tok.tab;
1892 yield { src: "_", tag: Tag.identifier };
1893 if (fields_len > 1) {
1894 yield Tok.comma;
1895 yield Tok.enter;
20041896 }
20051897 if (opts.indent) {
2006 name += opts.indent;
1898 for (let j = 0; j < opts.indent; j += 1) yield Tok.tab;
20071899 }
2008 name += "}";
2009 return name;
1900 yield Tok.r_brace;
1901 return;
20101902 }
20111903 case typeKinds.Union: {
20121904 let unionObj = typeObj;
2013 let name = "";
2014 let layout = "";
20151905 if (unionObj.layout !== null) {
20161906 switch (unionObj.layout.enumLiteral) {
20171907 case "Packed": {
2018 layout = "packed ";
1908 yield { src: "packed", tag: Tag.keyword_packed };
20191909 break;
20201910 }
20211911 case "Extern": {
2022 layout = "extern ";
1912 yield { src: "extern", tag: Tag.keyword_extern };
20231913 break;
20241914 }
20251915 }
1916 yield Tok.space;
20261917 }
2027 if (opts.wantHtml) {
2028 name = "<span class='tok-kw'>" + layout + "union</span>";
2029 } else {
2030 name = layout + "union";
2031 }
1918 yield { src: "union", tag: Tag.keyword_union };
20321919 if (unionObj.auto_tag) {
2033 if (opts.wantHtml) {
2034 name += "(<span class='tok-kw'>enum</span>";
2035 } else {
2036 name += "(enum";
2037 }
1920 yield Tok.l_paren;
1921 yield { src: "enum", tag: Tag.keyword_enum };
20381922 if (unionObj.tag) {
2039 name += "(" + exprName(unionObj.tag, opts) + "))";
1923 yield Tok.l_paren;
1924 yield* ex(unionObj.tag, opts);
1925 yield Tok.r_paren;
1926 yield Tok.r_paren;
20401927 } else {
2041 name += ")";
1928 yield Tok.r_paren;
20421929 }
20431930 } else if (unionObj.tag) {
2044 name += "(" + exprName(unionObj.tag, opts) + ")";
1931 yield Tok.l_paren;
1932 yield* ex(unionObj.tag, opts);
1933 yield Tok.r_paren;
20451934 }
2046 name += " { ";
2047 if (unionObj.field_types.length > 1 && opts.wantHtml) {
2048 name += "</br>";
1935 yield Tok.space;
1936 yield Tok.l_brace;
1937 if (unionObj.field_types.length > 1) {
1938 yield Tok.enter;
1939 } else {
1940 yield Tok.space;
20491941 }
2050 let indent = "";
2051 if (unionObj.field_types.length > 1 && opts.wantHtml) {
2052 indent = "&nbsp;&nbsp;&nbsp;&nbsp;"
1942 let indent = 0;
1943 if (unionObj.field_types.length > 1) {
1944 indent = 1;
20531945 }
20541946 if (opts.indent) {
2055 indent = opts.indent + indent;
1947 indent += opts.indent;
20561948 }
20571949 let unionNode = getAstNode(unionObj.src);
2058 let field_end = ",";
2059 if (unionObj.field_types.length > 1 && opts.wantHtml) {
2060 field_end += "</br>";
2061 } else {
2062 field_end += " ";
2063 }
20641950 for (let i = 0; i < unionObj.field_types.length; i += 1) {
20651951 let fieldNode = getAstNode(unionNode.fields[i]);
20661952 let fieldName = fieldNode.name;
2067 let html = indent + escapeHtml(fieldName);
1953 for (let j = 0; j < indent; j += 1) yield Tok.tab;
1954 yield { src: fieldName, tag: Tag.identifier };
20681955
20691956 let fieldTypeExpr = unionObj.field_types[i];
2070 html += ": ";
1957 yield Tok.colon;
1958 yield Tok.space;
20711959
2072 html += exprName(fieldTypeExpr, { ...opts, indent: indent });
1960 yield* ex(fieldTypeExpr, { ...opts, indent: indent });
20731961
2074 html += field_end;
2075
2076 name += html;
1962 if (unionObj.field_types.length > 1) {
1963 yield Tok.comma;
1964 yield Tok.enter;
1965 } else {
1966 yield Tok.space;
1967 }
20771968 }
20781969 if (opts.indent) {
2079 name += opts.indent;
1970 for (let j = 0; j < opts.indent; j += 1) yield Tok.tab;
20801971 }
2081 name += "}";
2082 return name;
1972 yield Tok.r_brace;
1973 return;
20831974 }
20841975 case typeKinds.Opaque: {
2085 let opaqueObj = typeObj;
2086 return opaqueObj;
2087 }
2088 case typeKinds.ComptimeExpr: {
2089 return "anyopaque";
2090 }
2091 case typeKinds.Array: {
2092 let arrayObj = typeObj;
2093 let name = "[";
2094 let lenName = exprName(arrayObj.len, opts);
2095 let sentinel = arrayObj.sentinel
2096 ? ":" + exprName(arrayObj.sentinel, opts)
2097 : "";
2098 // let is_mutable = arrayObj.is_multable ? "const " : "";
2099
2100 if (opts.wantHtml) {
2101 name +=
2102 '<span class="tok-number">' + lenName + sentinel + "</span>";
2103 } else {
2104 name += lenName + sentinel;
2105 }
2106 name += "]";
2107 // name += is_mutable;
2108 name += exprName(arrayObj.child, opts);
2109 return name;
2110 }
2111 case typeKinds.Optional:
2112 return "?" + exprName(typeObj.child, opts);
2113 case typeKinds.Pointer: {
2114 let ptrObj = typeObj;
2115 let sentinel = ptrObj.sentinel
2116 ? ":" + exprName(ptrObj.sentinel, opts)
2117 : "";
2118 let is_mutable = !ptrObj.is_mutable ? "const " : "";
2119 let name = "";
2120 switch (ptrObj.size) {
2121 default:
2122 console.log("TODO: implement unhandled pointer size case");
2123 case pointerSizeEnum.One:
2124 name += "*";
2125 name += is_mutable;
2126 break;
2127 case pointerSizeEnum.Many:
2128 name += "[*";
2129 name += sentinel;
2130 name += "]";
2131 name += is_mutable;
2132 break;
2133 case pointerSizeEnum.Slice:
2134 if (ptrObj.is_ref) {
2135 name += "*";
2136 }
2137 name += "[";
2138 name += sentinel;
2139 name += "]";
2140 name += is_mutable;
2141 break;
2142 case pointerSizeEnum.C:
2143 name += "[*c";
2144 name += sentinel;
2145 name += "]";
2146 name += is_mutable;
2147 break;
2148 }
2149 // @check: after the major changes in arrays the consts are came from switch above
2150 // if (!ptrObj.is_mutable) {
2151 // if (opts.wantHtml) {
2152 // name += '<span class="tok-kw">const</span> ';
2153 // } else {
2154 // name += "const ";
2155 // }
2156 // }
2157 if (ptrObj.is_allowzero) {
2158 name += "allowzero ";
2159 }
2160 if (ptrObj.is_volatile) {
2161 name += "volatile ";
2162 }
2163 if (ptrObj.has_addrspace) {
2164 name += "addrspace(";
2165 name += "." + "";
2166 name += ") ";
2167 }
2168 if (ptrObj.has_align) {
2169 let align = exprName(ptrObj.align, opts);
2170 if (opts.wantHtml) {
2171 name += '<span class="tok-kw">align</span>(';
2172 } else {
2173 name += "align(";
2174 }
2175 if (opts.wantHtml) {
2176 name += '<span class="tok-number">' + align + "</span>";
2177 } else {
2178 name += align;
2179 }
2180 if (ptrObj.hostIntBytes != null) {
2181 name += ":";
2182 if (opts.wantHtml) {
2183 name +=
2184 '<span class="tok-number">' +
2185 ptrObj.bitOffsetInHost +
2186 "</span>";
2187 } else {
2188 name += ptrObj.bitOffsetInHost;
2189 }
2190 name += ":";
2191 if (opts.wantHtml) {
2192 name +=
2193 '<span class="tok-number">' +
2194 ptrObj.hostIntBytes +
2195 "</span>";
2196 } else {
2197 name += ptrObj.hostIntBytes;
2198 }
2199 }
2200 name += ") ";
2201 }
2202 //name += typeValueName(ptrObj.child, wantHtml, wantSubLink, null);
2203 name += exprName(ptrObj.child, opts);
2204 return name;
2205 }
2206 case typeKinds.Float: {
2207 let floatObj = typeObj;
2208
2209 if (opts.wantHtml) {
2210 return '<span class="tok-type">' + floatObj.name + "</span>";
2211 } else {
2212 return floatObj.name;
2213 }
1976 yield { src: "opaque", tag: Tag.keyword_opaque };
1977 yield Tok.space;
1978 yield Tok.l_brace;
1979 yield Tok.r_brace;
1980 return;
22141981 }
2215 case typeKinds.Int: {
2216 let intObj = typeObj;
2217 let name = intObj.name;
2218 if (opts.wantHtml) {
2219 return '<span class="tok-type">' + name + "</span>";
2220 } else {
2221 return name;
2222 }
1982 case typeKinds.EnumLiteral: {
1983 yield { src: "(enum literal)", tag: Tag.identifier };
1984 return;
22231985 }
2224 case typeKinds.ComptimeInt:
2225 if (opts.wantHtml) {
2226 return '<span class="tok-type">comptime_int</span>';
2227 } else {
2228 return "comptime_int";
2229 }
2230 case typeKinds.ComptimeFloat:
2231 if (opts.wantHtml) {
2232 return '<span class="tok-type">comptime_float</span>';
2233 } else {
2234 return "comptime_float";
2235 }
2236 case typeKinds.Type:
2237 if (opts.wantHtml) {
2238 return '<span class="tok-type">type</span>';
2239 } else {
2240 return "type";
2241 }
2242 case typeKinds.Bool:
2243 if (opts.wantHtml) {
2244 return '<span class="tok-type">bool</span>';
2245 } else {
2246 return "bool";
2247 }
2248 case typeKinds.Void:
2249 if (opts.wantHtml) {
2250 return '<span class="tok-type">void</span>';
2251 } else {
2252 return "void";
2253 }
2254 case typeKinds.EnumLiteral:
2255 if (opts.wantHtml) {
2256 return '<span class="tok-type">(enum literal)</span>';
2257 } else {
2258 return "(enum literal)";
2259 }
2260 case typeKinds.NoReturn:
2261 if (opts.wantHtml) {
2262 return '<span class="tok-type">noreturn</span>';
2263 } else {
2264 return "noreturn";
2265 }
22661986 case typeKinds.ErrorSet: {
22671987 let errSetObj = typeObj;
2268 if (errSetObj.fields == null) {
2269 return '<span class="tok-type">anyerror</span>';
1988 if (errSetObj.fields === null) {
1989 yield { src: "anyerror", tag: Tag.identifier };
22701990 } else if (errSetObj.fields.length == 0) {
2271 return "error{}";
1991 yield { src: "error", tag: Tag.keyword_error };
1992 yield Tok.l_brace;
1993 yield Tok.r_brace;
22721994 } else if (errSetObj.fields.length == 1) {
2273 return "error{" + errSetObj.fields[0].name + "}";
1995 yield { src: "error", tag: Tag.keyword_error };
1996 yield Tok.l_brace;
1997 yield { src: errSetObj.fields[0].name, tag: Tag.identifier };
1998 yield Tok.r_brace;
22741999 } else {
2275 // throw "TODO";
2276 let html = "error{ " + errSetObj.fields[0].name;
2277 for (let i = 1; i < errSetObj.fields.length; i++) html += ", " + errSetObj.fields[i].name;
2278 html += " }";
2279 return html;
2000 yield { src: "error", tag: Tag.keyword_error };
2001 yield Tok.l_brace;
2002 yield { src: errSetObj.fields[0].name, tag: Tag.identifier };
2003 for (let i = 1; i < errSetObj.fields.length; i++) {
2004 yield Tok.comma;
2005 yield Tok.space;
2006 yield { src: errSetObj.fields[i].name, tag: Tag.identifier };
2007 }
2008 yield Tok.r_brace;
22802009 }
2010 return;
22812011 }
2282
22832012 case typeKinds.ErrorUnion: {
22842013 let errUnionObj = typeObj;
2285 let lhs = exprName(errUnionObj.lhs, opts);
2286 let rhs = exprName(errUnionObj.rhs, opts);
2287 return lhs + "!" + rhs;
2014 yield* ex(errUnionObj.lhs, opts);
2015 yield { src: "!", tag: Tag.bang };
2016 yield* ex(errUnionObj.rhs, opts);
2017 return;
22882018 }
22892019 case typeKinds.InferredErrorUnion: {
22902020 let errUnionObj = typeObj;
2291 let payload = exprName(errUnionObj.payload, opts);
2292 return "!" + payload;
2021 yield { src: "!", tag: Tag.bang };
2022 yield* ex(errUnionObj.payload, opts);
2023 return;
22932024 }
22942025 case typeKinds.Fn: {
22952026 let fnObj = typeObj;
......@@ -2299,45 +2030,32 @@ Happy writing!
22992030 opts.linkFnNameDecl = null;
23002031 let payloadHtml = "";
23012032 if (opts.addParensIfFnSignature && fnObj.src == 0) {
2302 payloadHtml += "(";
2033 yield Tok.l_paren;
23032034 }
23042035 if (fnObj.is_extern) {
2305 if (opts.wantHtml) {
2306 payloadHtml += '<span class="tok-kw">extern </span>';
2307 } else {
2308 payloadHtml += "extern ";
2309 }
2036 yield { src: "extern", tag: Tag.keyword_extern };
2037 yield Tok.space;
23102038 } else if (fnObj.has_cc) {
23112039 let cc_expr = zigAnalysis.exprs[fnObj.cc];
23122040 if (cc_expr.enumLiteral === "Inline") {
2313 if(opts.wantHtml) {
2314 payloadHtml += '<span class="tok-kw">inline </span>'
2315 } else {
2316 payloadHtml += "inline "
2317 }
2041 yield { src: "inline", tag: Tag.keyword_inline };
2042 yield Tok.space;
23182043 }
23192044 }
23202045 if (fnObj.has_lib_name) {
2321 payloadHtml += '"' + fnObj.lib_name + '" ';
2046 yield { src: '"' + fnObj.lib_name + '"', tag: Tag.string_literal };
2047 yield Tok.space;
23222048 }
2323 if (opts.wantHtml) {
2324 payloadHtml += '<span class="tok-kw">fn </span>';
2325 if (fnDecl) {
2326 payloadHtml += '<span class="tok-fn">';
2327 if (linkFnNameDecl) {
2328 payloadHtml +=
2329 '<a href="' + linkFnNameDecl + '">' +
2330 escapeHtml(fnDecl.name) +
2331 "</a>";
2332 } else {
2333 payloadHtml += escapeHtml(fnDecl.name);
2334 }
2335 payloadHtml += "</span>";
2049 yield { src: "fn", tag: Tag.keyword_fn };
2050 yield Tok.space;
2051 if (fnDecl) {
2052 if (linkFnNameDecl) {
2053 yield { src: fnDecl.name, tag: Tag.identifier, link: linkFnNameDecl, fnDecl: false };
2054 } else {
2055 yield { src: fnDecl.name, tag: Tag.identifier, fnDecl: true };
23362056 }
2337 } else {
2338 payloadHtml += "fn ";
23392057 }
2340 payloadHtml += "(";
2058 yield Tok.l_paren;
23412059 if (fnObj.params) {
23422060 let fields = null;
23432061 let isVarArgs = false;
......@@ -2349,13 +2067,10 @@ Happy writing!
23492067
23502068 for (let i = 0; i < fnObj.params.length; i += 1) {
23512069 if (i != 0) {
2352 payloadHtml += ", ";
2070 yield Tok.comma;
2071 yield Tok.space;
23532072 }
23542073
2355 if (opts.wantHtml) {
2356 payloadHtml +=
2357 "<span class='argBreaker'><br>&nbsp;&nbsp;&nbsp;&nbsp;</span>";
2358 }
23592074 let value = fnObj.params[i];
23602075 let paramValue = resolveValue({ expr: value });
23612076
......@@ -2363,24 +2078,20 @@ Happy writing!
23632078 let paramNode = getAstNode(fields[i]);
23642079
23652080 if (paramNode.varArgs) {
2366 payloadHtml += "...";
2081 yield Tok.period;
2082 yield Tok.period;
2083 yield Tok.period;
23672084 continue;
23682085 }
23692086
23702087 if (paramNode.noalias) {
2371 if (opts.wantHtml) {
2372 payloadHtml += '<span class="tok-kw">noalias</span> ';
2373 } else {
2374 payloadHtml += "noalias ";
2375 }
2088 yield { src: "noalias", tag: Tag.keyword_noalias };
2089 yield Tok.space;
23762090 }
23772091
23782092 if (paramNode.comptime) {
2379 if (opts.wantHtml) {
2380 payloadHtml += '<span class="tok-kw">comptime</span> ';
2381 } else {
2382 payloadHtml += "comptime ";
2383 }
2093 yield { src: "comptime", tag: Tag.keyword_comptime };
2094 yield Tok.space;
23842095 }
23852096
23862097 let paramName = paramNode.name;
......@@ -2390,94 +2101,102 @@ Happy writing!
23902101 if (paramName === "") {
23912102 paramName = "_";
23922103 }
2393 payloadHtml += paramName + ": ";
2104 yield { src: paramName, tag: Tag.identifier };
2105 yield Tok.colon;
2106 yield Tok.space;
23942107 }
23952108 }
23962109 }
23972110
23982111 if (isVarArgs && i === fnObj.params.length - 1) {
2399 payloadHtml += "...";
2112 yield Tok.period;
2113 yield Tok.period;
2114 yield Tok.period;
24002115 } else if ("alignOf" in value) {
2401 payloadHtml += exprName(value, opts);
2116 yield* ex(value, opts);
24022117 } else if ("typeOf" in value) {
2403 payloadHtml += exprName(value, opts);
2118 yield* ex(value, opts);
24042119 } else if ("typeOf_peer" in value) {
2405 payloadHtml += exprName(value, opts);
2120 yield* ex(value, opts);
24062121 } else if ("declRef" in value) {
2407 payloadHtml += exprName(value, opts);
2122 yield* ex(value, opts);
24082123 } else if ("call" in value) {
2409 payloadHtml += exprName(value, opts);
2124 yield* ex(value, opts);
24102125 } else if ("refPath" in value) {
2411 payloadHtml += exprName(value, opts);
2126 yield* ex(value, opts);
24122127 } else if ("type" in value) {
2413 payloadHtml += exprName(value, opts);
2128 yield* ex(value, opts);
24142129 //payloadHtml += '<span class="tok-kw">' + name + "</span>";
24152130 } else if ("binOpIndex" in value) {
2416 payloadHtml += exprName(value, opts);
2131 yield* ex(value, opts);
24172132 } else if ("comptimeExpr" in value) {
24182133 let comptimeExpr =
24192134 zigAnalysis.comptimeExprs[value.comptimeExpr].code;
2420 if (opts.wantHtml) {
2421 payloadHtml +=
2422 '<span class="tok-kw">' + comptimeExpr + "</span>";
2423 } else {
2424 payloadHtml += comptimeExpr;
2425 }
2426 } else if (opts.wantHtml) {
2427 payloadHtml += '<span class="tok-kw">anytype</span>';
2135 yield* Tokenizer(comptimeExpr);
24282136 } else {
2429 payloadHtml += "anytype";
2137 yield { src: "anytype", tag: Tag.keyword_anytype };
24302138 }
24312139 }
24322140 }
24332141
2434 if (opts.wantHtml) {
2435 payloadHtml += "<span class='argBreaker'>,<br></span>";
2436 }
2437 payloadHtml += ") ";
2142 yield Tok.r_paren;
2143 yield Tok.space;
24382144
24392145 if (fnObj.has_align) {
24402146 let align = zigAnalysis.exprs[fnObj.align];
2441 payloadHtml += "align(" + exprName(align, opts) + ") ";
2147 yield { src: "align", tag: Tag.keyword_align };
2148 yield Tok.l_paren;
2149 yield* ex(align, opts);
2150 yield Tok.r_paren;
2151 yield Tok.space;
24422152 }
24432153 if (fnObj.has_cc) {
24442154 let cc = zigAnalysis.exprs[fnObj.cc];
24452155 if (cc) {
24462156 if (cc.enumLiteral !== "Inline") {
2447 payloadHtml += "callconv(" + exprName(cc, opts) + ") ";
2157 yield { src: "collconv", tag: Tag.keyword_callconv };
2158 yield Tok.l_paren;
2159 yield* ex(cc, opts);
2160 yield Tok.r_paren;
2161 yield Tok.space;
24482162 }
24492163 }
24502164 }
24512165
24522166 if (fnObj.is_inferred_error) {
2453 payloadHtml += "!";
2167 yield { src: "!", tag: Tag.bang };
24542168 }
24552169 if (fnObj.ret != null) {
2456 payloadHtml += exprName(fnObj.ret, {
2170 yield* ex(fnObj.ret, {
24572171 ...opts,
24582172 addParensIfFnSignature: true,
24592173 });
2460 } else if (opts.wantHtml) {
2461 payloadHtml += '<span class="tok-kw">anytype</span>';
24622174 } else {
2463 payloadHtml += "anytype";
2175 yield { src: "anytype", tag: Tag.keyword_anytype };
24642176 }
24652177
24662178 if (opts.addParensIfFnSignature && fnObj.src == 0) {
2467 payloadHtml += ")";
2179 yield Tok.r_paren;
24682180 }
2469 return payloadHtml;
2181 return;
24702182 }
2471 // if (wantHtml) {
2472 // return escapeHtml(typeObj.name);
2473 // } else {
2474 // return typeObj.name;
2475 // }
24762183 }
24772184 }
2185 case "typeOf": {
2186 const typeRefArg = zigAnalysis.exprs[expr.typeOf];
2187 yield { src: "@TypeOf", tag: Tag.builtin };
2188 yield Tok.l_paren;
2189 yield* ex(typeRefArg, opts);
2190 yield Tok.r_paren;
2191 return;
2192 }
24782193 }
2194
2195
24792196 }
24802197
2198
2199
24812200 function shouldSkipParamName(typeRef, paramName) {
24822201 let resolvedTypeRef = resolveValue({ expr: typeRef });
24832202 if ("type" in resolvedTypeRef) {
......@@ -2504,13 +2223,13 @@ Happy writing!
25042223 typeObj ===
25052224 getType(zigAnalysis.modules[zigAnalysis.rootMod].main)
25062225 ) {
2507 name = "std";
2226 name = renderSingleToken(Tok.identifier("std"));
25082227 } else {
2509 name = exprName({ type: typeObj }, { wantHtml: false, wantLink: false });
2228 name = renderTokens(ex({ type: typeObj }));
25102229 }
25112230 if (name != null && name != "") {
2512 domHdrName.innerText =
2513 name + " (" + zigAnalysis.typeKinds[typeObj.kind] + ")";
2231 domHdrName.innerHTML = "<pre class='inline'>" + name + "</pre> ("
2232 + zigAnalysis.typeKinds[typeObj.kind] + ")";
25142233 domHdrName.classList.remove("hidden");
25152234 }
25162235 if (typeObj.kind == typeKinds.ErrorSet) {
......@@ -2528,7 +2247,7 @@ Happy writing!
25282247 //let srcObj = zigAnalysis.astNodes[errObj.src];
25292248 errorList.push(errObj);
25302249 }
2531 errorList.sort(function (a, b) {
2250 errorList.sort(function(a, b) {
25322251 return operatorCompare(a.name.toLowerCase(), b.name.toLowerCase());
25332252 });
25342253
......@@ -2624,55 +2343,80 @@ Happy writing!
26242343 if (resolvedValue.expr.fieldRef) {
26252344 const declRef = decl.value.expr.refPath[0].declRef;
26262345 const type = getDecl(declRef);
2627 domFnProtoCode.innerHTML =
2628 '<span class="tok-kw">const</span> ' +
2629 escapeHtml(decl.name) +
2630 ": " +
2631 type.name +
2632 " = " +
2633 exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
2634 ";";
2346
2347 domFnProtoCode.innerHTML = renderTokens(
2348 (function*() {
2349 yield Tok.const;
2350 yield Tok.space;
2351 yield Tok.identifier(decl.name);
2352 yield Tok.colon;
2353 yield Tok.space;
2354 yield Tok.identifier(type.name);
2355 yield Tok.space;
2356 yield Tok.eql;
2357 yield Tok.space;
2358 yield* ex(decl.value.expr, {});
2359 yield Tok.semi;
2360 })());
26352361 } else if (
26362362 resolvedValue.expr.string !== undefined ||
26372363 resolvedValue.expr.call !== undefined ||
26382364 resolvedValue.expr.comptimeExpr !== undefined
26392365 ) {
2640 let typeRef = null;
2641 if (resolvedValue.typeRef !== undefined) {
2642 typeRef = resolvedValue.typeRef;
2643 }
2644 domFnProtoCode.innerHTML =
2645 '<span class="tok-kw">const</span> ' +
2646 escapeHtml(decl.name) +
2647 ": " +
2648 exprName(typeRef !== null ? typeRef : resolvedValue.expr, { wantHtml: true, wantLink: true }) +
2649 " = " +
2650 exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
2651 ";";
2366 domFnProtoCode.innerHTML = renderTokens(
2367 (function*() {
2368 yield Tok.const;
2369 yield Tok.space;
2370 yield Tok.identifier(decl.name);
2371 if (decl.value.typeRef) {
2372 yield Tok.colon;
2373 yield Tok.space;
2374 yield* ex(decl.value.typeRef, {});
2375 }
2376 yield Tok.space;
2377 yield Tok.eql;
2378 yield Tok.space;
2379 yield* ex(decl.value.expr, {});
2380 yield Tok.semi;
2381 })());
26522382 } else if (resolvedValue.expr.compileError) {
2653 domFnProtoCode.innerHTML =
2654 '<span class="tok-kw">const</span> ' +
2655 escapeHtml(decl.name) +
2656 " = " +
2657 exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
2658 ";";
2383 domFnProtoCode.innerHTML = renderTokens(
2384 (function*() {
2385 yield Tok.const;
2386 yield Tok.space;
2387 yield Tok.identifier(decl.name);
2388 yield Tok.space;
2389 yield Tok.eql;
2390 yield Tok.space;
2391 yield* ex(decl.value.expr, {});
2392 yield Tok.semi;
2393 })());
26592394 } else {
2660 domFnProtoCode.innerHTML =
2661 '<span class="tok-kw">const</span> ' +
2662 escapeHtml(decl.name) +
2663 ": " +
2664 exprName(resolvedValue.typeRef, { wantHtml: true, wantLink: true }) +
2665 " = " +
2666 exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
2667 ";";
2395 const parent = getType(decl.parent_container);
2396 domFnProtoCode.innerHTML = renderTokens(
2397 (function*() {
2398 yield Tok.const;
2399 yield Tok.space;
2400 yield Tok.identifier(decl.name);
2401 if (decl.value.typeRef !== null) {
2402 yield Tok.colon;
2403 yield Tok.space;
2404 yield* ex(decl.value.typeRef, {});
2405 }
2406 yield Tok.space;
2407 yield Tok.eql;
2408 yield Tok.space;
2409 yield* ex(decl.value.expr, {});
2410 yield Tok.semi;
2411 })());
26682412 }
26692413
26702414 let docs = getAstNode(decl.src).docs;
26712415 if (docs != null) {
26722416 // TODO: it shouldn't just be decl.parent_container, but rather
26732417 // the type that the decl holds (if the value is a type)
2674 domTldDocs.innerHTML = markdown(docs, getType(decl.parent_container));
2675
2418 domTldDocs.innerHTML = markdown(docs, decl);
2419
26762420 domTldDocs.classList.remove("hidden");
26772421 }
26782422
......@@ -2685,43 +2429,68 @@ Happy writing!
26852429 if (resolvedVar.expr.fieldRef) {
26862430 const declRef = decl.value.expr.refPath[0].declRef;
26872431 const type = getDecl(declRef);
2688 domFnProtoCode.innerHTML =
2689 '<span class="tok-kw">var</span> ' +
2690 escapeHtml(decl.name) +
2691 ": " +
2692 type.name +
2693 " = " +
2694 exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
2695 ";";
2432 domFnProtoCode.innerHTML = renderTokens(
2433 (function*() {
2434 yield Tok.var;
2435 yield Tok.space;
2436 yield Tok.identifier(decl.name);
2437 yield Tok.colon;
2438 yield Tok.space;
2439 yield Tok.identifier(type.name);
2440 yield Tok.space;
2441 yield Tok.eql;
2442 yield Tok.space;
2443 yield* ex(decl.value.expr, {});
2444 yield Tok.semi;
2445 })());
26962446 } else if (
26972447 resolvedVar.expr.string !== undefined ||
26982448 resolvedVar.expr.call !== undefined ||
26992449 resolvedVar.expr.comptimeExpr !== undefined
27002450 ) {
2701 domFnProtoCode.innerHTML =
2702 '<span class="tok-kw">var</span> ' +
2703 escapeHtml(decl.name) +
2704 ": " +
2705 exprName(resolvedVar.typeRef !== null ? resolvedVar.typeRef : resolvedVar.expr, { wantHtml: true, wantLink: true }) +
2706 " = " +
2707 exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
2708 ";";
2451 domFnProtoCode.innerHTML = renderTokens(
2452 (function*() {
2453 yield Tok.var;
2454 yield Tok.space;
2455 yield Tok.identifier(decl.name);
2456 if (decl.value.typeRef) {
2457 yield Tok.colon;
2458 yield Tok.space;
2459 yield* ex(decl.value.typeRef, {});
2460 }
2461 yield Tok.space;
2462 yield Tok.eql;
2463 yield Tok.space;
2464 yield* ex(decl.value.expr, {});
2465 yield Tok.semi;
2466 })());
27092467 } else if (resolvedVar.expr.compileError) {
2710 domFnProtoCode.innerHTML =
2711 '<span class="tok-kw">var</span> ' +
2712 escapeHtml(decl.name) +
2713 " = " +
2714 exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
2715 ";";
2468 domFnProtoCode.innerHTML = renderTokens(
2469 (function*() {
2470 yield Tok.var;
2471 yield Tok.space;
2472 yield Tok.identifier(decl.name);
2473 yield Tok.space;
2474 yield Tok.eql;
2475 yield Tok.space;
2476 yield* ex(decl.value.expr, {});
2477 yield Tok.semi;
2478 })());
27162479 } else {
2717 domFnProtoCode.innerHTML =
2718 '<span class="tok-kw">var</span> ' +
2719 escapeHtml(decl.name) +
2720 ": " +
2721 exprName(resolvedVar.typeRef, { wantHtml: true, wantLink: true }) +
2722 " = " +
2723 exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
2724 ";";
2480 domFnProtoCode.innerHTML = renderTokens(
2481 (function*() {
2482 yield Tok.var;
2483 yield Tok.space;
2484 yield Tok.identifier(decl.name);
2485 yield Tok.colon;
2486 yield Tok.space;
2487 yield* ex(resolvedVar.typeRef, {});
2488 yield Tok.space;
2489 yield Tok.eql;
2490 yield Tok.space;
2491 yield* ex(decl.value.expr, {});
2492 yield Tok.semi;
2493 })());
27252494 }
27262495
27272496 let docs = getAstNode(decl.src).docs;
......@@ -2955,7 +2724,7 @@ Happy writing!
29552724 resizeDomList(
29562725 domListFns,
29572726 fnsList.length,
2958 "<div><dt><div class=\"fnSignature\"></div><div></div></dt><dd></dd></div>"
2727 '<div><dt><pre class="inline fnSignature"></pre><div></div></dt><dd></dd></div>'
29592728 );
29602729
29612730 for (let i = 0; i < fnsList.length; i += 1) {
......@@ -2968,12 +2737,10 @@ Happy writing!
29682737
29692738 let declType = resolveValue(decl.value);
29702739 console.assert("type" in declType.expr);
2971 tdFnSignature.innerHTML = exprName(declType.expr, {
2972 wantHtml: true,
2973 wantLink: true,
2740 tdFnSignature.innerHTML = renderTokens(ex(declType.expr, {
29742741 fnDecl: decl,
29752742 linkFnNameDecl: navLinkDecl(decl.name),
2976 });
2743 }));
29772744 tdFnSrc.innerHTML = "<a style=\"float: right;\" target=\"_blank\" href=\"" +
29782745 sourceFileLink(decl) + "\">[src]</a>";
29792746
......@@ -3018,14 +2785,22 @@ Happy writing!
30182785 if (container.kind === typeKinds.Enum) {
30192786 let value = container.values[i];
30202787 if (value !== null) {
3021 html += " = " + exprName(value, { wantHtml: true, wantLink: true });
2788 html += renderTokens((function*() {
2789 yield Tok.space;
2790 yield Tok.eql;
2791 yield Tok.space;
2792 yield* ex(value, {});
2793 })());
30222794 }
30232795 } else {
30242796 let fieldTypeExpr = container.field_types[i];
30252797 if (container.kind !== typeKinds.Struct || !container.is_tuple) {
3026 html += ": ";
2798 html += renderTokens((function*() {
2799 yield Tok.colon;
2800 yield Tok.space;
2801 })());
30272802 }
3028 html += exprName(fieldTypeExpr, { wantHtml: true, wantLink: true });
2803 html += renderTokens(ex(fieldTypeExpr, {}));
30292804 let tsn = typeShorthandName(fieldTypeExpr);
30302805 if (tsn) {
30312806 html += "<span> (" + tsn + ")</span>";
......@@ -3033,7 +2808,12 @@ Happy writing!
30332808 if (container.kind === typeKinds.Struct && !container.is_tuple) {
30342809 let defaultInitExpr = container.field_defaults[i];
30352810 if (defaultInitExpr !== null) {
3036 html += " = " + exprName(defaultInitExpr, { wantHtml: true, wantLink: true });
2811 html += renderTokens((function*() {
2812 yield Tok.space;
2813 yield Tok.eql;
2814 yield Tok.space;
2815 yield* ex(defaultInitExpr, {});
2816 })());
30372817 }
30382818 }
30392819 }
......@@ -3052,7 +2832,7 @@ Happy writing!
30522832 resizeDomList(
30532833 domListGlobalVars,
30542834 varsList.length,
3055 '<tr><td><a href="#"></a></td><td></td><td></td></tr>'
2835 '<tr><td><a href="#"></a></td><td><pre class="inline"></pre></td><td></td></tr>'
30562836 );
30572837 for (let i = 0; i < varsList.length; i += 1) {
30582838 let decl = varsList[i];
......@@ -3061,15 +2841,13 @@ Happy writing!
30612841 let tdName = trDom.children[0];
30622842 let tdNameA = tdName.children[0];
30632843 let tdType = trDom.children[1];
2844 let preType = tdType.children[0];
30642845 let tdDesc = trDom.children[2];
30652846
30662847 tdNameA.setAttribute("href", navLinkDecl(decl.name));
30672848 tdNameA.textContent = decl.name;
30682849
3069 tdType.innerHTML = exprName(walkResultTypeRef(decl.value), {
3070 wantHtml: true,
3071 wantLink: true,
3072 });
2850 preType.innerHTML = renderTokens(ex(walkResultTypeRef(decl.value), {}));
30732851
30742852 let docs = getAstNode(decl.src).docs;
30752853 if (docs != null) {
......@@ -3085,7 +2863,7 @@ Happy writing!
30852863 resizeDomList(
30862864 domListValues,
30872865 valsList.length,
3088 '<tr><td><a href="#"></a></td><td></td><td></td></tr>'
2866 '<tr><td><a href="#"></a></td><td><pre class="inline"></pre></td><td></td></tr>'
30892867 );
30902868 for (let i = 0; i < valsList.length; i += 1) {
30912869 let decl = valsList[i];
......@@ -3094,15 +2872,13 @@ Happy writing!
30942872 let tdName = trDom.children[0];
30952873 let tdNameA = tdName.children[0];
30962874 let tdType = trDom.children[1];
2875 let preType = tdType.children[0];
30972876 let tdDesc = trDom.children[2];
30982877
30992878 tdNameA.setAttribute("href", navLinkDecl(decl.name));
31002879 tdNameA.textContent = decl.name;
31012880
3102 tdType.innerHTML = exprName(walkResultTypeRef(decl.value), {
3103 wantHtml: true,
3104 wantLink: true,
3105 });
2881 preType.innerHTML = renderTokens(ex(walkResultTypeRef(decl.value), {}));
31062882
31072883 let docs = getAstNode(decl.src).docs;
31082884 if (docs != null) {
......@@ -3118,24 +2894,21 @@ Happy writing!
31182894 resizeDomList(
31192895 domListTests,
31202896 testsList.length,
3121 '<tr><td><a href="#"></a></td><td></td><td></td></tr>'
2897 '<tr><td><pre class="inline"></pre></td><td><pre class="inline"></pre></td><td></td></tr>'
31222898 );
31232899 for (let i = 0; i < testsList.length; i += 1) {
31242900 let decl = testsList[i];
31252901 let trDom = domListTests.children[i];
31262902
31272903 let tdName = trDom.children[0];
3128 let tdNameA = tdName.children[0];
2904 let tdNamePre = tdName.children[0];
31292905 let tdType = trDom.children[1];
2906 let tdTypePre = tdType.children[0];
31302907 let tdDesc = trDom.children[2];
31312908
3132 tdNameA.setAttribute("href", navLinkDecl(decl.name));
3133 tdNameA.textContent = decl.name;
2909 tdNamePre.innerHTML = renderSingleToken(Tok.identifier(decl.name));
31342910
3135 tdType.innerHTML = exprName(walkResultTypeRef(decl.value), {
3136 wantHtml: true,
3137 wantLink: true,
3138 });
2911 tdTypePre.innerHTML = ex(walkResultTypeRef(decl.value), {});
31392912
31402913 let docs = getAstNode(decl.src).docs;
31412914 if (docs != null) {
......@@ -3260,7 +3033,7 @@ Happy writing!
32603033
32613034 return;
32623035 case NAV_MODES.GUIDES:
3263
3036
32643037 const sections = zigAnalysis.guide_sections;
32653038 if (sections.length != 0 && sections[0].guides.length != 0 && nonSearchPart == "") {
32663039 location.hash = NAV_MODES.GUIDES + sections[0].guides[0].name;
......@@ -3428,10 +3201,10 @@ Happy writing!
34283201 if (list[declIndex] != null) continue;
34293202
34303203 let decl = getDecl(declIndex);
3431
3204
34323205 if (decl.is_uns) {
34333206 let unsDeclList = [decl];
3434 while(unsDeclList.length != 0) {
3207 while (unsDeclList.length != 0) {
34353208 let unsDecl = unsDeclList.pop();
34363209 let unsDeclVal = resolveValue(unsDecl.value);
34373210 if (!("type" in unsDeclVal.expr)) continue;
......@@ -3441,7 +3214,7 @@ Happy writing!
34413214 for (let unsDeclI = 0; unsDeclI < unsPubDeclLen; unsDeclI += 1) {
34423215 let childDeclIndex = unsType.pubDecls[unsDeclI];
34433216 let childDecl = getDecl(childDeclIndex);
3444
3217
34453218 if (childDecl.is_uns) {
34463219 unsDeclList.push(childDecl);
34473220 } else {
......@@ -3460,54 +3233,54 @@ Happy writing!
34603233 return list;
34613234 }
34623235
3463function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
3464 let declVal = resolveValue(decl.value);
3465 let declNames = item.declNames.concat([decl.name]);
3466 let declIndexes = item.declIndexes.concat([declIndex]);
3236 function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
3237 let declVal = resolveValue(decl.value);
3238 let declNames = item.declNames.concat([decl.name]);
3239 let declIndexes = item.declIndexes.concat([declIndex]);
34673240
3468 if (list[declIndex] != null) return;
3469 list[declIndex] = {
3470 modNames: modNames,
3471 declNames: declNames,
3472 declIndexes: declIndexes,
3473 };
3241 if (list[declIndex] != null) return;
3242 list[declIndex] = {
3243 modNames: modNames,
3244 declNames: declNames,
3245 declIndexes: declIndexes,
3246 };
34743247
3475 // add to search index
3476 {
3477 declSearchIndex.add(decl.name, {declIndex});
3478 }
3479
3480
3481 if ("type" in declVal.expr) {
3482 let value = getType(declVal.expr.type);
3483 if (declCanRepresentTypeKind(value.kind)) {
3484 canonTypeDecls[declVal.type] = declIndex;
3248 // add to search index
3249 {
3250 declSearchIndex.add(decl.name, { declIndex });
34853251 }
34863252
3487 if (isContainerType(value)) {
3488 stack.push({
3489 declNames: declNames,
3490 declIndexes: declIndexes,
3491 type: value,
3492 });
3493 }
34943253
3495 // Generic function
3496 if (typeIsGenericFn(declVal.expr.type)) {
3497 let ret = resolveGenericRet(value);
3498 if (ret != null && "type" in ret.expr) {
3499 let generic_type = getType(ret.expr.type);
3500 if (isContainerType(generic_type)) {
3501 stack.push({
3502 declNames: declNames,
3503 declIndexes: declIndexes,
3504 type: generic_type,
3505 });
3254 if ("type" in declVal.expr) {
3255 let value = getType(declVal.expr.type);
3256 if (declCanRepresentTypeKind(value.kind)) {
3257 canonTypeDecls[declVal.type] = declIndex;
3258 }
3259
3260 if (isContainerType(value)) {
3261 stack.push({
3262 declNames: declNames,
3263 declIndexes: declIndexes,
3264 type: value,
3265 });
3266 }
3267
3268 // Generic function
3269 if (typeIsGenericFn(declVal.expr.type)) {
3270 let ret = resolveGenericRet(value);
3271 if (ret != null && "type" in ret.expr) {
3272 let generic_type = getType(ret.expr.type);
3273 if (isContainerType(generic_type)) {
3274 stack.push({
3275 declNames: declNames,
3276 declIndexes: declIndexes,
3277 type: generic_type,
3278 });
3279 }
35063280 }
35073281 }
35083282 }
35093283 }
3510}
35113284
35123285 function getCanonDeclPath(index) {
35133286 if (canonDeclPaths == null) {
......@@ -3524,7 +3297,7 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
35243297 }
35253298
35263299 function escapeHtml(text) {
3527 return text.replace(/[&"<>]/g, function (m) {
3300 return text.replace(/[&"<>]/g, function(m) {
35283301 return escapeHtmlReplacements[m];
35293302 });
35303303 }
......@@ -3553,13 +3326,13 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
35533326 }
35543327
35553328 function parseGuides() {
3556 for (let j = 0; j < zigAnalysis.guide_sections.length; j+=1){
3329 for (let j = 0; j < zigAnalysis.guide_sections.length; j += 1) {
35573330 const section = zigAnalysis.guide_sections[j];
3558 for (let i = 0; i < section.guides.length; i+=1){
3559 let reader = new commonmark.Parser({smart: true});
3331 for (let i = 0; i < section.guides.length; i += 1) {
3332 let reader = new commonmark.Parser({ smart: true });
35603333 const guide = section.guides[i];
3561 const ast = reader.parse(guide.body);
3562
3334 const ast = reader.parse(guide.body);
3335
35633336 // Find the first text thing to use as a sidebar title
35643337 guide.title = "[empty guide]";
35653338 {
......@@ -3571,7 +3344,7 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
35713344 guide.title = node.literal;
35723345 break;
35733346 }
3574 }
3347 }
35753348 }
35763349 // Index this guide
35773350 {
......@@ -3580,24 +3353,24 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
35803353 while ((event = walker.next())) {
35813354 node = event.node;
35823355 if (event.entering == true && node.type === 'text') {
3583 indexTextForGuide(j, i, node);
3356 indexTextForGuide(j, i, node);
35843357 }
3585 }
3358 }
35863359 }
3587 }
3360 }
35883361 }
35893362 }
35903363
3591 function indexTextForGuide(section_idx, guide_idx, node){
3364 function indexTextForGuide(section_idx, guide_idx, node) {
35923365 const terms = node.literal.split(" ");
3593 for (let i = 0; i < terms.length; i += 1){
3366 for (let i = 0; i < terms.length; i += 1) {
35943367 const t = terms[i];
35953368 if (!guidesSearchIndex[t]) guidesSearchIndex[t] = new Set();
3596 node.guide = {section_idx, guide_idx};
3369 node.guide = { section_idx, guide_idx };
35973370 guidesSearchIndex[t].add(node);
3598 }
3371 }
35993372 }
3600
3373
36013374
36023375 function markdown(input, contextType) {
36033376 const parsed = new commonmark.Parser({ smart: true }).parse(input);
......@@ -3620,70 +3393,71 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
36203393
36213394 return new commonmark.HtmlRenderer({ safe: true }).render(parsed);
36223395
3623 function detectDeclPath(text, context) {
3624 let result = "";
3625 let separator = ":";
3626 const components = text.split(".");
3627 let curDeclOrType = undefined;
3628
3629 let curContext = context;
3630 let limit = 10000;
3631 while (curContext) {
3632 limit -= 1;
3633
3634 if (limit == 0) {
3635 throw "too many iterations";
3636 }
3637
3638 curDeclOrType = findSubDecl(curContext, components[0]);
3639
3640 if (!curDeclOrType) {
3641 if (curContext.parent_container == null) break;
3642 curContext = getType(curContext.parent_container);
3643 continue;
3644 }
3396 }
36453397
3646 if (curContext == context) {
3647 separator = '.';
3648 result = location.hash + separator + components[0];
3649 } else {
3650 // We had to go up, which means we need a new path!
3651 const canonPath = getCanonDeclPath(curDeclOrType.find_subdecl_idx);
3652 if (!canonPath) return;
3653
3654 let lastModName = canonPath.modNames[canonPath.modNames.length - 1];
3655 let fullPath = lastModName + ":" + canonPath.declNames.join(".");
3656
3657 separator = '.';
3658 result = "#A;" + fullPath;
3659 }
3398 function detectDeclPath(text, context) {
3399 let result = "";
3400 let separator = ":";
3401 const components = text.split(".");
3402 let curDeclOrType = undefined;
36603403
3661 break;
3662 }
3404 let curContext = context;
3405 let limit = 10000;
3406 while (curContext) {
3407 limit -= 1;
3408
3409 if (limit == 0) {
3410 throw "too many iterations";
3411 }
3412
3413 curDeclOrType = findSubDecl(curContext, components[0]);
36633414
36643415 if (!curDeclOrType) {
3665 for (let i = 0; i < zigAnalysis.modules.length; i += 1){
3666 const p = zigAnalysis.modules[i];
3667 if (p.name == components[0]) {
3668 curDeclOrType = getType(p.main);
3669 result += "#A;" + components[0];
3670 break;
3671 }
3672 }
3416 if (curContext.parent_container == null) break;
3417 curContext = getType(curContext.parent_container);
3418 continue;
36733419 }
36743420
3675 if (!curDeclOrType) return null;
3676
3677 for (let i = 1; i < components.length; i += 1) {
3678 curDeclOrType = findSubDecl(curDeclOrType, components[i]);
3679 if (!curDeclOrType) return null;
3680 result += separator + components[i];
3421 if (curContext == context) {
3422 separator = '.';
3423 result = location.hash + separator + components[0];
3424 } else {
3425 // We had to go up, which means we need a new path!
3426 const canonPath = getCanonDeclPath(curDeclOrType.find_subdecl_idx);
3427 if (!canonPath) return;
3428
3429 let lastModName = canonPath.modNames[canonPath.modNames.length - 1];
3430 let fullPath = lastModName + ":" + canonPath.declNames.join(".");
3431
36813432 separator = '.';
3433 result = "#A;" + fullPath;
36823434 }
36833435
3684 return result;
3685
3436 break;
3437 }
3438
3439 if (!curDeclOrType) {
3440 for (let i = 0; i < zigAnalysis.modules.length; i += 1) {
3441 const p = zigAnalysis.modules[i];
3442 if (p.name == components[0]) {
3443 curDeclOrType = getType(p.main);
3444 result += "#A;" + components[0];
3445 break;
3446 }
3447 }
3448 }
3449
3450 if (!curDeclOrType) return null;
3451
3452 for (let i = 1; i < components.length; i += 1) {
3453 curDeclOrType = findSubDecl(curDeclOrType, components[i]);
3454 if (!curDeclOrType) return null;
3455 result += separator + components[i];
3456 separator = '.';
36863457 }
3458
3459 return result;
3460
36873461 }
36883462
36893463 function activateSelectedResult() {
......@@ -3723,7 +3497,7 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
37233497 startSearch();
37243498 }
37253499 }
3726
3500
37273501
37283502 function onSearchKeyDown(ev) {
37293503 switch (getKeyString(ev)) {
......@@ -3824,7 +3598,7 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
38243598 break;
38253599 case "/":
38263600 if (!getPrefSlashSearch()) break;
3827 // fallthrough
3601 // fallthrough
38283602 case "s":
38293603 if (!isModalVisible(domHelpModal) && !isModalVisible(domPrefsModal)) {
38303604 if (ev.target == domSearch) break;
......@@ -3846,9 +3620,9 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
38463620
38473621 // toggle the help modal
38483622 if (isModalVisible(domHelpModal)) {
3849 hideModal(domHelpModal);
3623 hideModal(domHelpModal);
38503624 } else {
3851 showModal(domHelpModal);
3625 showModal(domHelpModal);
38523626 }
38533627 ev.preventDefault();
38543628 ev.stopPropagation();
......@@ -3927,21 +3701,21 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
39273701 function renderSearchGuides() {
39283702 const searchTrimmed = false;
39293703 let ignoreCase = curNavSearch.toLowerCase() === curNavSearch;
3930
3704
39313705 let terms = getSearchTerms();
39323706 let matchedItems = new Set();
39333707
39343708 for (let i = 0; i < terms.length; i += 1) {
39353709 const nodes = guidesSearchIndex[terms[i]];
39363710 if (nodes) {
3937 for (const n of nodes) {
3711 for (const n of nodes) {
39383712 matchedItems.add(n);
39393713 }
39403714 }
39413715 }
39423716
3943
3944
3717
3718
39453719 if (matchedItems.size !== 0) {
39463720 // Build up the list of search results
39473721 let matchedItemsHTML = "";
......@@ -3966,14 +3740,14 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
39663740 }
39673741 }
39683742
3969 function renderSearchAPI(){
3743 function renderSearchAPI() {
39703744 if (canonDeclPaths == null) {
39713745 canonDeclPaths = computeCanonDeclPaths();
39723746 }
39733747 let declSet = new Set();
39743748 let otherDeclSet = new Set(); // for low quality results
39753749 let declScores = {};
3976
3750
39773751 let ignoreCase = curNavSearch.toLowerCase() === curNavSearch;
39783752 let term_list = getSearchTerms();
39793753 for (let i = 0; i < term_list.length; i += 1) {
......@@ -4004,7 +3778,7 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
40043778 if (declSet.has(p)) {
40053779 found = true;
40063780 break;
4007 }
3781 }
40083782 }
40093783 if (!found) {
40103784 otherDeclSet.add(d);
......@@ -4012,9 +3786,9 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
40123786 termSet.add(d);
40133787 }
40143788 }
4015
3789
40163790 if (declScores[d] == undefined) declScores[d] = 0;
4017
3791
40183792 // scores (lower is better)
40193793 let decl_name = decl.name;
40203794 if (ignoreCase) decl_name = decl_name.toLowerCase();
......@@ -4022,21 +3796,21 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
40223796 // shallow path are preferable
40233797 const path_depth = canonPath.declNames.length * 50;
40243798 // matching the start of a decl name is good
4025 const match_from_start = decl_name.startsWith(term) ? -term.length * (2 -ignoreCase) : (decl_name.length - term.length) + 1;
3799 const match_from_start = decl_name.startsWith(term) ? -term.length * (2 - ignoreCase) : (decl_name.length - term.length) + 1;
40263800 // being a perfect match is good
40273801 const is_full_match = (decl_name === term) ? -decl_name.length * (1 - ignoreCase) : Math.abs(decl_name.length - term.length);
40283802 // matching the end of a decl name is good
40293803 const matches_the_end = decl_name.endsWith(term) ? -term.length * (1 - ignoreCase) : (decl_name.length - term.length) + 1;
40303804 // explicitly penalizing scream case decls
4031 const decl_is_scream_case = decl.name.toUpperCase() != decl.name ? 0 : decl.name.length;
4032
4033 const score = path_depth
4034 + match_from_start
4035 + is_full_match
4036 + matches_the_end
3805 const decl_is_scream_case = decl.name.toUpperCase() != decl.name ? 0 : decl.name.length;
3806
3807 const score = path_depth
3808 + match_from_start
3809 + is_full_match
3810 + matches_the_end
40373811 + decl_is_scream_case;
40383812
4039 declScores[d] += score;
3813 declScores[d] += score;
40403814 }
40413815 }
40423816 if (i != 0) {
......@@ -4047,19 +3821,19 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
40473821 if (termSet.has(p) || otherDeclSet.has(p)) {
40483822 found = true;
40493823 break;
4050 }
3824 }
40513825 }
40523826 if (found) {
40533827 declScores[d] = declScores[d] / term_list.length;
40543828 }
4055
3829
40563830 termOtherSet.add(d);
40573831 }
40583832 declSet = termSet;
40593833 for (let d of termOtherSet) {
40603834 otherDeclSet.add(d);
40613835 }
4062
3836
40633837 }
40643838 }
40653839
......@@ -4068,21 +3842,21 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
40683842 low_quality: [],
40693843 };
40703844 for (let idx of declSet) {
4071 matchedItems.high_quality.push({points: declScores[idx], declIndex: idx})
3845 matchedItems.high_quality.push({ points: declScores[idx], declIndex: idx })
40723846 }
40733847 for (let idx of otherDeclSet) {
4074 matchedItems.low_quality.push({points: declScores[idx], declIndex: idx})
3848 matchedItems.low_quality.push({ points: declScores[idx], declIndex: idx })
40753849 }
4076
4077 matchedItems.high_quality.sort(function (a, b) {
3850
3851 matchedItems.high_quality.sort(function(a, b) {
40783852 let cmp = operatorCompare(a.points, b.points);
40793853 return cmp;
40803854 });
4081 matchedItems.low_quality.sort(function (a, b) {
3855 matchedItems.low_quality.sort(function(a, b) {
40823856 let cmp = operatorCompare(a.points, b.points);
40833857 return cmp;
40843858 });
4085
3859
40863860 // Build up the list of search results
40873861 let matchedItemsHTML = "";
40883862
......@@ -4099,7 +3873,7 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
40993873
41003874 let lastModName = canonPath.modNames[canonPath.modNames.length - 1];
41013875 let text = lastModName + "." + canonPath.declNames.join(".");
4102
3876
41033877
41043878 const href = navLink(canonPath.modNames, canonPath.declNames);
41053879
......@@ -4113,7 +3887,7 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
41133887
41143888 domSectSearchResults.classList.remove("hidden");
41153889 }
4116
3890
41173891 function renderSearchAPIOld() {
41183892 let matchedItems = [];
41193893 let ignoreCase = curNavSearch.toLowerCase() === curNavSearch;
......@@ -4179,7 +3953,7 @@ function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) {
41793953 }
41803954
41813955 if (matchedItems.length !== 0) {
4182 matchedItems.sort(function (a, b) {
3956 matchedItems.sort(function(a, b) {
41833957 let cmp = operatorCompare(b.points, a.points);
41843958 if (cmp != 0) return cmp;
41853959 return operatorCompare(a.decl.name, b.decl.name);
......@@ -4485,12 +4259,12 @@ function toggleExpand(event) {
44854259function RadixTree() {
44864260 this.root = null;
44874261
4488 RadixTree.prototype.search = function (query) {
4262 RadixTree.prototype.search = function(query) {
44894263 return this.root.search(query);
4490
4264
44914265 }
44924266
4493 RadixTree.prototype.add = function (declName, value) {
4267 RadixTree.prototype.add = function(declName, value) {
44944268 if (this.root == null) {
44954269 this.root = new Node(declName.toLowerCase(), null, [value]);
44964270 } else {
......@@ -4499,7 +4273,7 @@ function RadixTree() {
44994273
45004274 const not_scream_case = declName.toUpperCase() != declName;
45014275 let found_separator = false;
4502 for (let i = 1; i < declName.length; i +=1) {
4276 for (let i = 1; i < declName.length; i += 1) {
45034277 if (declName[i] == '_' || declName[i] == '.') {
45044278 found_separator = true;
45054279 continue;
......@@ -4507,42 +4281,42 @@ function RadixTree() {
45074281
45084282
45094283 if (found_separator || (declName[i].toLowerCase() !== declName[i])) {
4510 if (declName.length > i+1
4511 && declName[i+1].toLowerCase() != declName[i+1]) continue;
4284 if (declName.length > i + 1
4285 && declName[i + 1].toLowerCase() != declName[i + 1]) continue;
45124286 let suffix = declName.slice(i);
45134287 this.root.add(suffix.toLowerCase(), value);
45144288 found_separator = false;
45154289 }
45164290 }
45174291 }
4518
4292
45194293 function Node(labels, next, values) {
4520 this.labels = labels;
4294 this.labels = labels;
45214295 this.next = next;
45224296 this.values = values;
45234297 }
45244298
4525 Node.prototype.isCompressed = function () {
4299 Node.prototype.isCompressed = function() {
45264300 return !Array.isArray(this.next);
45274301 }
45284302
4529 Node.prototype.search = function (word) {
4303 Node.prototype.search = function(word) {
45304304 let full_matches = [];
45314305 let partial_matches = [];
45324306 let subtree_root = null;
4533
4307
45344308 let cn = this;
45354309 char_loop: for (let i = 0; i < word.length;) {
45364310 if (cn.isCompressed()) {
45374311 for (let j = 0; j < cn.labels.length; j += 1) {
4538 let current_idx = i+j;
4312 let current_idx = i + j;
45394313
45404314 if (current_idx == word.length) {
45414315 partial_matches = cn.values;
45424316 subtree_root = cn.next;
4543 break char_loop;
4317 break char_loop;
45444318 }
4545
4319
45464320 if (word[current_idx] != cn.labels[j]) return null;
45474321 }
45484322
......@@ -4553,33 +4327,33 @@ function RadixTree() {
45534327 subtree_root = cn.next;
45544328 break char_loop;
45554329 }
4556
4557
4330
4331
45584332 i = new_idx;
45594333 cn = cn.next;
45604334 continue;
45614335 } else {
45624336 for (let j = 0; j < cn.labels.length; j += 1) {
45634337 if (word[i] == cn.labels[j]) {
4564 if (i == word.length - 1) {
4338 if (i == word.length - 1) {
45654339 full_matches = cn.values[j];
45664340 subtree_root = cn.next[j];
45674341 break char_loop;
45684342 }
4569
4343
45704344 let next = cn.next[j];
45714345 if (next == null) return null;
45724346 cn = next;
45734347 i += 1;
4574 continue char_loop;
4575 }
4348 continue char_loop;
4349 }
45764350 }
4577
4351
45784352 // didn't find a match
45794353 return null;
45804354 }
45814355 }
4582
4356
45834357 // Match was found, let's collect all other
45844358 // partial matches from the subtree
45854359 let stack = [subtree_root];
......@@ -4594,22 +4368,22 @@ function RadixTree() {
45944368 for (let v of node.values) {
45954369 partial_matches = partial_matches.concat(v);
45964370 }
4597
4371
45984372 for (let n of node.next) {
45994373 if (n != null) stack.push(n);
46004374 }
46014375 }
46024376 }
46034377
4604 return {full: full_matches, partial: partial_matches};
4378 return { full: full_matches, partial: partial_matches };
46054379 }
46064380
4607 Node.prototype.add = function (word, value) {
4381 Node.prototype.add = function(word, value) {
46084382 let cn = this;
46094383 char_loop: for (let i = 0; i < word.length;) {
46104384 if (cn.isCompressed()) {
4611 for(let j = 0; j < cn.labels.length; j += 1) {
4612 let current_idx = i+j;
4385 for (let j = 0; j < cn.labels.length; j += 1) {
4386 let current_idx = i + j;
46134387
46144388 if (current_idx == word.length) {
46154389 if (j < cn.labels.length - 1) {
......@@ -4621,13 +4395,13 @@ function RadixTree() {
46214395 cn.values.push(value);
46224396 return;
46234397 }
4624
4398
46254399 if (word[current_idx] == cn.labels[j]) continue;
4626
4400
46274401 // if we're here, a mismatch was found
46284402 if (j != cn.labels.length - 1) {
46294403 // create a suffix node
4630 const label_suffix = cn.labels.slice(j+1);
4404 const label_suffix = cn.labels.slice(j + 1);
46314405 let node = new Node(label_suffix, cn.next, [...cn.values]);
46324406 cn.next = node;
46334407 cn.values = [];
......@@ -4641,11 +4415,11 @@ function RadixTree() {
46414415 // meaning that the current node should hold its value
46424416 word_values.push(value);
46434417 } else {
4644 node = new Node(word.slice(current_idx+1), null, [value]);
4418 node = new Node(word.slice(current_idx + 1), null, [value]);
46454419 }
4646
4420
46474421 cn.labels = cn.labels[j] + word[current_idx];
4648 cn.next = [cn.next, node];
4422 cn.next = [cn.next, node];
46494423 cn.values = [cn.values, word_values];
46504424
46514425 if (j != 0) {
......@@ -4657,7 +4431,7 @@ function RadixTree() {
46574431 }
46584432
46594433 return;
4660 }
4434 }
46614435 // label matched fully with word, are there any more chars?
46624436 const new_idx = i + cn.labels.length;
46634437 if (new_idx == word.length) {
......@@ -4673,7 +4447,7 @@ function RadixTree() {
46734447 i = new_idx;
46744448 continue;
46754449 }
4676 }
4450 }
46774451 } else { // node is not compressed
46784452 let letter = word[i];
46794453 for (let j = 0; j < cn.labels.length; j += 1) {
......@@ -4683,7 +4457,7 @@ function RadixTree() {
46834457 return;
46844458 }
46854459 if (cn.next[j] == null) {
4686 let node = new Node(word.slice(i+1), null, [value]);
4460 let node = new Node(word.slice(i + 1), null, [value]);
46874461 cn.next[j] = node;
46884462 return;
46894463 } else {
......@@ -4700,7 +4474,7 @@ function RadixTree() {
47004474 cn.next.push(null);
47014475 cn.values.push([value]);
47024476 } else {
4703 let node = new Node(word.slice(i+1), null, [value]);
4477 let node = new Node(word.slice(i + 1), null, [value]);
47044478 cn.next.push(node);
47054479 cn.values.push([]);
47064480 }
lib/docs/ziglexer.js+225-190
......@@ -1,6 +1,7 @@
11'use strict';
22
33const Tag = {
4 whitespace: "whitespace",
45 invalid: "invalid",
56 identifier: "identifier",
67 string_literal: "string_literal",
......@@ -125,6 +126,27 @@ const Tag = {
125126 keyword_while: "keyword_while"
126127}
127128
129const Tok = {
130 const: { src: "const", tag: Tag.keyword_const },
131 var: { src: "var", tag: Tag.keyword_var },
132 colon: { src: ":", tag: Tag.colon },
133 eql: { src: "=", tag: Tag.equals },
134 space: { src: " ", tag: Tag.whitespace },
135 tab: { src: " ", tag: Tag.whitespace },
136 enter: { src: "\n", tag: Tag.whitespace },
137 semi: { src: ";", tag: Tag.semicolon },
138 l_bracket: { src: "[", tag: Tag.l_bracket },
139 r_bracket: { src: "]", tag: Tag.r_bracket },
140 l_brace: { src: "{", tag: Tag.l_brace },
141 r_brace: { src: "}", tag: Tag.r_brace },
142 l_paren: { src: "(", tag: Tag.l_paren },
143 r_paren: { src: ")", tag: Tag.r_paren },
144 period: { src: ".", tag: Tag.period },
145 comma: { src: ",", tag: Tag.comma },
146 identifier: (name) => { return { src: name, tag: Tag.identifier } },
147};
148
149
128150const State = {
129151 start: 0,
130152 identifier: 1,
......@@ -175,6 +197,7 @@ const State = {
175197 period_2: 46,
176198 period_asterisk: 47,
177199 saw_at_sign: 48,
200 whitespace: 49,
178201}
179202
180203const keywords = {
......@@ -256,25 +279,36 @@ function dump_tokens(tokens, raw_source) {
256279 }
257280}
258281
282function* Tokenizer(raw_source) {
283 let tokenizer = new InnerTokenizer(raw_source);
284 while (true) {
285 let t = tokenizer.next();
286 if (t.tag == Tag.eof)
287 return;
288
289 t.src = raw_source.slice(t.loc.start, t.loc.end);
290
291 yield t;
292 }
259293
294}
295function InnerTokenizer(raw_source) {
296 this.index = 0;
297 this.flag = false;
260298
261function tokenize_zig_source(raw_source) {
262
263 var index = 0;
264 var flag = false;
265
266 let seen_escape_digits = undefined;
267 let remaining_code_units = undefined;
299 this.seen_escape_digits = undefined;
300 this.remaining_code_units = undefined;
268301
269 const next = () => {
302 this.next = () => {
270303 let state = State.start;
271304
272305 var result = {
273306 tag: -1,
274307 loc: {
275 start: index,
308 start: this.index,
276309 end: undefined,
277310 },
311 src: undefined,
278312 };
279313
280314 //having a while (true) loop seems like a bad idea the loop should never
......@@ -284,37 +318,39 @@ function tokenize_zig_source(raw_source) {
284318
285319 while (iterations <= MAX_ITERATIONS) {
286320
287 if (flag) {
288 return make_token(Tag.eof, index - 2, index - 2);
321 if (this.flag) {
322 return make_token(Tag.eof, this.index - 2, this.index - 2);
289323 }
290324 iterations += 1; // avoid death loops
291325
292 var c = raw_source[index];
326 var c = raw_source[this.index];
293327
294328 if (c === undefined) {
295329 c = ' '; // push the last token
296 flag = true;
330 this.flag = true;
297331 }
298332
299333 switch (state) {
300334 case State.start:
301335 switch (c) {
302336 case 0: {
303 if (index != raw_source.length) {
337 if (this.index != raw_source.length) {
304338 result.tag = Tag.invalid;
305 result.loc.start = index;
306 index += 1;
307 result.loc.end = index;
339 result.loc.start = this.index;
340 this.index += 1;
341 result.loc.end = this.index;
308342 return result;
309343 }
310 result.loc.end = index;
344 result.loc.end = this.index;
311345 return result;
312346 }
313347 case ' ':
314348 case '\n':
315349 case '\t':
316350 case '\r': {
317 result.loc.start = index + 1;
351 state = State.whitespace;
352 result.tag = Tag.whitespace;
353 result.loc.start = this.index;
318354 break;
319355 }
320356 case '"': {
......@@ -401,51 +437,51 @@ function tokenize_zig_source(raw_source) {
401437 }
402438 case '(': {
403439 result.tag = Tag.l_paren;
404 index += 1;
405 result.loc.end = index;
440 this.index += 1;
441 result.loc.end = this.index;
406442
407443 return result;
408444
409445 }
410446 case ')': {
411447 result.tag = Tag.r_paren;
412 index += 1; result.loc.end = index;
448 this.index += 1; result.loc.end = this.index;
413449 return result;
414450
415451 }
416452 case '[': {
417453 result.tag = Tag.l_bracket;
418 index += 1; result.loc.end = index;
454 this.index += 1; result.loc.end = this.index;
419455 return result;
420456
421457 }
422458 case ']': {
423459 result.tag = Tag.r_bracket;
424 index += 1; result.loc.end = index;
460 this.index += 1; result.loc.end = this.index;
425461 return result;
426462
427463 }
428464 case ';': {
429465 result.tag = Tag.semicolon;
430 index += 1; result.loc.end = index;
466 this.index += 1; result.loc.end = this.index;
431467 return result;
432468
433469 }
434470 case ',': {
435471 result.tag = Tag.comma;
436 index += 1; result.loc.end = index;
472 this.index += 1; result.loc.end = this.index;
437473 return result;
438474
439475 }
440476 case '?': {
441477 result.tag = Tag.question_mark;
442 index += 1; result.loc.end = index;
478 this.index += 1; result.loc.end = this.index;
443479 return result;
444480
445481 }
446482 case ':': {
447483 result.tag = Tag.colon;
448 index += 1; result.loc.end = index;
484 this.index += 1; result.loc.end = this.index;
449485 return result;
450486
451487 }
......@@ -473,19 +509,19 @@ function tokenize_zig_source(raw_source) {
473509 }
474510 case '{': {
475511 result.tag = Tag.l_brace;
476 index += 1; result.loc.end = index;
512 this.index += 1; result.loc.end = this.index;
477513 return result;
478514
479515 }
480516 case '}': {
481517 result.tag = Tag.r_brace;
482 index += 1; result.loc.end = index;
518 this.index += 1; result.loc.end = this.index;
483519 return result;
484520
485521 }
486522 case '~': {
487523 result.tag = Tag.tilde;
488 index += 1; result.loc.end = index;
524 this.index += 1; result.loc.end = this.index;
489525 return result;
490526
491527 }
......@@ -517,8 +553,8 @@ function tokenize_zig_source(raw_source) {
517553 }
518554 default: {
519555 result.tag = Tag.invalid;
520 result.loc.end = index;
521 index += 1;
556 result.loc.end = this.index;
557 this.index += 1;
522558 return result;
523559 }
524560 }
......@@ -588,7 +624,7 @@ function tokenize_zig_source(raw_source) {
588624 }
589625 default: {
590626 result.tag = Tag.invalid;
591 result.loc.end = index;
627 result.loc.end = this.index;
592628 return result;
593629 }
594630 }
......@@ -597,11 +633,11 @@ function tokenize_zig_source(raw_source) {
597633 switch (c) {
598634 case '=': {
599635 result.tag = Tag.ampersand_equal;
600 index += 1; result.loc.end = index;
636 this.index += 1; result.loc.end = this.index;
601637 return result;
602638 }
603639 default: {
604 result.tag = Tag.ampersand; result.loc.end = index;
640 result.tag = Tag.ampersand; result.loc.end = this.index;
605641 return result;
606642 }
607643 }
......@@ -609,12 +645,12 @@ function tokenize_zig_source(raw_source) {
609645 case State.asterisk: switch (c) {
610646 case '=': {
611647 result.tag = Tag.asterisk_equal;
612 index += 1; result.loc.end = index;
648 this.index += 1; result.loc.end = this.index;
613649 return result;
614650 }
615651 case '*': {
616652 result.tag = Tag.asterisk_asterisk;
617 index += 1; result.loc.end = index;
653 this.index += 1; result.loc.end = this.index;
618654 return result;
619655 }
620656 case '%': {
......@@ -625,7 +661,7 @@ function tokenize_zig_source(raw_source) {
625661 }
626662 default: {
627663 result.tag = Tag.asterisk;
628 result.loc.end = index;
664 result.loc.end = this.index;
629665 return result;
630666 }
631667 }
......@@ -634,12 +670,12 @@ function tokenize_zig_source(raw_source) {
634670 switch (c) {
635671 case '=': {
636672 result.tag = Tag.asterisk_percent_equal;
637 index += 1; result.loc.end = index;
673 this.index += 1; result.loc.end = this.index;
638674 return result;
639675 }
640676 default: {
641677 result.tag = Tag.asterisk_percent;
642 result.loc.end = index;
678 result.loc.end = this.index;
643679 return result;
644680 }
645681 }
......@@ -648,11 +684,11 @@ function tokenize_zig_source(raw_source) {
648684 switch (c) {
649685 case '=': {
650686 result.tag = Tag.asterisk_pipe_equal;
651 index += 1; result.loc.end = index;
687 this.index += 1; result.loc.end = this.index;
652688 return result;
653689 }
654690 default: {
655 result.tag = Tag.asterisk_pipe; result.loc.end = index;
691 result.tag = Tag.asterisk_pipe; result.loc.end = this.index;
656692 return result;
657693 }
658694 }
......@@ -661,11 +697,11 @@ function tokenize_zig_source(raw_source) {
661697 switch (c) {
662698 case '=': {
663699 result.tag = Tag.percent_equal;
664 index += 1; result.loc.end = index;
700 this.index += 1; result.loc.end = this.index;
665701 return result;
666702 }
667703 default: {
668 result.tag = Tag.percent; result.loc.end = index;
704 result.tag = Tag.percent; result.loc.end = this.index;
669705 return result;
670706 }
671707 }
......@@ -674,12 +710,12 @@ function tokenize_zig_source(raw_source) {
674710 switch (c) {
675711 case '=': {
676712 result.tag = Tag.plus_equal;
677 index += 1; result.loc.end = index;
713 this.index += 1; result.loc.end = this.index;
678714 return result;
679715 }
680716 case '+': {
681717 result.tag = Tag.plus_plus;
682 index += 1; result.loc.end = index;
718 this.index += 1; result.loc.end = this.index;
683719 return result;
684720 }
685721 case '%': {
......@@ -689,7 +725,7 @@ function tokenize_zig_source(raw_source) {
689725 state = State.plus_pipe; break;
690726 }
691727 default: {
692 result.tag = Tag.plus; result.loc.end = index;
728 result.tag = Tag.plus; result.loc.end = this.index;
693729 return result;
694730 }
695731 }
......@@ -698,11 +734,11 @@ function tokenize_zig_source(raw_source) {
698734 switch (c) {
699735 case '=': {
700736 result.tag = Tag.plus_percent_equal;
701 index += 1; result.loc.end = index;
737 this.index += 1; result.loc.end = this.index;
702738 return result;
703739 }
704740 default: {
705 result.tag = Tag.plus_percent; result.loc.end = index;
741 result.tag = Tag.plus_percent; result.loc.end = this.index;
706742 return result;
707743 }
708744 }
......@@ -711,11 +747,11 @@ function tokenize_zig_source(raw_source) {
711747 switch (c) {
712748 case '=': {
713749 result.tag = Tag.plus_pipe_equal;
714 index += 1; result.loc.end = index;
750 this.index += 1; result.loc.end = this.index;
715751 return result;
716752 }
717753 default: {
718 result.tag = Tag.plus_pipe; result.loc.end = index;
754 result.tag = Tag.plus_pipe; result.loc.end = this.index;
719755 return result;
720756 }
721757 }
......@@ -724,11 +760,11 @@ function tokenize_zig_source(raw_source) {
724760 switch (c) {
725761 case '=': {
726762 result.tag = Tag.caret_equal;
727 index += 1; result.loc.end = index;
763 this.index += 1; result.loc.end = this.index;
728764 return result;
729765 }
730766 default: {
731 result.tag = Tag.caret; result.loc.end = index;
767 result.tag = Tag.caret; result.loc.end = this.index;
732768 return result;
733769 }
734770 }
......@@ -799,12 +835,12 @@ function tokenize_zig_source(raw_source) {
799835 case '8':
800836 case '9': break;
801837 default: {
802 // if (Token.getKeyword(buffer[result.loc.start..index])) | tag | {
803 const z = raw_source.substring(result.loc.start, index);
838 // if (Token.getKeyword(buffer[result.loc.start..this.index])) | tag | {
839 const z = raw_source.substring(result.loc.start, this.index);
804840 if (z in keywords) {
805841 result.tag = keywords[z];
806842 }
807 result.loc.end = index;
843 result.loc.end = this.index;
808844 return result;
809845 }
810846
......@@ -875,7 +911,7 @@ function tokenize_zig_source(raw_source) {
875911 case '7':
876912 case '8':
877913 case '9': break;
878 default: result.loc.end = index;
914 default: result.loc.end = this.index;
879915 return result;
880916 }
881917 break;
......@@ -887,7 +923,7 @@ function tokenize_zig_source(raw_source) {
887923 }
888924 default: {
889925 result.tag = Tag.invalid;
890 result.loc.end = index;
926 result.loc.end = this.index;
891927 return result;
892928 }
893929 }
......@@ -898,25 +934,25 @@ function tokenize_zig_source(raw_source) {
898934 state = State.string_literal_backslash; break;
899935 }
900936 case '"': {
901 index += 1;
902 result.loc.end = index;
937 this.index += 1;
938 result.loc.end = this.index;
903939
904940 return result;
905941 }
906942 case 0: {
907943 //TODO: PORT
908 // if (index == buffer.len) {
944 // if (this.index == buffer.len) {
909945 // result.tag = .invalid;
910946 // break;
911947 // } else {
912948 // checkLiteralCharacter();
913949 // }
914 result.loc.end = index;
950 result.loc.end = this.index;
915951 return result;
916952 }
917953 case '\n': {
918954 result.tag = Tag.invalid;
919 result.loc.end = index;
955 result.loc.end = this.index;
920956 return result;
921957 }
922958 //TODO: PORT
......@@ -928,7 +964,7 @@ function tokenize_zig_source(raw_source) {
928964 case 0:
929965 case '\n': {
930966 result.tag = Tag.invalid;
931 result.loc.end = index;
967 result.loc.end = this.index;
932968 return result;
933969 }
934970 default: {
......@@ -939,7 +975,7 @@ function tokenize_zig_source(raw_source) {
939975 case State.char_literal: switch (c) {
940976 case 0: {
941977 result.tag = Tag.invalid;
942 result.loc.end = index;
978 result.loc.end = this.index;
943979 return result;
944980 }
945981 case '\\': {
......@@ -952,15 +988,15 @@ function tokenize_zig_source(raw_source) {
952988 // break;
953989 // },
954990 // 0xc0...0xdf => { // 110xxxxx
955 // remaining_code_units = 1;
991 // this.remaining_code_units = 1;
956992 // state = .char_literal_unicode;
957993 // },
958994 // 0xe0...0xef => { // 1110xxxx
959 // remaining_code_units = 2;
995 // this.remaining_code_units = 2;
960996 // state = .char_literal_unicode;
961997 // },
962998 // 0xf0...0xf7 => { // 11110xxx
963 // remaining_code_units = 3;
999 // this.remaining_code_units = 3;
9641000 // state = .char_literal_unicode;
9651001 // },
9661002
......@@ -1070,7 +1106,7 @@ function tokenize_zig_source(raw_source) {
10701106 // case 0xdd:
10711107 // case 0xde:
10721108 // case 0xdf:
1073 // remaining_code_units = 1;
1109 // this.remaining_code_units = 1;
10741110 // state = .char_literal_unicode;
10751111 // case 0xe0:
10761112 // case 0xe1:
......@@ -1088,7 +1124,7 @@ function tokenize_zig_source(raw_source) {
10881124 // case 0xed:
10891125 // case 0xee:
10901126 // case 0xef:
1091 // remaining_code_units = 2;
1127 // this.remaining_code_units = 2;
10921128 // state = .char_literal_unicode;
10931129 // case 0xf0:
10941130 // case 0xf1:
......@@ -1098,12 +1134,12 @@ function tokenize_zig_source(raw_source) {
10981134 // case 0xf5:
10991135 // case 0xf6:
11001136 // case 0xf7:
1101 // remaining_code_units = 3;
1137 // this.remaining_code_units = 3;
11021138 // state = .char_literal_unicode;
11031139
11041140 case '\n': {
11051141 result.tag = Tag.invalid;
1106 result.loc.end = index;
1142 result.loc.end = this.index;
11071143 return result;
11081144 }
11091145 default: {
......@@ -1116,12 +1152,12 @@ function tokenize_zig_source(raw_source) {
11161152 case 0:
11171153 case '\n': {
11181154 result.tag = Tag.invalid;
1119 result.loc.end = index;
1155 result.loc.end = this.index;
11201156 return result;
11211157 }
11221158 case 'x': {
11231159 state = State.char_literal_hex_escape;
1124 seen_escape_digits = 0; break;
1160 this.seen_escape_digits = 0; break;
11251161 }
11261162 case 'u': {
11271163 state = State.char_literal_unicode_escape_saw_u; break;
......@@ -1155,14 +1191,14 @@ function tokenize_zig_source(raw_source) {
11551191 case 'D':
11561192 case 'E':
11571193 case 'F': {
1158 seen_escape_digits += 1;
1159 if (seen_escape_digits == 2) {
1194 this.seen_escape_digits += 1;
1195 if (this.seen_escape_digits == 2) {
11601196 state = State.char_literal_end;
11611197 } break;
11621198 }
11631199 default: {
11641200 result.tag = Tag.invalid;
1165 esult.loc.end = index;
1201 esult.loc.end = this.index;
11661202 return result;
11671203 }
11681204 }
......@@ -1171,7 +1207,7 @@ function tokenize_zig_source(raw_source) {
11711207 switch (c) {
11721208 case 0: {
11731209 result.tag = Tag.invalid;
1174 result.loc.end = index;
1210 result.loc.end = this.index;
11751211 return result;
11761212 }
11771213 case '{': {
......@@ -1187,7 +1223,7 @@ function tokenize_zig_source(raw_source) {
11871223 switch (c) {
11881224 case 0: {
11891225 result.tag = Tag.invalid;
1190 result.loc.end = index;
1226 result.loc.end = this.index;
11911227 return result;
11921228 }
11931229 case '0':
......@@ -1297,13 +1333,13 @@ function tokenize_zig_source(raw_source) {
12971333 switch (c) {
12981334 case '\'': {
12991335 result.tag = Tag.char_literal;
1300 index += 1;
1301 result.loc.end = index;
1336 this.index += 1;
1337 result.loc.end = this.index;
13021338 return result;
13031339 }
13041340 default: {
13051341 result.tag = Tag.invalid;
1306 result.loc.end = index;
1342 result.loc.end = this.index;
13071343 return result;
13081344 }
13091345 }
......@@ -1311,14 +1347,14 @@ function tokenize_zig_source(raw_source) {
13111347 case State.char_literal_unicode:
13121348 switch (c) {
13131349 // 0x80...0xbf => {
1314 // remaining_code_units -= 1;
1315 // if (remaining_code_units == 0) {
1350 // this.remaining_code_units -= 1;
1351 // if (this.remaining_code_units == 0) {
13161352 // state = .char_literal_end;
13171353 // }
13181354 // },
13191355 default: {
13201356 result.tag = Tag.invalid;
1321 result.loc.end = index;
1357 result.loc.end = this.index;
13221358 return result;
13231359 }
13241360 }
......@@ -1326,12 +1362,12 @@ function tokenize_zig_source(raw_source) {
13261362 case State.multiline_string_literal_line:
13271363 switch (c) {
13281364 case 0:
1329 result.loc.end = index;
1365 result.loc.end = this.index;
13301366 return result;
13311367 case '\n': {
13321368
1333 index += 1;
1334 result.loc.end = index;
1369 this.index += 1;
1370 result.loc.end = this.index;
13351371 return result;
13361372 }
13371373 case '\t': break;
......@@ -1344,13 +1380,13 @@ function tokenize_zig_source(raw_source) {
13441380 switch (c) {
13451381 case '=': {
13461382 result.tag = Tag.bang_equal;
1347 index += 1;
1348 result.loc.end = index;
1383 this.index += 1;
1384 result.loc.end = this.index;
13491385 return result;
13501386 }
13511387 default: {
13521388 result.tag = Tag.bang;
1353 result.loc.end = index;
1389 result.loc.end = this.index;
13541390 return result;
13551391 }
13561392 }
......@@ -1359,19 +1395,19 @@ function tokenize_zig_source(raw_source) {
13591395 switch (c) {
13601396 case '=': {
13611397 result.tag = Tag.pipe_equal;
1362 index += 1;
1363 result.loc.end = index;
1398 this.index += 1;
1399 result.loc.end = this.index;
13641400 return result;
13651401 }
13661402 case '|': {
13671403 result.tag = Tag.pipe_pipe;
1368 index += 1;
1369 result.loc.end = index;
1404 this.index += 1;
1405 result.loc.end = this.index;
13701406 return result;
13711407 }
13721408 default: {
13731409 result.tag = Tag.pipe;
1374 result.loc.end = index;
1410 result.loc.end = this.index;
13751411 return result;
13761412 }
13771413 }
......@@ -1379,19 +1415,19 @@ function tokenize_zig_source(raw_source) {
13791415 case State.equal: switch (c) {
13801416 case '=': {
13811417 result.tag = Tag.equal_equal;
1382 index += 1;
1383 result.loc.end = index;
1418 this.index += 1;
1419 result.loc.end = this.index;
13841420 return result;
13851421 }
13861422 case '>': {
13871423 result.tag = Tag.equal_angle_bracket_right;
1388 index += 1;
1389 result.loc.end = index;
1424 this.index += 1;
1425 result.loc.end = this.index;
13901426 return result;
13911427 }
13921428 default: {
13931429 result.tag = Tag.equal;
1394 result.loc.end = index;
1430 result.loc.end = this.index;
13951431 return result;
13961432 }
13971433 }
......@@ -1399,14 +1435,14 @@ function tokenize_zig_source(raw_source) {
13991435 case State.minus: switch (c) {
14001436 case '>': {
14011437 result.tag = Tag.arrow;
1402 index += 1;
1403 result.loc.end = index;
1438 this.index += 1;
1439 result.loc.end = this.index;
14041440 return result;
14051441 }
14061442 case '=': {
14071443 result.tag = Tag.minus_equal;
1408 index += 1;
1409 result.loc.end = index;
1444 this.index += 1;
1445 result.loc.end = this.index;
14101446 return result;
14111447 }
14121448 case '%': {
......@@ -1417,7 +1453,7 @@ function tokenize_zig_source(raw_source) {
14171453 }
14181454 default: {
14191455 result.tag = Tag.minus;
1420 result.loc.end = index;
1456 result.loc.end = this.index;
14211457 return result;
14221458 }
14231459 }
......@@ -1426,13 +1462,13 @@ function tokenize_zig_source(raw_source) {
14261462 switch (c) {
14271463 case '=': {
14281464 result.tag = Tag.minus_percent_equal;
1429 index += 1;
1430 result.loc.end = index;
1465 this.index += 1;
1466 result.loc.end = this.index;
14311467 return result;
14321468 }
14331469 default: {
14341470 result.tag = Tag.minus_percent;
1435 result.loc.end = index;
1471 result.loc.end = this.index;
14361472 return result;
14371473 }
14381474 }
......@@ -1441,13 +1477,13 @@ function tokenize_zig_source(raw_source) {
14411477 switch (c) {
14421478 case '=': {
14431479 result.tag = Tag.minus_pipe_equal;
1444 index += 1;
1445 result.loc.end = index;
1480 this.index += 1;
1481 result.loc.end = this.index;
14461482 return result;
14471483 }
14481484 default: {
14491485 result.tag = Tag.minus_pipe;
1450 result.loc.end = index;
1486 result.loc.end = this.index;
14511487 return result;
14521488 }
14531489 }
......@@ -1459,13 +1495,13 @@ function tokenize_zig_source(raw_source) {
14591495 }
14601496 case '=': {
14611497 result.tag = Tag.angle_bracket_left_equal;
1462 index += 1;
1463 result.loc.end = index;
1498 this.index += 1;
1499 result.loc.end = this.index;
14641500 return result;
14651501 }
14661502 default: {
14671503 result.tag = Tag.angle_bracket_left;
1468 result.loc.end = index;
1504 result.loc.end = this.index;
14691505 return result;
14701506 }
14711507 }
......@@ -1474,8 +1510,8 @@ function tokenize_zig_source(raw_source) {
14741510 switch (c) {
14751511 case '=': {
14761512 result.tag = Tag.angle_bracket_angle_bracket_left_equal;
1477 index += 1;
1478 result.loc.end = index;
1513 this.index += 1;
1514 result.loc.end = this.index;
14791515 return result;
14801516 }
14811517 case '|': {
......@@ -1483,7 +1519,7 @@ function tokenize_zig_source(raw_source) {
14831519 }
14841520 default: {
14851521 result.tag = Tag.angle_bracket_angle_bracket_left;
1486 result.loc.end = index;
1522 result.loc.end = this.index;
14871523 return result;
14881524 }
14891525 }
......@@ -1492,13 +1528,13 @@ function tokenize_zig_source(raw_source) {
14921528 switch (c) {
14931529 case '=': {
14941530 result.tag = Tag.angle_bracket_angle_bracket_left_pipe_equal;
1495 index += 1;
1496 result.loc.end = index;
1531 this.index += 1;
1532 result.loc.end = this.index;
14971533 return result;
14981534 }
14991535 default: {
15001536 result.tag = Tag.angle_bracket_angle_bracket_left_pipe;
1501 result.loc.end = index;
1537 result.loc.end = this.index;
15021538 return result;
15031539 }
15041540 }
......@@ -1510,13 +1546,13 @@ function tokenize_zig_source(raw_source) {
15101546 }
15111547 case '=': {
15121548 result.tag = Tag.angle_bracket_right_equal;
1513 index += 1;
1514 result.loc.end = index;
1549 this.index += 1;
1550 result.loc.end = this.index;
15151551 return result;
15161552 }
15171553 default: {
15181554 result.tag = Tag.angle_bracket_right;
1519 result.loc.end = index;
1555 result.loc.end = this.index;
15201556 return result;
15211557 }
15221558 }
......@@ -1525,13 +1561,13 @@ function tokenize_zig_source(raw_source) {
15251561 switch (c) {
15261562 case '=': {
15271563 result.tag = Tag.angle_bracket_angle_bracket_right_equal;
1528 index += 1;
1529 result.loc.end = index;
1564 this.index += 1;
1565 result.loc.end = this.index;
15301566 return result;
15311567 }
15321568 default: {
15331569 result.tag = Tag.angle_bracket_angle_bracket_right;
1534 result.loc.end = index;
1570 result.loc.end = this.index;
15351571 return result;
15361572 }
15371573 }
......@@ -1546,7 +1582,7 @@ function tokenize_zig_source(raw_source) {
15461582 }
15471583 default: {
15481584 result.tag = Tag.period;
1549 result.loc.end = index;
1585 result.loc.end = this.index;
15501586 return result;
15511587 }
15521588 }
......@@ -1555,13 +1591,13 @@ function tokenize_zig_source(raw_source) {
15551591 switch (c) {
15561592 case '.': {
15571593 result.tag = Tag.ellipsis3;
1558 index += 1;
1559 result.loc.end = index;
1594 this.index += 1;
1595 result.loc.end = this.index;
15601596 return result;
15611597 }
15621598 default: {
15631599 result.tag = Tag.ellipsis2;
1564 result.loc.end = index;
1600 result.loc.end = this.index;
15651601 return result;
15661602 }
15671603 }
......@@ -1570,12 +1606,12 @@ function tokenize_zig_source(raw_source) {
15701606 switch (c) {
15711607 case '*': {
15721608 result.tag = Tag.invalid_periodasterisks;
1573 result.loc.end = index;
1609 result.loc.end = this.index;
15741610 return result;
15751611 }
15761612 default: {
15771613 result.tag = Tag.period_asterisk;
1578 result.loc.end = index;
1614 result.loc.end = this.index;
15791615 return result;
15801616 }
15811617 }
......@@ -1588,24 +1624,24 @@ function tokenize_zig_source(raw_source) {
15881624 }
15891625 case '=': {
15901626 result.tag = Tag.slash_equal;
1591 index += 1;
1592 result.loc.end = index;
1627 this.index += 1;
1628 result.loc.end = this.index;
15931629 return result;
15941630 }
15951631 default: {
15961632 result.tag = Tag.slash;
1597 result.loc.end = index;
1633 result.loc.end = this.index;
15981634 return result;
15991635 }
16001636 } break;
16011637 case State.line_comment_start:
16021638 switch (c) {
16031639 case 0: {
1604 if (index != raw_source.length) {
1640 if (this.index != raw_source.length) {
16051641 result.tag = Tag.invalid;
1606 index += 1;
1642 this.index += 1;
16071643 }
1608 result.loc.end = index;
1644 result.loc.end = this.index;
16091645 return result;
16101646 }
16111647 case '/': {
......@@ -1617,7 +1653,7 @@ function tokenize_zig_source(raw_source) {
16171653 }
16181654 case '\n': {
16191655 state = State.start;
1620 result.loc.start = index + 1; break;
1656 result.loc.start = this.index + 1; break;
16211657 }
16221658 case '\t':
16231659 state = State.line_comment; break;
......@@ -1637,7 +1673,7 @@ function tokenize_zig_source(raw_source) {
16371673 case '\n':
16381674 {
16391675 result.tag = Tag.doc_comment;
1640 result.loc.end = index;
1676 result.loc.end = this.index;
16411677 return result;
16421678 }
16431679 case '\t': {
......@@ -1655,16 +1691,16 @@ function tokenize_zig_source(raw_source) {
16551691 case State.line_comment:
16561692 switch (c) {
16571693 case 0: {
1658 if (index != raw_source.length) {
1694 if (this.index != raw_source.length) {
16591695 result.tag = Tag.invalid;
1660 index += 1;
1696 this.index += 1;
16611697 }
1662 result.loc.end = index;
1698 result.loc.end = this.index;
16631699 return result;
16641700 }
16651701 case '\n': {
16661702 state = State.start;
1667 result.loc.start = index + 1;
1703 result.loc.start = this.index + 1;
16681704 break;
16691705 }
16701706 case '\t': break;
......@@ -1675,7 +1711,7 @@ function tokenize_zig_source(raw_source) {
16751711 switch (c) {
16761712 case 0://
16771713 case '\n':
1678 result.loc.end = index;
1714 result.loc.end = this.index;
16791715 return result;
16801716 case '\t': break;
16811717 //TODOL PORT
......@@ -1754,7 +1790,7 @@ function tokenize_zig_source(raw_source) {
17541790 case 'P':
17551791 state = State.int_exponent;
17561792 break;
1757 default: result.loc.end = index;
1793 default: result.loc.end = this.index;
17581794 return result;
17591795 } break;
17601796 case State.int_exponent:
......@@ -1766,7 +1802,7 @@ function tokenize_zig_source(raw_source) {
17661802 state = State.float; break;
17671803 }
17681804 default: {
1769 index -= 1;
1805 this.index -= 1;
17701806 state = State.int; break;
17711807 }
17721808 } break;
......@@ -1838,8 +1874,8 @@ function tokenize_zig_source(raw_source) {
18381874 case 'P':
18391875 state = State.float_exponent; break;
18401876 default: {
1841 index -= 1;
1842 result.loc.end = index;
1877 this.index -= 1;
1878 result.loc.end = this.index;
18431879 return result;
18441880 }
18451881 } break;
......@@ -1911,7 +1947,7 @@ function tokenize_zig_source(raw_source) {
19111947 case 'p':
19121948 case 'P':
19131949 state = State.float_exponent; break;
1914 default: result.loc.end = index;
1950 default: result.loc.end = this.index;
19151951 return result;
19161952 } break;
19171953 case State.float_exponent:
......@@ -1920,13 +1956,27 @@ function tokenize_zig_source(raw_source) {
19201956 case '+':
19211957 state = State.float; break;
19221958 default: {
1923 index -= 1;
1959 this.index -= 1;
19241960 state = State.float; break;
19251961 }
19261962 }
19271963 break;
1964
1965 case State.whitespace:
1966 switch(c) {
1967 case ' ':
1968 case '\n':
1969 case '\t':
1970 case '\r': {
1971 break;
1972 }
1973 default: {
1974 result.loc.end = this.index;
1975 return result;
1976 }
1977 }
19281978 }
1929 index += 1;
1979 this.index += 1;
19301980 }
19311981
19321982 //TODO: PORT
......@@ -1938,52 +1988,37 @@ function tokenize_zig_source(raw_source) {
19381988 // result.loc.start = sindex;
19391989 // }
19401990
1941 result.loc.end = index;
1991 result.loc.end = this.index;
19421992 return result;
19431993
19441994 }
1945
1946 let toks = []
1947
1948 for (let i = 0; i < raw_source.length * 2; i++) {
1949 const tok = next();
1950 toks.push(tok);
1951
1952 if (tok.tag == Tag.eof) {
1953 break;
1954 }
1955 }
1956
1957 return toks;
19581995}
19591996
19601997
1961function generate_html_for_src(src) {
1962 var toks = tokenize_zig_source(src);
1963 var html = [];
1964
1965 let offset = 0;
1966 for (let z = 0; z < toks.length; z++) {
1967 const t = toks[z];
1998const builtin_types = [
1999 "f16", "f32", "f64", "f80", "f128",
2000 "c_longdouble", "c_short", "c_ushort", "c_int", "c_uint",
2001 "c_long", "c_ulong", "c_longlong", "c_ulonglong", "c_char",
2002 "anyopaque", "void", "bool", "isize", "usize",
2003 "noreturn", "type", "anyerror", "comptime_int", "comptime_float",
2004];
19682005
1969 if(t.tag == Tag.eof)
1970 break;
1971
1972 const spanStart = `<span class="zig_${t.tag}">`
1973 const spanEnd = `</span>`
1974
1975 src = `${src.slice(0, t.loc.start + offset)}` + spanStart + `${src.slice(t.loc.start + offset)}`;
1976 offset += spanStart.length;
2006function isSimpleType(typeName) {
2007 return builtin_types.includes(typeName) || isIntType(typeName);
2008}
19772009
1978 src = `${src.slice(0, t.loc.end + offset)}` + spanEnd + `${src.slice(t.loc.end + offset)}`;
1979 offset += spanEnd.length;
2010function isIntType(typeName) {
2011 if (typeName[0] != 'u' && typeName[0] != 'i') return false;
2012 let i = 1;
2013 if (i == typeName.length) return false;
2014 for (; i < typeName.length; i += 1) {
2015 if (typeName[i] < '0' || typeName[i] > '9') return false;
19802016 }
2017 return true;
2018}
19812019
1982
1983 html.push(src);
1984
1985 return html.join("");
1986
2020function isSpecialIndentifier(identifier) {
2021 return ["null", "true", "false", ,"undefined"].includes(identifier);
19872022}
19882023
19892024//const fs = require('fs');
src/Autodoc.zig+7-6
......@@ -814,6 +814,7 @@ const DocData = struct {
814814 this: usize, // index in `types`
815815 declRef: *Scope.DeclStatus,
816816 declIndex: usize, // index into `decls`, alternative repr for `declRef`
817 declName: []const u8, // unresolved decl name
817818 builtinField: enum { len, ptr },
818819 fieldRef: FieldRef,
819820 refPath: []Expr,
......@@ -2282,7 +2283,7 @@ fn walkInstruction(
22822283
22832284 var path: std.ArrayListUnmanaged(DocData.Expr) = .{};
22842285 try path.append(self.arena, .{
2285 .string = file.zir.nullTerminatedString(extra.data.field_name_start),
2286 .declName = file.zir.nullTerminatedString(extra.data.field_name_start),
22862287 });
22872288
22882289 // Put inside path the starting index of each decl name that
......@@ -2304,7 +2305,7 @@ fn walkInstruction(
23042305 );
23052306
23062307 try path.append(self.arena, .{
2307 .string = file.zir.nullTerminatedString(lhs_extra.data.field_name_start),
2308 .declName = file.zir.nullTerminatedString(lhs_extra.data.field_name_start),
23082309 });
23092310 }
23102311 };
......@@ -3665,7 +3666,7 @@ fn tryResolveRefPath(
36653666 var i: usize = 0;
36663667 outer: while (i < path.len - 1) : (i += 1) {
36673668 const parent = path[i];
3668 const child_string = path[i + 1].string; // we expect to find a string union case
3669 const child_string = path[i + 1].declName; // we expect to find an unsolved decl
36693670
36703671 var resolved_parent = parent;
36713672 var j: usize = 0;
......@@ -3738,14 +3739,14 @@ fn tryResolveRefPath(
37383739 return;
37393740 }
37403741
3741 // If the last element is a string or a CTE, then we give up,
3742 // If the last element is a declName or a CTE, then we give up,
37423743 // otherwise we resovle the parent to it and loop again.
37433744 // NOTE: we assume that if we find a string, it's because of
37443745 // a CTE component somewhere in the path. We know that the path
37453746 // is not pending futher evaluation because we just checked!
37463747 const last = rp[rp.len - 1];
37473748 switch (last) {
3748 .comptimeExpr, .string => break :outer,
3749 .comptimeExpr, .declName => break :outer,
37493750 else => {
37503751 resolved_parent = last;
37513752 continue;
......@@ -3772,7 +3773,7 @@ fn tryResolveRefPath(
37723773 "TODO: handle `{s}`in tryResolveRefPath\nInfo: {}",
37733774 .{ @tagName(resolved_parent), resolved_parent },
37743775 );
3775 path[i + 1] = (try self.cteTodo("<match failure>")).expr;
3776 // path[i + 1] = (try self.cteTodo("<match failure>")).expr;
37763777 continue :outer;
37773778 },
37783779 .comptimeExpr, .call, .typeOf => {