Documentation Index
8 min read•Chapter 4

4. Primitive Data Types

In Quorlin, primitive data types form the foundational building blocks for all state variables, memory operations, and contract interactions. Designed to read like plain English while compiling directly to high-performance Kortana Virtual Machine (KVM) instructions, Quorlin replaces traditional cryptic type names with clear, intuitive keywords.

Underneath this human-readable surface, Quorlin maintains full binary and Application Binary Interface (ABI) compatibility with standard Ethereum tools and smart contracts running on the Kortana network.

This chapter covers the types provided by Quorlin:

  • number (256-bit unsigned integer)
  • truth (Boolean flag)
  • address (20-byte account identifier)
  • text (UTF-8 dynamic string, up to 128 bytes)
  • nothing (Void type)
  • list<T> (bounded sequence of number/truth/address, max 64 elements — parameters, locals and return values only, never storage)
  • bytes (opaque byte string, max 256 bytes — carried and never inspected, e.g. ERC-1155 data)
  • bytes4 (four-byte tag — ERC-165 supportsInterface)

1. number (Unsigned 256-bit Integer)

The number type represents an unsigned 256-bit integer (u256). It is the primary numeric primitive in Quorlin and is used for balance calculations, token supplies, timestamps, loop counters, and mathematical operations.

ABI and KVM Representation

  • Quorlin Keyword: number
  • Internal AST Type: Type::U256
  • Ethereum ABI Equivalent: uint256
  • KVM Architecture: Occupies a single 256-bit register or memory word.

In KVM bytecode, operations on number utilize native 256-bit ALU instructions (Add, Sub, Mul, Div, Mod, Lt, Gt, Eq).

Literal Syntax

Numeric literals can be expressed in standard decimal format or in hexadecimal format (prefixed with 0x):

quorlin (.ql)
number standardAmount = 1000000; number hexAmount = 0x0F4240; // 1,000,000 in hexadecimal

Supported Operations

1. Standard Arithmetic

Standard arithmetic operations on number include addition (+), subtraction (-), multiplication (*), division (/), and modulo (%). By default, operations are subject to safety checks.

quorlin (.ql)
number a = 50; number b = 20; number sum = a + b; // 70 number difference = a - b; // 30 number product = a * b; // 1000 number quotient = a / b; // 2 number remainder = a % b; // 10

2. Wrapping Arithmetic

