Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

deferred

std › bitter › deferred

Values that depend on where things end up, such as the distance to a branch target. They’re built as Deferred expressions that bitter resolves once the image is laid out, and given a width by Positioned<N>.

from std.binary import bits
from std.bitter.deferred import *

macro db(value: int) {
    @emit value as bits<8>
}

macro offset_to(target: int) {
    @emit Positioned<8> { value: span(here(), target) }
}

offset_to end
db 0xAA
db 0xBB
end:
03 aa bb

add, sub, mul, shr and band work on ints, giving an int, and on Deferreds, giving a Deferred, so an encoder is written the same way whether its operand is known yet or not.

Macros

here

The position of the value being packed. Use it only inside the span of the value being emitted: stored and used by a different value, it refers to that value’s position instead.

SyntaxParametersResultDescription
here()returns Deferred

add

SyntaxParametersResultDescription
add(a, b)a: int, b: intreturns inta + b: an int when both are ints, else a Deferred.
add(a, b)a: Deferred, b: intreturns Deferred
add(a, b)a: int, b: Deferredreturns Deferred
add(a, b)a: Deferred, b: Deferredreturns Deferred

sub

SyntaxParametersResultDescription
sub(a, b)a: int, b: intreturns inta - b: an int when both are ints, else a Deferred.
sub(a, b)a: Deferred, b: intreturns Deferred
sub(a, b)a: int, b: Deferredreturns Deferred
sub(a, b)a: Deferred, b: Deferredreturns Deferred

mul

SyntaxParametersResultDescription
mul(a, b)a: int, b: intreturns inta * b: an int when both are ints, else a Deferred.
mul(a, b)a: Deferred, b: intreturns Deferred
mul(a, b)a: int, b: Deferredreturns Deferred
mul(a, b)a: Deferred, b: Deferredreturns Deferred

shr

SyntaxParametersResultDescription
shr(a, b)a: int, b: intreturns inta >> b: an int when a is an int, else a Deferred.
shr(a, b)a: Deferred, b: intreturns Deferred

band

SyntaxParametersResultDescription
band(a, b)a: int, b: intreturns inta & b: an int when a is an int, else a Deferred.
band(a, b)a: Deferred, b: intreturns Deferred

span

SyntaxParametersResultDescription
span(start, end)start: int, end: intreturns DeferredThe number of bytes from position start to position end, negative if end comes first. Either may be here(). Labels are positions, so span(here(), target) is a relative branch offset.
span(start, end)start: Deferred, end: intreturns Deferred
span(start, end)start: int, end: Deferredreturns Deferred

Types

Op

enum Op

The operation of a BinOp.

VariantPayloadDescription
Addleft + right.
Subleft - right.
Mulleft * right.
Shrleft >> right.
Bandleft & right.
SpanBytes from position left to position right, as in span.

BinOp

struct BinOp

An operation on two Deferred values.

FieldTypeDescription
opOpWhat to do.
leftDeferredThe first operand.
rightDeferredThe second operand.

Deferred

enum Deferred

A value bitter works out after laying out the image. Build one with here, span and the arithmetic macros rather than by hand.

VariantPayloadDescription
LeafintA plain number.
PosintA position, such as a label, as a number of entries.
HereThe position of the value being packed.
NodeBinOpAn operation on two Deferred values.

Positioned

struct Positioned<const width: int>

A Deferred value, packed into width bits once bitter resolves it: what bits<N> is to an int. A negative value is packed in two’s complement.

FieldTypeDescription
valueDeferredThe value to resolve.