Module agora.script.ScopeCondition
Keeps track of scopes and their conditions (TRUE or FALSE). This struct can be used to implement conditional (IF/ELSE/ENDIF) logic.
It does this by pushing a new scope for each visited IF
opcode,
popping a scope for every visited END_IF
opcode, and toggling the scope's
condition for every visited ELSE
opcode.
Unlike C-like programming languages we do not support GOTO and therefore may only increment the program counter one instruction at a time. This constraint makes this ScopeCondition design possible.
This implementation is largely based on Bitcoin's ConditionStack
,
as it's the most optimal O(1) solution we could think of using.
For a description on how code flow control works (for a previous version),
see
https://building-on-bitcoin.com/docs/slides/Thomas_Kerin_BoB_2018.pdf
Example
ScopeCondition sc;
assert(sc .empty());
assert(sc .isTrue());
// IF
// DO <- pc
sc .push(true);
assert(!sc .empty());
assert(sc .isTrue());
// IF
// DO
// ELSE
// DO <- pc
sc .tryToggle();
assert(!sc .empty());
assert(!sc .isTrue());
// IF
// IF
// DO <- pc
// ENDIF
// DO
// ENDIF
sc = ScopeCondition .init;
sc .push(true);
sc .push(true);
assert(!sc .empty());
assert(sc .isTrue());
// IF
// IF
// DO
// ENDIF
// DO <- pc
// ENDIF
sc .pop();
assert(!sc .empty());
assert(sc .isTrue());
// IF
// IF
// DO
// ENDIF
// DO
// ENDIF <- pc
sc .pop();
assert(sc .empty());
assert(sc .isTrue());
// OP_TRUE
// IF -> true
// DO -> executed
// OP_0
// IF
// DO -> skipped
// OP_TRUE <- false as previous scope was false
// IF
// DO -> skipped
// OP_TRUE <- false, ditto
// IF
// DO -> skipped
// OP_TRUE <- false, ditto
// IF
// DO -> skipped
// ENDIF
// DO -> skipped
// ENDIF
// DO -> skipped
// ENDIF
// DO -> skipped
// ENDIF
// DO -> executed (no false scopes left)
// ENDIF
sc = ScopeCondition .init;
sc .push(true);
sc .push(false);
sc .push(true);
sc .push(true);
sc .push(false);
assert(!sc .empty());
assert(!sc .isTrue());
sc .pop();
assert(!sc .empty());
assert(!sc .isTrue());
sc .pop();
assert(!sc .empty());
assert(!sc .isTrue());
sc .pop();
assert(!sc .empty());
assert(!sc .isTrue());
sc .pop();
assert(sc .isTrue());
sc .pop();
assert(sc .empty());
assert(sc .isTrue());
Structs
Name | Description |
---|---|
ScopeCondition
|