Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 13x 3x 25x 5x 18x 5x 13x 3x 9x 15x 15x 2x 2x 2x 13x 13x 13x 15x 15x 15x 15x 15x | /**
* Assignment Handler Utilities
*
* Common utilities shared across assignment handlers to reduce duplication.
* Issue #707: Extracted from RegisterHandlers.ts and AccessPatternHandlers.ts.
*/
import IRegisterNameResult from "./IRegisterNameResult";
/**
* Validate that 'this' is being used within a scope context.
* Throws if currentScope is not set.
*
* @param currentScope - The current scope name or null
* @throws Error if 'this' is used outside a scope
*/
function validateScopeContext(currentScope: string | null): void {
if (!currentScope) {
throw new Error("Error: 'this' can only be used inside a scope");
}
}
/**
* Validate that compound assignment operators are not used with bit field access.
*
* @param isCompound - Whether this is a compound assignment
* @param cnextOp - The C-Next operator being used
* @throws Error if compound operator is used with bit fields
*/
function validateNoCompoundForBitAccess(
isCompound: boolean,
cnextOp: string,
): void {
if (isCompound) {
throw new Error(
`Compound assignment operators not supported for bit field access: ${cnextOp}`,
);
}
}
/**
* Validate write-only register assignment value.
* Throws if trying to clear bits on a write-only register.
*
* @param value - The value being assigned
* @param targetName - The full register name for error messages
* @param bitIndex - The bit index expression for error messages
* @param isSingleBit - True for single bit access, false for bit range
* @throws Error if attempting to clear bits on write-only register
*/
function validateWriteOnlyValue(
value: string,
targetName: string,
bitIndex: string,
isSingleBit: boolean,
): void {
if (isSingleBit && (value === "false" || value === "0")) {
throw new Error(
`Cannot assign false to write-only register bit ${targetName}[${bitIndex}]. ` +
`Use the corresponding CLEAR register to clear bits.`,
);
}
if (!isSingleBit && value === "0") {
throw new Error(
`Cannot assign 0 to write-only register bits ${targetName}[${bitIndex}]. ` +
`Use the corresponding CLEAR register to clear bits.`,
);
}
}
/**
* Build a scoped register name from scope and identifier parts.
*
* @param scopeName - The scope name prefix
* @param parts - The identifier parts (register name, member name)
* @returns The full scoped register name (e.g., "Scope_Register_Member")
*/
function buildScopedRegisterName(
scopeName: string,
parts: readonly string[],
): string {
return `${scopeName}_${parts.join("_")}`;
}
/**
* Build register name with automatic scope detection.
*
* @param identifiers - The identifier chain
* @param isKnownScope - Function to check if an identifier is a known scope
* @returns Object with fullName, regName, and isScoped flag
*/
function buildRegisterNameWithScopeDetection(
identifiers: readonly string[],
isKnownScope: (name: string) => boolean,
): IRegisterNameResult {
const leadingId = identifiers[0];
if (isKnownScope(leadingId) && identifiers.length >= 3) {
// Scoped: Scope.Register.Member
const regName = `${leadingId}_${identifiers[1]}`;
const fullName = `${regName}_${identifiers[2]}`;
return { fullName, regName, isScoped: true };
} else {
// Non-scoped: Register.Member
const regName = leadingId;
const fullName = `${leadingId}_${identifiers[1]}`;
return { fullName, regName, isScoped: false };
}
}
/**
* Assignment Handler Utilities
*/
class AssignmentHandlerUtils {
static readonly validateScopeContext = validateScopeContext;
static readonly validateNoCompoundForBitAccess =
validateNoCompoundForBitAccess;
static readonly validateWriteOnlyValue = validateWriteOnlyValue;
static readonly buildScopedRegisterName = buildScopedRegisterName;
static readonly buildRegisterNameWithScopeDetection =
buildRegisterNameWithScopeDetection;
}
export default AssignmentHandlerUtils;
|