diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-09-11 20:26:53 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-09-11 20:26:53 -0700 |
| commit | ab3ac291ac08435f7aba1fc8a53fe0a0290cc1e1 (patch) | |
| tree | 5f6dd2a4a7dc97a72e3652fff09399ed1cba8b83 /lib | |
| parent | 37cdb5dbf90acd61584bae4a6661d0a6f9b54295 (diff) | |
| parent | c97d64b677eb891144fb356e1f4b9011c60cc0e2 (diff) | |
| download | zig-ab3ac291ac08435f7aba1fc8a53fe0a0290cc1e1.tar.gz zig-ab3ac291ac08435f7aba1fc8a53fe0a0290cc1e1.zip | |
Merge remote-tracking branch 'origin/master' into llvm15
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/docs/main.js | 295 | ||||
| -rw-r--r-- | lib/std/child_process.zig | 2 | ||||
| -rw-r--r-- | lib/std/linked_list.zig | 2 |
3 files changed, 232 insertions, 67 deletions
diff --git a/lib/docs/main.js b/lib/docs/main.js index b02b061eb4..18886f37fb 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -203,7 +203,7 @@ var zigAnalysis; if (!("type" in resolvedExpr)) { return null; } - let type = zigAnalysis.types[resolvedExpr.type]; + let type = getType(resolvedExpr.type); outer: for (let i = 0; i < 10000; i += 1) { switch (type.kind) { @@ -212,7 +212,7 @@ var zigAnalysis; let child = type.child; let resolvedChild = resolveValue(child); if ("type" in resolvedChild) { - type = zigAnalysis.types[resolvedChild.type]; + type = getType(resolvedChild.type); continue; } else { return null; @@ -276,7 +276,7 @@ var zigAnalysis; } if ("declRef" in value.expr) { - value = zigAnalysis.decls[value.expr.declRef].value; + value = getDecl(value.expr.declRef).value; continue; } @@ -430,7 +430,7 @@ var zigAnalysis; curNav.pkgObjs.push(pkg); } - let currentType = zigAnalysis.types[pkg.main]; + let currentType = getType(pkg.main); curNav.declObjs = [currentType]; for (let i = 0; i < curNav.declNames.length; i += 1) { let childDecl = findSubDecl(currentType, curNav.declNames[i]); @@ -440,7 +440,7 @@ var zigAnalysis; let childDeclValue = resolveValue(childDecl.value).expr; if ("type" in childDeclValue) { - const t = zigAnalysis.types[childDeclValue.type]; + const t = getType(childDeclValue.type); if (t.kind != typeKinds.Fn) { childDecl = t; } @@ -478,19 +478,21 @@ var zigAnalysis; } if (lastIsDecl && last.kind === "const") { - let typeObj = zigAnalysis.types[resolveValue(last.value).expr.type]; - if (typeObj && typeObj.kind === typeKinds.Fn) { - return renderFn(last); + const value = resolveValue(last.value); + if ("type" in value.expr) { + let typeObj = getType(value.expr.type); + if (typeObj.kind === typeKinds.Fn) { + return renderFn(last); + } } - return renderValue(last); } } function renderDocTest(decl) { - if (!("decltest" in decl)) return; - const astNode = zigAnalysis.astNodes[decl.decltest]; + if (!decl.decltest) return; + const astNode = getAstNode(decl.decltest); domSectDocTests.classList.remove("hidden"); domDocTestsCode.innerHTML = astNode.code; } @@ -498,7 +500,7 @@ var zigAnalysis; function renderUnknownDecl(decl) { domDeclNoRef.classList.remove("hidden"); - let docs = zigAnalysis.astNodes[decl.src].docs; + let docs = getAstNode(decl.src).docs; if (docs != null) { domTldDocs.innerHTML = markdown(docs); } else { @@ -509,18 +511,18 @@ var zigAnalysis; } function typeIsErrSet(typeIndex) { - let typeObj = zigAnalysis.types[typeIndex]; + let typeObj = getType(typeIndex); return typeObj.kind === typeKinds.ErrorSet; } function typeIsStructWithNoFields(typeIndex) { - let typeObj = zigAnalysis.types[typeIndex]; + let typeObj = getType(typeIndex); if (typeObj.kind !== typeKinds.Struct) return false; return typeObj.fields.length == 0; } function typeIsGenericFn(typeIndex) { - let typeObj = zigAnalysis.types[typeIndex]; + let typeObj = getType(typeIndex); if (typeObj.kind !== typeKinds.Fn) { return false; } @@ -532,12 +534,12 @@ var zigAnalysis; let last = fnDecl.value.expr.refPath.length - 1; let lastExpr = fnDecl.value.expr.refPath[last]; console.assert("declRef" in lastExpr); - fnDecl = zigAnalysis.decls[lastExpr.declRef]; + fnDecl = getDecl(lastExpr.declRef); } let value = resolveValue(fnDecl.value); console.assert("type" in value.expr); - let typeObj = zigAnalysis.types[value.expr.type]; + let typeObj = getType(value.expr.type); domFnProtoCode.innerHTML = exprName(value.expr, { wantHtml: true, @@ -546,7 +548,7 @@ var zigAnalysis; }); let docsSource = null; - let srcNode = zigAnalysis.astNodes[fnDecl.src]; + let srcNode = getAstNode(fnDecl.src); if (srcNode.docs != null) { docsSource = srcNode.docs; } @@ -557,14 +559,14 @@ var zigAnalysis; if ("type" in retExpr) { let retIndex = retExpr.type; let errSetTypeIndex = null; - let retType = zigAnalysis.types[retIndex]; + let retType = getType(retIndex); if (retType.kind === typeKinds.ErrorSet) { errSetTypeIndex = retIndex; } else if (retType.kind === typeKinds.ErrorUnion) { errSetTypeIndex = retType.err.type; } if (errSetTypeIndex != null) { - let errSetType = zigAnalysis.types[errSetTypeIndex]; + let errSetType = getType(errSetTypeIndex); renderErrorSet(errSetType); } } @@ -578,7 +580,7 @@ var zigAnalysis; let call = zigAnalysis.calls[resolvedGenericRet.expr.call]; let resolvedFunc = resolveValue({ expr: call.func }); if (!("type" in resolvedFunc.expr)) return; - let callee = zigAnalysis.types[resolvedFunc.expr.type]; + let callee = getType(resolvedFunc.expr.type); if (!callee.generic_ret) return; resolvedGenericRet = resolveValue({ expr: callee.generic_ret }); } @@ -591,7 +593,7 @@ var zigAnalysis; } if (!("type" in resolvedGenericRet.expr)) return; - const genericType = zigAnalysis.types[resolvedGenericRet.expr.type]; + const genericType = getType(resolvedGenericRet.expr.type); if (isContainerType(genericType)) { renderContainer(genericType); } @@ -621,7 +623,7 @@ var zigAnalysis; domFnNoExamples.classList.add("hidden"); } - let protoSrcNode = zigAnalysis.astNodes[protoSrcIndex]; + let protoSrcNode = getAstNode(protoSrcIndex); if ( docsSource == null && protoSrcNode != null && @@ -639,13 +641,13 @@ var zigAnalysis; function renderFnParamDocs(fnDecl, typeObj) { let docCount = 0; - let fnNode = zigAnalysis.astNodes[fnDecl.src]; + let fnNode = getAstNode(fnDecl.src); let fields = fnNode.fields; let isVarArgs = fnNode.varArgs; for (let i = 0; i < fields.length; i += 1) { let field = fields[i]; - let fieldNode = zigAnalysis.astNodes[field]; + let fieldNode = getAstNode(field); if (fieldNode.docs != null) { docCount += 1; } @@ -659,7 +661,7 @@ var zigAnalysis; for (let i = 0; i < fields.length; i += 1) { let field = fields[i]; - let fieldNode = zigAnalysis.astNodes[field]; + let fieldNode = getAstNode(field); let docs = fieldNode.docs; if (fieldNode.docs == null) { continue; @@ -967,17 +969,17 @@ var zigAnalysis; } case "switchOp": { let condExpr = zigAnalysis.exprs[expr.switchOp.cond_index]; - let ast = zigAnalysis.astNodes[expr.switchOp.ast]; + let ast = getAstNode(expr.switchOp.src); let file_name = expr.switchOp.file_name; let outer_decl_index = expr.switchOp.outer_decl; - let outer_decl = zigAnalysis.types[outer_decl_index]; + let outer_decl = getType(outer_decl_index); let line = 0; // console.log(expr.switchOp) // console.log(outer_decl) while (outer_decl_index !== 0 && outer_decl.line_number > 0) { line += outer_decl.line_number; outer_decl_index = outer_decl.outer_decl; - outer_decl = zigAnalysis.types[outer_decl_index]; + outer_decl = getType(outer_decl_index); // console.log(outer_decl) } line += ast.line + 1; @@ -1028,8 +1030,8 @@ var zigAnalysis; case "fieldRef": { const enumObj = exprName({ type: expr.fieldRef.type }, opts); const field = - zigAnalysis.astNodes[enumObj.ast].fields[expr.fieldRef.index]; - const name = zigAnalysis.astNodes[field].name; + getAstNode(enumObj.src).fields[expr.fieldRef.index]; + const name = getAstNode(field).name; return name; } case "enumToInt": { @@ -1452,13 +1454,13 @@ var zigAnalysis; return print_lhs + " " + operator + " " + print_rhs; } case "errorSets": { - const errUnionObj = zigAnalysis.types[expr.errorSets]; + const errUnionObj = getType(expr.errorSets); let lhs = exprName(errUnionObj.lhs, opts); let rhs = exprName(errUnionObj.rhs, opts); return lhs + " || " + rhs; } case "errorUnion": { - const errUnionObj = zigAnalysis.types[expr.errorUnion]; + const errUnionObj = getType(expr.errorUnion); let lhs = exprName(errUnionObj.lhs, opts); let rhs = exprName(errUnionObj.rhs, opts); return lhs + "!" + rhs; @@ -1574,7 +1576,7 @@ var zigAnalysis; return exprName(exprArg, opts); } case "declRef": { - return zigAnalysis.decls[expr.declRef].name; + return getDecl(expr.declRef).name; } case "refPath": { return expr.refPath.map((x) => exprName(x, opts)).join("."); @@ -1611,7 +1613,7 @@ var zigAnalysis; let name = ""; let typeObj = expr.type; - if (typeof typeObj === "number") typeObj = zigAnalysis.types[typeObj]; + if (typeof typeObj === "number") typeObj = getType(typeObj); switch (typeObj.kind) { default: throw "TODO"; @@ -1865,7 +1867,7 @@ var zigAnalysis; if (fnObj.params) { let fields = null; let isVarArgs = false; - let fnNode = zigAnalysis.astNodes[fnObj.src]; + let fnNode = getAstNode(fnObj.src); fields = fnNode.fields; isVarArgs = fnNode.varArgs; @@ -1880,7 +1882,7 @@ var zigAnalysis; let paramValue = resolveValue({ expr: value }); if (fields != null) { - let paramNode = zigAnalysis.astNodes[fields[i]]; + let paramNode = getAstNode(fields[i]); if (paramNode.varArgs) { payloadHtml += "..."; @@ -2046,7 +2048,7 @@ var zigAnalysis; function shouldSkipParamName(typeRef, paramName) { let resolvedTypeRef = resolveValue({ expr: typeRef }); if ("type" in resolvedTypeRef) { - let typeObj = zigAnalysis.types[resolvedTypeRef.type]; + let typeObj = getType(resolvedTypeRef.type); if (typeObj.kind === typeKinds.Pointer) { let ptrObj = typeObj; if (getPtrSize(ptrObj) === pointerSizeEnum.One) { @@ -2067,7 +2069,7 @@ var zigAnalysis; if ( rootIsStd && typeObj === - zigAnalysis.types[zigAnalysis.packages[zigAnalysis.rootPkg].main] + getType(zigAnalysis.packages[zigAnalysis.rootPkg].main) ) { name = "std"; } else { @@ -2189,7 +2191,7 @@ var zigAnalysis; if (resolvedValue.expr.fieldRef) { const declRef = decl.value.expr.refPath[0].declRef; - const type = zigAnalysis.decls[declRef]; + const type = getDecl(declRef); domFnProtoCode.innerHTML = '<span class="tok-kw">const</span> ' + escapeHtml(decl.name) + @@ -2229,7 +2231,7 @@ var zigAnalysis; ";"; } - let docs = zigAnalysis.astNodes[decl.src].docs; + let docs = getAstNode(decl.src).docs; if (docs != null) { domTldDocs.innerHTML = markdown(docs); domTldDocs.classList.remove("hidden"); @@ -2246,7 +2248,7 @@ var zigAnalysis; ": " + typeValueName(declTypeRef, true, true); - let docs = zigAnalysis.astNodes[decl.src].docs; + let docs = getAstNode(decl.src).docs; if (docs != null) { domTldDocs.innerHTML = markdown(docs); domTldDocs.classList.remove("hidden"); @@ -2266,7 +2268,7 @@ var zigAnalysis; testsList ) { for (let i = 0; i < decls.length; i += 1) { - let decl = zigAnalysis.decls[decls[i]]; + let decl = getDecl(decls[i]); let declValue = resolveValue(decl.value); if (decl.isTest) { @@ -2282,7 +2284,7 @@ var zigAnalysis; if (decl.kind === "const") { if ("type" in declValue.expr) { // We have the actual type expression at hand. - const typeExpr = zigAnalysis.types[declValue.expr.type]; + const typeExpr = getType(declValue.expr.type); if (typeExpr.kind == typeKinds.Fn) { const funcRetExpr = resolveValue({ expr: typeExpr.ret, @@ -2310,7 +2312,7 @@ var zigAnalysis; typesList.push(decl); } } - } else if ("typeRef" in declValue) { + } else if (declValue.typeRef) { if ("type" in declValue.typeRef && declValue.typeRef == typeTypeId) { // We don't know what the type expression is, but we know it's a type. typesList.push(decl); @@ -2324,7 +2326,7 @@ var zigAnalysis; } } function renderSourceFileLink(decl) { - let srcNode = zigAnalysis.astNodes[decl.src]; + let srcNode = getAstNode(decl.src); return "<a style=\"float: right;\" href=\"" + sourceFileUrlTemplate.replace("{{file}}", @@ -2377,7 +2379,7 @@ var zigAnalysis; testsList.sort(byNameProperty); if (container.src != null) { - let docs = zigAnalysis.astNodes[container.src].docs; + let docs = getAstNode(container.src).docs; if (docs != null) { domTldDocs.innerHTML = markdown(docs); domTldDocs.classList.remove("hidden"); @@ -2457,7 +2459,7 @@ var zigAnalysis; }); tdFnSrc.innerHTML = renderSourceFileLink(decl); - let docs = zigAnalysis.astNodes[decl.src].docs; + let docs = getAstNode(decl.src).docs; if (docs != null) { tdDesc.innerHTML = shortDescMarkdown(docs); } else { @@ -2467,12 +2469,12 @@ var zigAnalysis; domSectFns.classList.remove("hidden"); } - let containerNode = zigAnalysis.astNodes[container.src]; + let containerNode = getAstNode(container.src); if (containerNode.fields && containerNode.fields.length > 0) { resizeDomList(domListFields, containerNode.fields.length, "<div></div>"); for (let i = 0; i < containerNode.fields.length; i += 1) { - let fieldNode = zigAnalysis.astNodes[containerNode.fields[i]]; + let fieldNode = getAstNode(containerNode.fields[i]); let divDom = domListFields.children[i]; let fieldName = fieldNode.name; let docs = fieldNode.docs; @@ -2528,7 +2530,7 @@ var zigAnalysis; tdType.innerHTML = typeValueName(typeOfDecl(decl), true, true); - let docs = zigAnalysis.astNodes[decl.src].docs; + let docs = getAstNode(decl.src).docs; if (docs != null) { tdDesc.innerHTML = shortDescMarkdown(docs); } else { @@ -2561,7 +2563,7 @@ var zigAnalysis; wantLink: true, }); - let docs = zigAnalysis.astNodes[decl.src].docs; + let docs = getAstNode(decl.src).docs; if (docs != null) { tdDesc.innerHTML = shortDescMarkdown(docs); } else { @@ -2594,7 +2596,7 @@ var zigAnalysis; wantLink: true, }); - let docs = zigAnalysis.astNodes[decl.src].docs; + let docs = getAstNode(decl.src).docs; if (docs != null) { tdDesc.innerHTML = shortDescMarkdown(docs); } else { @@ -2668,7 +2670,7 @@ var zigAnalysis; function findTypeTypeId() { for (let i = 0; i < zigAnalysis.types.length; i += 1) { - if (zigAnalysis.types[i].kind == typeKinds.Type) { + if (getType(i).kind == typeKinds.Type) { return i; } } @@ -2732,11 +2734,11 @@ var zigAnalysis; if ("value" in parentType) { const rv = resolveValue(parentType.value); if ("type" in rv.expr) { - const t = zigAnalysis.types[rv.expr.type]; + const t = getType(rv.expr.type); if (t.kind == typeKinds.Fn && t.generic_ret != null) { const rgr = resolveValue({ expr: t.generic_ret }); if ("type" in rgr.expr) { - parentType = zigAnalysis.types[rgr.expr.type]; + parentType = getType(rgr.expr.type); } } } @@ -2746,7 +2748,7 @@ var zigAnalysis; if (!parentType.pubDecls) return null; for (let i = 0; i < parentType.pubDecls.length; i += 1) { let declIndex = parentType.pubDecls[i]; - let childDecl = zigAnalysis.decls[declIndex]; + let childDecl = getDecl(declIndex); if (childDecl.name === childName) { return childDecl; } @@ -2754,7 +2756,7 @@ var zigAnalysis; if (!parentType.privDecls) return null; for (let i = 0; i < parentType.privDecls.length; i += 1) { let declIndex = parentType.privDecls[i]; - let childDecl = zigAnalysis.decls[declIndex]; + let childDecl = getDecl(declIndex); if (childDecl.name === childName) { return childDecl; } @@ -2805,7 +2807,7 @@ var zigAnalysis; let stack = [ { declNames: [], - type: zigAnalysis.types[pkg.main], + type: getType(pkg.main), }, ]; while (stack.length !== 0) { @@ -2819,7 +2821,7 @@ var zigAnalysis; let mainDeclIndex = t.pubDecls[declI]; if (list[mainDeclIndex] != null) continue; - let decl = zigAnalysis.decls[mainDeclIndex]; + let decl = getDecl(mainDeclIndex); let declVal = resolveValue(decl.value); let declNames = item.declNames.concat([decl.name]); list[mainDeclIndex] = { @@ -2827,7 +2829,7 @@ var zigAnalysis; declNames: declNames, }; if ("type" in declVal.expr) { - let value = zigAnalysis.types[declVal.expr.type]; + let value = getType(declVal.expr.type); if (declCanRepresentTypeKind(value.kind)) { canonTypeDecls[declVal.type] = mainDeclIndex; } @@ -2843,7 +2845,7 @@ var zigAnalysis; if (value.kind == typeKinds.Fn && value.generic_ret != null) { let resolvedVal = resolveValue({ expr: value.generic_ret }); if ("type" in resolvedVal.expr) { - let generic_type = zigAnalysis.types[resolvedVal.expr.type]; + let generic_type = getType(resolvedVal.expr.type); if (isContainerType(generic_type)) { stack.push({ declNames: declNames, @@ -3394,11 +3396,11 @@ var zigAnalysis; let canonPath = getCanonDeclPath(declIndex); if (canonPath == null) continue; - let decl = zigAnalysis.decls[declIndex]; + let decl = getDecl(declIndex); let lastPkgName = canonPath.pkgNames[canonPath.pkgNames.length - 1]; let fullPathSearchText = lastPkgName + "." + canonPath.declNames.join("."); - let astNode = zigAnalysis.astNodes[decl.src]; + let astNode = getAstNode(decl.src); let fileAndDocs = ""; //zigAnalysis.files[astNode.file]; // TODO: understand what this piece of code is trying to achieve // also right now `files` are expressed as a hashmap. @@ -3513,4 +3515,169 @@ var zigAnalysis; function byNameProperty(a, b) { return operatorCompare(a.name, b.name); } + + + function getDecl(idx) { + const decl = zigAnalysis.decls[idx]; + return { + name: decl[0], + kind: decl[1], + isTest: decl[2], + src: decl[3], + value: decl[4], + decltest: decl[5], + }; + } + + function getAstNode(idx) { + const ast = zigAnalysis.astNodes[idx]; + return { + file: ast[0], + line: ast[1], + col: ast[2], + name: ast[3], + code: ast[4], + docs: ast[5], + fields: ast[6], + comptime: ast[7], + }; + } + + function getType(idx){ + const ty = zigAnalysis.types[idx]; + switch(ty[0]) { + default: + throw "unhandled type kind!"; + case 0: // Unanalyzed + throw "unanalyzed type!"; + case 1: // Type + case 2: // Void + case 3: // Bool + case 4: // NoReturn + case 5: // Int + case 6: // Float + return { kind: ty[0], name: ty[1]}; + case 7: // Pointer + return { + kind: ty[0], + size: ty[1], + child: ty[2], + sentinel: ty[3], + align: ty[4], + address_space: ty[5], + bit_start: ty[6], + host_size: ty[7], + is_ref: ty[8], + is_allowzero: ty[9], + is_mutable: ty[10], + is_volatile: ty[11], + has_sentinel: ty[12], + has_align: ty[13], + has_addrspace: ty[14], + has_bit_range: ty[15], + }; + case 8: // Array + return { + kind: ty[0], + len: ty[1], + child: ty[2], + sentinel: ty[3], + }; + case 9: // Struct + return { + kind: ty[0], + name: ty[1], + src: ty[2], + privDecls: ty[3], + pubDecls: ty[4], + fields: ty[5], + line_number: ty[6], + outer_decl: ty[7], + }; + case 10: // ComptimeExpr + case 11: // ComptimeFloat + case 12: // ComptimeInt + case 13: // Undefined + case 14: // Null + return { kind: ty[0], name: ty[1] }; + case 15: // Optional + return { + kind: ty[0], + name: ty[1], + child: ty[2], + }; + case 16: // ErrorUnion + return { + kind: ty[0], + lhs: ty[1], + rhs: ty[2], + }; + case 17: // InferredErrorUnion + return { + kind: ty[0], + payload: ty[1], + }; + case 18: // ErrorSet + return { + kind: ty[0], + name: ty[1], + fields: ty[2], + }; + case 19: // Enum + return { + kind: ty[0], + name: ty[1], + src: ty[2], + privDecls: ty[3], + pubDecls: ty[4], + }; + case 20: // Union + return { + kind: ty[0], + name: ty[1], + src: ty[2], + privDecls: ty[3], + pubDecls: ty[4], + fields: ty[5], + }; + case 21: // Fn + return { + kind: ty[0], + name: ty[1], + src: ty[2], + ret: ty[3], + generic_ret: ty[4], + params: ty[5], + lib_name: ty[6], + is_var_args: ty[7], + is_inferred_error: ty[8], + has_lib_name: ty[9], + has_cc: ty[10], + cc: ty[11], + align: ty[12], + has_align: ty[13], + is_test: ty[14], + is_extern: ty[15], + }; + case 22: // BoundFn + return { kind: ty[0], name: ty[1] }; + case 23: // Opaque + return { + kind: ty[0], + name: ty[1], + src: ty[2], + privDecls: ty[3], + pubDecls: ty[4], + }; + case 24: // Frame + case 25: // AnyFrame + case 26: // Vector + case 27: // EnumLiteral + return { kind: ty[0], name: ty[1] }; + } + } + })(); + + + diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index fb521eb784..f1604bb86c 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -508,7 +508,7 @@ pub const ChildProcess = struct { // it, that's the error code returned by the child process. _ = std.os.poll(&fd, 0) catch unreachable; - // According to eventfd(2) the descriptro is readable if the counter + // According to eventfd(2) the descriptor is readable if the counter // has a value greater than 0 if ((fd[0].revents & std.os.POLL.IN) != 0) { const err_int = try readIntFd(err_pipe[0]); diff --git a/lib/std/linked_list.zig b/lib/std/linked_list.zig index 5039e16583..577bae3d38 100644 --- a/lib/std/linked_list.zig +++ b/lib/std/linked_list.zig @@ -2,8 +2,6 @@ const std = @import("std.zig"); const debug = std.debug; const assert = debug.assert; const testing = std.testing; -const mem = std.mem; -const Allocator = mem.Allocator; /// A singly-linked list is headed by a single forward pointer. The elements /// are singly linked for minimum space and pointer manipulation overhead at |
