Primitive types
Lithe's primitive types map directly onto ABI types. Nothing converts implicitly: each width is its own type, and wei and timestamp don't mix with uint.
primitive-types.lithe
import "std/crypto";
import "std/evm";
import "std/int";
import "std/uint";
storage is record {
flag : bool;
(* `uint` is uint256, `int` is int256. *)
amount : uint;
delta : int;
(* Fixed widths are distinct types, from 8 to 256 bits. *)
small : uint8;
offset : int16;
owner : address;
(* Fixed-size and dynamic byte strings. *)
tag : bytes4;
hash : bytes32;
blob : bytes;
name : string;
(* Semantic types: both are uint256 in the ABI, but neither mixes with `uint`. *)
price : wei;
deadline : timestamp;
}
external function fill() is {
storage.flag := true;
storage.amount := 1_000;
storage.delta := -42;
storage.small := 255;
storage.offset := -300;
storage.owner := Evm.sender();
storage.tag := 0xa9059cbb;
storage.hash := Crypto.keccak256("abc");
storage.blob := 0x616263;
storage.name := "Lithe";
storage.price := 3gwei;
storage.deadline := Evm.blockTimestamp() + 1days;
}
(* Bounds come from the type the context expects. *)
external pure function bounds() : (uint8, int16, uint) is
(Uint.max, Int.min, Uint.max)- Integer literals like
255and-300take their type from context and must fit it. Uint.maxandInt.mintake their width from context too, which is whyboundsreturns 255, -32768, and 2²⁵⁶-1.- See Types for the full list.

