From 20764d74d3285239b8f456189f8f688a44a486d5 Mon Sep 17 00:00:00 2001 From: "D. Rimron-Soutter" Date: Fri, 10 Oct 2025 13:46:21 +0100 Subject: [PATCH] Moving towards multiple register parsers, to handle more exotic register types --- src/app/registers/RegisterBrowser.tsx | 15 ++------- src/app/registers/RegisterDetail.tsx | 38 ++++++++++++----------- src/app/registers/[hex]/page.tsx | 3 +- src/utils/register_parser.ts | 18 ++++++----- src/utils/register_parsers/reg_default.ts | 30 +++++++++++++----- src/utils/register_parsers/reg_f0.ts | 21 +++++++------ 6 files changed, 69 insertions(+), 56 deletions(-) diff --git a/src/app/registers/RegisterBrowser.tsx b/src/app/registers/RegisterBrowser.tsx index 47cc47d..4d74ac1 100644 --- a/src/app/registers/RegisterBrowser.tsx +++ b/src/app/registers/RegisterBrowser.tsx @@ -74,12 +74,6 @@ export default function RegisterBrowser({ registers }: RegisterBrowserProps) { register.description.toLowerCase().includes(searchTerm.toLowerCase()) ); - const getDefaultActiveKey = (register: Register) => { - if (register.common) return 'common'; - if (register.read) return 'read'; - if (register.write) return 'write'; - return ''; - }; return ( @@ -92,12 +86,9 @@ export default function RegisterBrowser({ registers }: RegisterBrowserProps) { /> - {filteredRegisters.map(register => { - const defaultActiveKey = getDefaultActiveKey(register); - return ( - - ); - })} + {filteredRegisters.map(register => ( + + ))} ); diff --git a/src/app/registers/RegisterDetail.tsx b/src/app/registers/RegisterDetail.tsx index 443daf4..b32c22a 100644 --- a/src/app/registers/RegisterDetail.tsx +++ b/src/app/registers/RegisterDetail.tsx @@ -10,15 +10,12 @@ import * as Icon from 'react-bootstrap-icons'; /** * A client-side component that displays the details of a single register. * @param register The register object to display. - * @param defaultActiveKey The default active tab to display. * @returns A React component that displays the register details. */ export default function RegisterDetail({ register, - defaultActiveKey, }: { register: Register; - defaultActiveKey?: string; }) { const [showSource, setShowSource] = useState(false); @@ -27,9 +24,7 @@ export default function RegisterDetail({ {register.hex_address} ( {register.dec_address} )   - {/**/} {register.name} {register.issue_4_only && Issue 4 Only} - {/**/}
@@ -45,20 +40,27 @@ export default function RegisterDetail({
- - {register.common && {renderAccess(register.common)}} - {register.read && {renderAccess(register.read)}} - {register.write && {renderAccess(register.write)}} - - {register.notes.map((note, index) => ( -

{note.ref} {note.text}

+ { register.modes.map((mode, idx) => ( +
0 ? 'mt-4' : ''}> + {register.modes.length > 1 && ( +
Mode {idx + 1}
+ )} + + {mode.common && {renderAccess(mode.common)}} + {mode.read && {renderAccess(mode.read)}} + {mode.write && {renderAccess(mode.write)}} + + {mode.notes && mode.notes.map((note, index) => ( +

{note.ref} {note.text}

+ ))} + {mode.text && mode.text.length > 0 && ( +
+
Notes:
+
{mode.text}
+
+ )} +
))} - {register.text && register.text.length > 0 && ( -
-
Notes:
-
{register.text}
-
- )}
diff --git a/src/app/registers/[hex]/page.tsx b/src/app/registers/[hex]/page.tsx index 635f0e4..0622dcb 100644 --- a/src/app/registers/[hex]/page.tsx +++ b/src/app/registers/[hex]/page.tsx @@ -13,7 +13,6 @@ export default async function RegisterDetailPage({ params }: { params: { hex: st if (!register) return notFound(); - const defaultActiveKey = register.common ? 'common' : (register.read ? 'read' : (register.write ? 'write' : undefined)); return ( @@ -21,7 +20,7 @@ export default async function RegisterDetailPage({ params }: { params: { hex: st ← Back to Registers - + ); diff --git a/src/utils/register_parser.ts b/src/utils/register_parser.ts index 0e83084..da49f35 100644 --- a/src/utils/register_parser.ts +++ b/src/utils/register_parser.ts @@ -18,16 +18,21 @@ export interface RegisterAccess { operations: RegisterBitwiseOperation[]; notes: Note[]; } -export interface Register { - hex_address: string; - dec_address: number | string; - name: string; - description: string; + +export interface RegisterDetail { read?: RegisterAccess; write?: RegisterAccess; common?: RegisterAccess; text: string; notes: Note[]; +} + +export interface Register { + hex_address: string; + dec_address: number | string; + name: string; + modes: RegisterDetail[]; + description: string; issue_4_only: boolean; source: string[]; } @@ -84,8 +89,7 @@ export function processRegisterBlock(paragraph: string, registers: Register[]) { dec_address: dec, name: regName, description: description, - notes: [], - text: "", + modes: [], issue_4_only: false, source: [] }; diff --git a/src/utils/register_parsers/reg_default.ts b/src/utils/register_parsers/reg_default.ts index 42713fc..4ebb55f 100644 --- a/src/utils/register_parsers/reg_default.ts +++ b/src/utils/register_parsers/reg_default.ts @@ -1,9 +1,11 @@ -import {Register, RegisterAccess} from "@/utils/register_parser"; +import {Register, RegisterAccess, RegisterDetail} 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: '', notes: [] }; for (const line of descriptionLines) { if (line.includes('Issue 4 Only')) reg.issue_4_only = true; @@ -14,25 +16,34 @@ export const parseDescriptionDefault = (reg: Register, description: string) => { if (trimmedLine.startsWith('//')) continue; if (trimmedLine.startsWith('(R)')) { - if (currentAccess) reg[currentAccess] = accessData; + if (currentAccess) { + // finalize previous access block into detail + detail[currentAccess] = accessData; + } accessData = { operations: [], notes: [] }; currentAccess = 'read'; continue; } if (trimmedLine.startsWith('(W)')) { - if (currentAccess) reg[currentAccess] = accessData; + if (currentAccess) { + detail[currentAccess] = accessData; + } accessData = { operations: [], notes: [] }; currentAccess = 'write'; continue; } if (trimmedLine.startsWith('(R/W')) { - if (currentAccess) reg[currentAccess] = accessData; + if (currentAccess) { + detail[currentAccess] = accessData; + } accessData = { operations: [], notes: [] }; currentAccess = 'common'; continue; } if (line.startsWith(trimmedLine)) { - if (currentAccess) reg[currentAccess] = accessData; + if (currentAccess) { + detail[currentAccess] = accessData; + } accessData = { operations: [], notes: [] }; currentAccess = null; } @@ -81,17 +92,20 @@ export const parseDescriptionDefault = (reg: Register, description: string) => { if (trimmedLine.startsWith('*')) { const noteMatch = trimmedLine.match(/^(\*+)\s*(.*)/); if (noteMatch) { - reg.notes.push({ + detail.notes.push({ ref: noteMatch[1], text: noteMatch[2], }); } } else if (trimmedLine) { - reg.text += `${line}\n`; + detail.text += `${line}\n`; } } } if (currentAccess) { - reg[currentAccess] = accessData; + detail[currentAccess] = accessData; } + // Push the parsed detail into modes + reg.modes = reg.modes || []; + reg.modes.push(detail); }; \ No newline at end of file diff --git a/src/utils/register_parsers/reg_f0.ts b/src/utils/register_parsers/reg_f0.ts index 8bca351..1c7a68a 100644 --- a/src/utils/register_parsers/reg_f0.ts +++ b/src/utils/register_parsers/reg_f0.ts @@ -1,12 +1,13 @@ // Special-case parser for 0xF0 (XDEV CMD): treat headings beginning with '*' inside access blocks // as descriptive text instead of notes, so sub-modes become part of the section descriptions. -import {Register, RegisterAccess} from "@/utils/register_parser"; +import {Register, RegisterAccess, RegisterDetail} from "@/utils/register_parser"; export const parseDescriptionF0 = (reg: Register, description: string) => { const descriptionLines = description.split('\n'); let currentAccess: 'read' | 'write' | 'common' | null = null; let accessData: RegisterAccess = { operations: [], notes: [] }; + const detail: RegisterDetail = { read: undefined, write: undefined, common: undefined, text: '', notes: [] }; for (const line of descriptionLines) { if (line.includes('Issue 4 Only')) reg.issue_4_only = true; @@ -17,25 +18,25 @@ export const parseDescriptionF0 = (reg: Register, description: string) => { if (trimmedLine.startsWith('//')) continue; if (trimmedLine.startsWith('(R)')) { - if (currentAccess) reg[currentAccess] = accessData; + if (currentAccess) detail[currentAccess] = accessData; accessData = { operations: [], notes: [] }; currentAccess = 'read'; continue; } if (trimmedLine.startsWith('(W)')) { - if (currentAccess) reg[currentAccess] = accessData; + if (currentAccess) detail[currentAccess] = accessData; accessData = { operations: [], notes: [] }; currentAccess = 'write'; continue; } if (trimmedLine.startsWith('(R/W')) { - if (currentAccess) reg[currentAccess] = accessData; + if (currentAccess) detail[currentAccess] = accessData; accessData = { operations: [], notes: [] }; currentAccess = 'common'; continue; } if (line.startsWith(trimmedLine)) { - if (currentAccess) reg[currentAccess] = accessData; + if (currentAccess) detail[currentAccess] = accessData; accessData = { operations: [], notes: [] }; currentAccess = null; } @@ -79,20 +80,22 @@ export const parseDescriptionF0 = (reg: Register, description: string) => { } } else { if (trimmedLine.startsWith('*')) { - // Outside access blocks, keep notes as-is + // Outside access blocks, keep notes as-is but attach to detail now const noteMatch = trimmedLine.match(/^(\*+)\s*(.*)/); if (noteMatch) { - reg.notes.push({ + detail.notes.push({ ref: noteMatch[1], text: noteMatch[2], }); } } else if (trimmedLine) { - reg.text += `${line}\n`; + detail.text += `${line}\n`; } } } if (currentAccess) { - reg[currentAccess] = accessData; + detail[currentAccess] = accessData; } + reg.modes = reg.modes || []; + reg.modes.push(detail); };