diff --git a/src/components/DSValue.vue b/src/components/DSValue.vue index d236df0..23b7c42 100644 --- a/src/components/DSValue.vue +++ b/src/components/DSValue.vue @@ -2,6 +2,8 @@ import type { CppType, MemoryCell } from '~/composables/interpreter/types' import { computed } from 'vue' import AddressLink from '~/components/AddressLink.vue' +import { formatType } from '~/composables/interpreter/helpers' +import { structFieldOffset } from '~/composables/interpreter/memory' import { useInterpreterContext } from '~/composables/useInterpreterContext' const props = defineProps<{ @@ -10,6 +12,9 @@ const props = defineProps<{ indexPrefix?: string /** Field address to highlight (from referenced-by hover or arrow hover) */ highlightedFieldAddress?: number | null + /** Statement LHS/RHS addresses for per-field code highlighting */ + statementLhsAddresses?: ReadonlySet + statementRhsAddresses?: ReadonlySet }>() const emit = defineEmits<{ @@ -19,18 +24,6 @@ const emit = defineEmits<{ const context = useInterpreterContext() -function formatType(type: CppType): string { - if (typeof type === 'string') - return type - if (type.type === 'pointer') - return `${formatType(type.to)}*` - if (type.type === 'array') - return `${formatType(type.of)}[${type.size}]` - if (type.type === 'struct') - return type.name - return '?' -} - // ---- Computed data ---- /** Fresh cell value — re-reads from reactive memory each step */ @@ -78,11 +71,37 @@ const structFields = computed((): FieldEntry[] => { const structDef = context.structs[v.name] if (!structDef) return [] - return Object.keys(structDef).map((name, i) => ({ - name, - cell: context.memory.cells.get(v.base + 1 + i), - type: structDef[name], - })) + const entries: FieldEntry[] = [] + + /** Recursively flatten array elements with subscript prefix (handles n-d arrays) */ + function flattenArray(prefix: string, elemType: CppType, cell: MemoryCell | undefined) { + if (!cell) + return + const arrVal = cell.value + if (typeof arrVal !== 'object' || arrVal.type !== 'array') + return + for (let i = 0; i < arrVal.length; i++) { + const elemCell = context.memory.cells.get(arrVal.base + 1 + i) + const subscript = `${prefix}[${i}]` + // Nested array: recurse + if (typeof elemType === 'object' && elemType.type === 'array' && elemCell) { + flattenArray(subscript, elemType.of, elemCell) + } + else { + entries.push({ name: subscript, cell: elemCell, type: elemType }) + } + } + } + + for (const [name, fieldType] of Object.entries(structDef)) { + const fieldCell = context.memory.cells.get(v.base + 1 + structFieldOffset(name, structDef)) + if (typeof fieldType === 'object' && fieldType.type === 'array' && fieldCell) { + flattenArray(name, fieldType.of, fieldCell) + continue + } + entries.push({ name, cell: fieldCell, type: fieldType }) + } + return entries }) interface ArrayEntry { @@ -135,7 +154,15 @@ const arrayElements = computed((): ArrayEntry[] => { /> -
+
{{ elem.prefix }} {