@@ -1433,6 +1433,94 @@ The first cast is reified as a `thunk`, the second one resolves it and eliminate
14331433 andBool lookupTy(TY_DEST_INNER) ==K lookupTy(TY_SRC_OUTER) // and is well-formed (invariant)
14341434```
14351435
1436+ Casting a byte array/slice to an integer reinterprets the bytes in little-endian order.
1437+
1438+ ``` k
1439+ rule <k> #cast(
1440+ Range(ELEMS),
1441+ castKindTransmute,
1442+ _TY_SOURCE,
1443+ TY_TARGET
1444+ )
1445+ =>
1446+ #intAsType(
1447+ #littleEndianFromBytes(ELEMS),
1448+ size(ELEMS) *Int 8,
1449+ #numTypeOf(lookupTy(TY_TARGET))
1450+ )
1451+ ...
1452+ </k>
1453+ requires #isIntType(lookupTy(TY_TARGET))
1454+ andBool size(ELEMS) *Int 8 ==Int #bitWidth(#numTypeOf(lookupTy(TY_TARGET)))
1455+ andBool #areLittleEndianBytes(ELEMS)
1456+ [preserves-definedness] // ensures #numTypeOf is defined
1457+
1458+ syntax Bool ::= #areLittleEndianBytes ( List ) [function, total]
1459+ // -------------------------------------------------------------
1460+ rule #areLittleEndianBytes(.List) => true
1461+ rule #areLittleEndianBytes(ListItem(Integer(_, 8, false)) REST)
1462+ => #areLittleEndianBytes(REST)
1463+ rule #areLittleEndianBytes(ListItem(_OTHER) _) => false [owise]
1464+
1465+ syntax Int ::= #littleEndianFromBytes ( List ) [function]
1466+ // -----------------------------------------------------
1467+ rule #littleEndianFromBytes(.List) => 0
1468+ rule #littleEndianFromBytes(ListItem(Integer(BYTE, 8, false)) REST)
1469+ => BYTE +Int 256 *Int #littleEndianFromBytes(REST)
1470+ ```
1471+
1472+ Casting an integer to a ` [u8; N] ` array materialises its little-endian bytes.
1473+
1474+ ``` k
1475+ rule <k> #cast(
1476+ Integer(VAL, WIDTH, _SIGNEDNESS),
1477+ castKindTransmute,
1478+ _TY_SOURCE,
1479+ TY_TARGET
1480+ )
1481+ =>
1482+ Range(#littleEndianBytesFromInt(VAL, WIDTH))
1483+ ...
1484+ </k>
1485+ requires #isStaticU8Array(lookupTy(TY_TARGET))
1486+ andBool WIDTH >=Int 0
1487+ andBool WIDTH %Int 8 ==Int 0
1488+ andBool WIDTH ==Int #staticArrayLenBits(lookupTy(TY_TARGET))
1489+ [preserves-definedness] // ensures element type/length are well-formed
1490+
1491+ syntax List ::= #littleEndianBytesFromInt ( Int, Int ) [function]
1492+ // -------------------------------------------------------------
1493+ rule #littleEndianBytesFromInt(VAL, WIDTH)
1494+ => #littleEndianBytes(truncate(VAL, WIDTH, Unsigned), WIDTH /Int 8)
1495+ requires WIDTH %Int 8 ==Int 0
1496+ andBool WIDTH >=Int 0
1497+ [preserves-definedness]
1498+
1499+ syntax List ::= #littleEndianBytes ( Int, Int ) [function]
1500+ // -------------------------------------------------------------
1501+ rule #littleEndianBytes(_, COUNT)
1502+ => .List
1503+ requires COUNT <=Int 0
1504+
1505+ rule #littleEndianBytes(VAL, COUNT)
1506+ => ListItem(Integer(VAL %Int 256, 8, false)) #littleEndianBytes(VAL /Int 256, COUNT -Int 1)
1507+ requires COUNT >Int 0
1508+ [preserves-definedness]
1509+
1510+ syntax Bool ::= #isStaticU8Array ( TypeInfo ) [function, total]
1511+ // -------------------------------------------------------------
1512+ rule #isStaticU8Array(typeInfoArrayType(ELEM_TY, someTyConst(_)))
1513+ => lookupTy(ELEM_TY) ==K typeInfoPrimitiveType(primTypeUint(uintTyU8))
1514+ rule #isStaticU8Array(_OTHER) => false [owise]
1515+
1516+ syntax Int ::= #staticArrayLenBits ( TypeInfo ) [function, total]
1517+ // -------------------------------------------------------------
1518+ rule #staticArrayLenBits(typeInfoArrayType(_, someTyConst(tyConst(KIND, _))))
1519+ => readTyConstInt(KIND) *Int 8
1520+ [preserves-definedness]
1521+ rule #staticArrayLenBits(_OTHER) => 0 [owise]
1522+ ```
1523+
14361524Another specialisation is getting the discriminant of ` enum ` s without fields after converting some integer data to it
14371525(see ` #discriminant ` and ` rvalueDiscriminant ` ).
14381526If 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