For low-level algorithms requiring explicit modular arithmetic without overflow/underflow checks, Quorlin provides wrapping operators: +% (wrapping add), -% (wrapping subtract), and *% (wrapping multiply). Checked +/-/* stop the call on overflow; the wrapping forms wrap modulo 2^256 and have to say so. (AddWrap/SubWrap/MulWrap are the internal BinaryOp names, not source syntax.)

quorlin (.ql)
number max = 115792089237316195423570985008687907853269984665640564039457584007913129639935; // 2^256 - 1 number wrapped = max +% 1; // Wraps around to 0

3. Bitwise Operators

Bitwise operations allow direct bit manipulation on 256-bit words:

  • Bitwise AND (&)
  • Bitwise OR (|)
  • Bitwise XOR (^)
  • Shift Left (<<)
  • Shift Right (>>)
quorlin (.ql)
number flags = 0b0101; number mask = 0b0011; number result = flags & mask; // 0b0001

4. Relational & Ordering Operators

Ordering operators compare the magnitude of two number values and return a truth result:

  • Less than (<)
  • Less than or equal (<=)
  • Greater than (>)
  • Greater than or equal (>=)
  • Equal (==)
  • Not equal (!=)
quorlin (.ql)
number balance = 100; number price = 50; truth canAfford = balance >= price; // yes

2. truth (Boolean Type)

The truth type represents a binary logical condition. It can hold one of two explicit English literal states: yes (representing boolean true) or no (representing boolean false).

ABI and KVM Representation

  • Quorlin Keyword: truth
  • Internal AST Type: Type::Bool
  • Ethereum ABI Equivalent: bool
  • KVM Architecture: Stored as a 256-bit word where 1 represents yes and 0 represents no.

Literal Syntax

Quorlin avoids standard true/false keywords in favor of yes and no:

quorlin (.ql)
truth isActive = yes; truth isPaused = no;

Logical Operations

Logical operations require both operands to be of type truth:

  • Logical AND (and)
  • Logical OR (or)
  • Logical NOT (not)
  • Equality (==, !=)

Words, not symbols: and/or/not rather than &&/||/!. A bare ! is a compile error and &/| are bitwise. Logic short-circuits.

quorlin (.ql)
truth isUserEligible = yes; truth hasToken = no; // Evaluates to 'no' truth canClaim = isUserEligible and hasToken; // Evaluates to 'yes' truth allowAccess = isUserEligible or hasToken;

3. address (Account Identifier)

The address type holds a 20-byte (160-bit) account address, representing either an Externally Owned Account (EOA) or a Smart Contract instance on the Kortana network.

ABI and KVM Representation

  • Quorlin Keyword: address
  • Internal AST Type: Type::Address
  • Ethereum ABI Equivalent: address
  • KVM Architecture: Encoded into a 256-bit KVM register, left-padded with 12 zero bytes. The 20 address bytes occupy the lowest 160 bits (low 20 bytes).

Context Built-ins

Quorlin provides context built-ins that return values of type address:

  • caller: the address calling this function.
  • sender: the address that signed the transaction (caller and sender differ when a contract calls through).
  • thisContract: this contract's own address.
  • nobody: the zero address, named. Use it for zero-address guards — recipient != 0 does not typecheck (address vs number) and there are no address literals.
  • kortanaChain / kortanaStaking / kortanaGovernance: the system contracts' addresses.
quorlin (.ql)
address currentCaller = caller; require recipient != nobody, "transfer to the zero address";

Literal and Operations

Addresses come from parameters, fields, caller/sender/thisContract/nobody — never from a constant typed into the source. There are no address literals.

Supported operators on address are limited to equality comparisons:

  • Equal (==)
  • Not Equal (!=)
quorlin (.ql)
reads truth isOwner(address user, address owner) { return user == owner; }

4. text (Dynamic String)

The text type represents human-readable UTF-8 string data. It is primarily used for log messages, contract names, symbols, and error diagnostics passed to standard assertion routines like require.

ABI and KVM Representation

  • Quorlin Keyword: text
  • Internal AST Type: Type::Text
  • Ethereum ABI Equivalent: string
  • KVM Architecture: Dynamic heap/memory allocation pointer and length descriptor.

Constraints & Literals

Text literals are enclosed in double quotes. Source texts and string literals are bounded by kMaxTextBytes in the semantic analyzer to prevent memory exhaustion inside the KVM runtime.

Escaping rules in JSON output and lexing enforce clean identifier handling for quotes (") and backslashes (\).

quorlin (.ql)
text tokenName = "Kortana Utility Token"; writes truth validateBalance(number balance, number required) { require balance >= required, "Insufficient token balance"; return yes; }

5. nothing (Void Type)

The nothing keyword represents the explicit absence of a return value. Functions that mutate state or emit events without returning data specify nothing as their return type.

ABI and KVM Representation

  • Quorlin Keyword: nothing
  • Internal AST Type: Type::Void
  • Ethereum ABI Equivalent: void (no return values specified in ABI JSON definition)

Usage Example

quorlin (.ql)
writes nothing updateAdmin(address newAdmin) { require caller == admin, "Only admin can call this"; admin = newAdmin; }

6. Type Mapping Reference Table

The following table summarizes how Quorlin source types map to internal semantic types, Ethereum/KVM ABI exports, and their standard literal representations:

Quorlin KeywordInternal AST TypeABI Type NameLiterals / ExamplesKVM Bit Width
numberType::U256uint256100, 0xFF256 bits
truthType::Boolboolyes, no256 bits (0 or 1)
addressType::Addressaddresscaller, nobody (no address literals)160 bits (padded to 256)
textType::Textstring"Insufficient balance"Variable / Pointer
list<T>Type::Listuint256[] etc.list(n), ids[i], ids.length (max 64, never storage)Variable (bounded)
bytesType::Bytesbytesforwarded hook data (max 256 bytes, carried never inspected)Variable (bounded)
bytes4Type::Bytes4bytes4supportsInterface(bytes4 interfaceId)32 bits (left-aligned word)
nothingType::VoidvoidNone (Return type only)0 bits

7. Complete Code Example

The following smart contract illustrates the scalar primitive data types operating together in a standard Quorlin contract declaration (list, bytes, and bytes4 appear at the call boundary — see the token standards):

java
contract VaultManager { // Primitive State Variables address owner; number vaultBalance; truth isLocked; text vaultName; // Event declaration using primitive types event DepositMade(address indexed sender, number amount); constructor { owner = caller; vaultBalance = 0; isLocked = no; vaultName = "Secure Vault"; } // Returns a primitive 'truth' value reads truth checkOwner(address check) { return check == owner; } // Returns a primitive 'number' value reads number getBalance() { return vaultBalance; } // State mutating function returning 'nothing' writes nothing lockVault() { require caller == owner, "Unauthorized caller"; isLocked = yes; } // State mutating function returning 'truth' writes truth deposit(number amount) { require isLocked == no, "Vault is locked"; require amount > 0, "Deposit amount must be positive"; vaultBalance = vaultBalance + amount; emit DepositMade(caller, amount); return yes; } }