import {Register, RegisterAccess, RegisterDetail, Note} from "@/utils/register_parser"; export const parseDescriptionDefault = (reg: Register, description: string) => { const descriptionLines = description.split('\n'); let currentAccess: 'read' | 'write' | 'common' | null = null; let accessData: RegisterAccess = { operations: [], notes: [] }; // Prepare a new RegisterDetail for this description block const detail: RegisterDetail = { read: undefined, write: undefined, common: undefined, text: ''}; // Footnote multiline state let inFootnote = false; let footnoteBaseIndent = 0; // let footnoteTarget: 'global' | 'access' | null = null; let currentFootnote: Note | null = null; const endFootnoteIfActive = () => { inFootnote = false; footnoteBaseIndent = 0; // footnoteTarget = null; currentFootnote = null; }; for (let idx = 0; idx < descriptionLines.length; idx++) { const line = descriptionLines[idx]; reg.source.push(line); const trimmedLine = line.trim(); if (trimmedLine.startsWith('//')) continue; reg.search += line.toLowerCase() + " "; const spaces_at_start = line.match(/^(\s*)/)?.[0].length || 0; if (line.includes('Issue 4 Only')) reg.issue_4_only = true; // Handle multiline footnote continuation if (inFootnote) { if (spaces_at_start > footnoteBaseIndent && trimmedLine.length > 0) { // continuation line; append preserving original line (trim left to the base indent) const continuation = line.substring(footnoteBaseIndent + 1); // +1 to skip at least one extra indent if (currentFootnote) { currentFootnote.text += `\n${continuation.trimEnd()}`; } continue; } else { // indentation returned -> end footnote, and fall through to process this line normally endFootnoteIfActive(); } } // Access state markers if (trimmedLine.startsWith('(R)')) { if (currentAccess) { // finalize previous access block into detail detail[currentAccess] = accessData; } accessData = { operations: [], notes: [] }; currentAccess = 'read'; continue; } if (trimmedLine.startsWith('(W)')) { if (currentAccess) { detail[currentAccess] = accessData; } accessData = { operations: [], notes: [] }; currentAccess = 'write'; continue; } if (trimmedLine.startsWith('(R/W')) { if (currentAccess) { detail[currentAccess] = accessData; } accessData = { operations: [], notes: [] }; currentAccess = 'common'; continue; } // New top-level text block (no leading spaces) if (line.startsWith(trimmedLine)) { if (currentAccess) { detail[currentAccess] = accessData; } accessData = { operations: [], notes: [] }; currentAccess = null; } // Start of a footnote (works both inside and outside an access block) if (trimmedLine.startsWith('*')) { const noteMatch = trimmedLine.match(/^(\*+)\s*(.*)/); if (noteMatch) { const note: Note = { ref: noteMatch[1], text: noteMatch[2] }; if (currentAccess) { accessData.notes.push(note); // footnoteTarget = 'access'; } else { reg.notes.push(note); // footnoteTarget = 'global'; } currentFootnote = note; inFootnote = true; footnoteBaseIndent = spaces_at_start; continue; } } if (currentAccess) { const bitMatch = trimmedLine.match(/^(bits?|bit)\s+([\d:-]+)\s*=\s*(.*)/); // const valueMatch = !line.match(/^\s+/) && trimmedLine.match(/^([01\s]+)\s*=\s*(.*)/); if (bitMatch) { let bitDescription = bitMatch[3]; const footnoteMatch = bitDescription.match(/(\*+)$/); let footnoteRef: string | undefined = undefined; if (footnoteMatch) { footnoteRef = footnoteMatch[1]; bitDescription = bitDescription.substring(0, bitDescription.length - footnoteRef.length).trim(); } accessData.operations.push({ bits: bitMatch[2], description: bitDescription, footnoteRef: footnoteRef, }); // } else if (valueMatch) { // console.error("VALUE MATCH",valueMatch); // accessData.operations.push({ // bits: valueMatch[1].trim().replace(/\s/g, ''), // description: valueMatch[2].trim(), // }); } else if (trimmedLine) { if(spaces_at_start == 2) { reg.text += `${line}\n`; continue; } if (line.match(/^\s+/) && accessData.operations.length > 0) { accessData.operations[accessData.operations.length - 1].description += `\n${line}`; } else { if (!accessData.description) { accessData.description = ''; } accessData.description += `\n${trimmedLine}`; } } } else { if (trimmedLine) { detail.text += `${line}\n`; } } } // close any dangling footnote if (inFootnote) { endFootnoteIfActive(); } if (currentAccess) { detail[currentAccess] = accessData; } // Push the parsed detail into modes reg.modes = reg.modes || []; reg.modes.push(detail); };