@@ -1414,6 +1414,94 @@ The first cast is reified as a `thunk`, the second one resolves it and eliminate
14141414 andBool lookupTy(TY_DEST_INNER) ==K lookupTy(TY_SRC_OUTER) // and is well-formed (invariant)
14151415```
14161416
1417+ Casting a byte array/slice to an integer reinterprets the bytes in little-endian order.
1418+
1419+ ``` k
1420+ rule <k> #cast(
1421+ Range(ELEMS),
1422+ castKindTransmute,
1423+ _TY_SOURCE,
1424+ TY_TARGET
1425+ )
1426+ =>
1427+ #intAsType(
1428+ #littleEndianFromBytes(ELEMS),
1429+ size(ELEMS) *Int 8,
1430+ #numTypeOf(lookupTy(TY_TARGET))
1431+ )
1432+ ...
1433+ </k>
1434+ requires #isIntType(lookupTy(TY_TARGET))
1435+ andBool size(ELEMS) *Int 8 ==Int #bitWidth(#numTypeOf(lookupTy(TY_TARGET)))
1436+ andBool #areLittleEndianBytes(ELEMS)
1437+ [preserves-definedness] // ensures #numTypeOf is defined
1438+
1439+ syntax Bool ::= #areLittleEndianBytes ( List ) [function, total]
1440+ // -------------------------------------------------------------
1441+ rule #areLittleEndianBytes(.List) => true
1442+ rule #areLittleEndianBytes(ListItem(Integer(_, 8, false)) REST)
1443+ => #areLittleEndianBytes(REST)
1444+ rule #areLittleEndianBytes(ListItem(_OTHER) _) => false [owise]
1445+
1446+ syntax Int ::= #littleEndianFromBytes ( List ) [function]
1447+ // -----------------------------------------------------
1448+ rule #littleEndianFromBytes(.List) => 0
1449+ rule #littleEndianFromBytes(ListItem(Integer(BYTE, 8, false)) REST)
1450+ => BYTE +Int 256 *Int #littleEndianFromBytes(REST)
1451+ ```
1452+
1453+ Casting an integer to a ` [u8; N] ` array materialises its little-endian bytes.
1454+
1455+ ``` k
1456+ rule <k> #cast(
1457+ Integer(VAL, WIDTH, _SIGNEDNESS),
1458+ castKindTransmute,
1459+ _TY_SOURCE,
1460+ TY_TARGET
1461+ )
1462+ =>
1463+ Range(#littleEndianBytesFromInt(VAL, WIDTH))
1464+ ...
1465+ </k>
1466+ requires #isStaticU8Array(lookupTy(TY_TARGET))
1467+ andBool WIDTH >=Int 0
1468+ andBool WIDTH %Int 8 ==Int 0
1469+ andBool WIDTH ==Int #staticArrayLenBits(lookupTy(TY_TARGET))
1470+ [preserves-definedness] // ensures element type/length are well-formed
1471+
1472+ syntax List ::= #littleEndianBytesFromInt ( Int, Int ) [function]
1473+ // -------------------------------------------------------------
1474+ rule #littleEndianBytesFromInt(VAL, WIDTH)
1475+ => #littleEndianBytes(truncate(VAL, WIDTH, Unsigned), WIDTH /Int 8)
1476+ requires WIDTH %Int 8 ==Int 0
1477+ andBool WIDTH >=Int 0
1478+ [preserves-definedness]
1479+
1480+ syntax List ::= #littleEndianBytes ( Int, Int ) [function]
1481+ // -------------------------------------------------------------
1482+ rule #littleEndianBytes(_, COUNT)
1483+ => .List
1484+ requires COUNT <=Int 0
1485+
1486+ rule #littleEndianBytes(VAL, COUNT)
1487+ => ListItem(Integer(VAL %Int 256, 8, false)) #littleEndianBytes(VAL /Int 256, COUNT -Int 1)
1488+ requires COUNT >Int 0
1489+ [preserves-definedness]
1490+
1491+ syntax Bool ::= #isStaticU8Array ( TypeInfo ) [function, total]
1492+ // -------------------------------------------------------------
1493+ rule #isStaticU8Array(typeInfoArrayType(ELEM_TY, someTyConst(_)))
1494+ => lookupTy(ELEM_TY) ==K typeInfoPrimitiveType(primTypeUint(uintTyU8))
1495+ rule #isStaticU8Array(_OTHER) => false [owise]
1496+
1497+ syntax Int ::= #staticArrayLenBits ( TypeInfo ) [function, total]
1498+ // -------------------------------------------------------------
1499+ rule #staticArrayLenBits(typeInfoArrayType(_, someTyConst(tyConst(KIND, _))))
1500+ => readTyConstInt(KIND) *Int 8
1501+ [preserves-definedness]
1502+ rule #staticArrayLenBits(_OTHER) => 0 [owise]
1503+ ```
1504+
14171505Another specialisation is getting the discriminant of ` enum ` s without fields after converting some integer data to it
14181506(see ` #discriminant ` and ` rvalueDiscriminant ` ).
14191507If none of the ` enum ` variants has any fields, the ` Transmute ` of a number to the ` enum ` data is necessarily just the discriminant itself., and can be returned as the integer value afgter adjusting to the byte length of the discriminant:
0 commit comments