Documentation
¶
Overview ¶
Package ir is the compiler's intermediate representation, and everything that operates on it: Parse and Dump convert to and from the textual format (see ir-textual-format.md), Typecheck checks register types, Assemble lowers to a vm.Program. The grammar's AST is internal, so callers only see instructions.
Index ¶
- Variables
- func Assemble(instrs []Instr) (vm.Program, error)
- func Dump(code []Instr) string
- func Parse(src string) ([]Instr, []Error)
- func Typecheck(instrs []Instr) error
- type AssertLeftover
- type AssertNonNegativeAmount
- type AssertNonNegativeBalance
- type AssertNonNegativePortion
- type AssertSameAsset
- type AssertUnscoped
- type AssertValidAccount
- type AssertValidColor
- type AssertValidScope
- type BinKind
- type BinaryOp
- type Builder
- type CheckEnoughFunds
- type ConstBool
- type Error
- type FetchBalance
- type Instr
- type Jmp
- type JmpIfFalse
- type JmpIfTrue
- type Label
- type LabelMarker
- type LoadInt
- type LoadStr
- type LoadVar
- type MarkEnd
- type MarkPush
- type MetaInt
- type MetaMonetary
- type MetaPortion
- type MetaStr
- type MetaType
- type MetaVar
- type OpAddInt
- type OpAddPortion
- type OpAddString
- type OpBoolCopy
- type OpEqInt
- type OpEqPortion
- type OpIntCopy
- type OpIntToPortion
- type OpIntToString
- type OpIsZero
- type OpLtInt
- type OpLtPortion
- type OpMakePortion
- type OpMonetaryToString
- type OpMulPortion
- type OpNegInt
- type OpNot
- type OpPortionCopy
- type OpPortionToInt
- type OpPortionToString
- type OpStrCopy
- type OpStrEq
- type OpSubInt
- type OpSubPortion
- type PullAccount
- type Reg
- type Save
- type SendToAccount
- type SetAccountMeta
- type SetCurrentAsset
- type SetTxMeta
- type UnKind
- type UnaryOp
- type VarInt
- type VarStr
- type VarType
Constants ¶
This section is empty.
Variables ¶
var ErrProgramTooLarge = errors.New("program too large")
ErrProgramTooLarge is the assembler refusing a program whose instruction stream outgrows what a jump target can address — the encoding's uint16 operand limit. Like ErrRegisterBankOverflow, a capacity bound of the compiled engine, not a semantic rejection of the script.
var ErrRegisterBankOverflow = errors.New("register bank overflow")
ErrRegisterBankOverflow is the assembler refusing a program that needs more than maxReg simultaneously-live registers in one bank — the instruction encoding's one-byte operand limit. It is a capacity bound of the compiled engine, not a semantic rejection of the script.
Functions ¶
func Parse ¶
Parse reads an IR text into the instruction stream it describes.
It checks the grammar and everything the grammar can't express: that instructions exist and take the arguments they were given, that labels resolve and are unique, and that jumps go forward. It does not typecheck the registers — that's Typecheck.
Types ¶
type AssertLeftover ¶
type AssertLeftover struct {
Portion Reg // the allotment leftover (1 - sum of the given Portions)
Exact bool // no `remaining` clause: leftover must be exactly 0, else >= 0
}
func (AssertLeftover) String ¶
func (i AssertLeftover) String() string
type AssertNonNegativeAmount ¶
type AssertNonNegativeAmount struct{ Amount Reg } // int (a sent/saved amount, not tied to an account)
func (AssertNonNegativeAmount) String ¶
func (i AssertNonNegativeAmount) String() string
type AssertNonNegativeBalance ¶
type AssertNonNegativeBalance struct{ Balance, Account Reg } // int (the amount), str
func (AssertNonNegativeBalance) String ¶
func (i AssertNonNegativeBalance) String() string
type AssertNonNegativePortion ¶
type AssertNonNegativePortion struct{ Portion Reg } // portion (an allotment clause portion)
func (AssertNonNegativePortion) String ¶
func (i AssertNonNegativePortion) String() string
type AssertSameAsset ¶
type AssertSameAsset struct{ Left, Right Reg } // str, str
func (AssertSameAsset) String ¶
func (i AssertSameAsset) String() string
type AssertUnscoped ¶
type AssertUnscoped struct{ Scope, Account Reg } // str, str
func (AssertUnscoped) String ¶
func (i AssertUnscoped) String() string
type AssertValidAccount ¶
type AssertValidAccount struct{ Account Reg } // str
func (AssertValidAccount) String ¶
func (i AssertValidAccount) String() string
type AssertValidColor ¶
type AssertValidColor struct{ Color Reg } // str
func (AssertValidColor) String ¶
func (i AssertValidColor) String() string
type AssertValidScope ¶
type AssertValidScope struct{ Scope Reg } // str
func (AssertValidScope) String ¶
func (i AssertValidScope) String() string
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder accumulates an instruction stream, handing out the registers and labels it needs.
func (*Builder) FreshLabel ¶
FreshLabel suffixes prefix with a counter: "inorder_end" -> #inorder_end_0.
func (*Builder) PushWithDest ¶
PushWithDest allocates the register the instruction writes to. Allocating here rather than up front keeps registers numbered in emission order, which is what makes a Dump of the result parse back to the same program.
type CheckEnoughFunds ¶
type CheckEnoughFunds struct{ Got, Needed Reg } // int
func (CheckEnoughFunds) String ¶
func (i CheckEnoughFunds) String() string
type ConstBool ¶
ConstBool assembles to Op_ConstTrue or Op_ConstFalse: the value is in the opcode, so there is no pool entry.
type Error ¶
Error is something wrong with an IR text: either the grammar rejected it, or it doesn't describe a well-formed instruction stream.
type FetchBalance ¶
type FetchBalance struct {
Dest Reg // int (the amount; the asset is the Asset operand)
Account, Asset Reg // str, str
Scope *Reg
} // reads the run-state (impure)
func (FetchBalance) String ¶
func (i FetchBalance) String() string
type JmpIfFalse ¶
The two conditional jumps differ only in which edge of the bool jumps, so either branch of a condition is one instruction and no negation is needed.
func (JmpIfFalse) String ¶
func (i JmpIfFalse) String() string
type LabelMarker ¶
type LabelMarker struct{ Label Label }
func (LabelMarker) String ¶
func (i LabelMarker) String() string
type MarkEnd ¶
type MarkEnd struct{ Rewind bool }
MarkEnd closes the innermost region. Rewind undoes what it did; otherwise the region's pulls and postings are committed. Dumps as mark_rewind / mark_commit.
type MarkPush ¶
type MarkPush struct{} // opens a region at the current source-queue depth
The mark ops, used for oneof backtracking. Neither takes a register: the mark is a source-queue depth on a LIFO the run-state owns, so no operand can name a depth it never marked.
There is no "rewind but keep the mark" instruction: a retry is MarkEnd{Rewind: true} followed by a fresh MarkPush, which after the rollback yields a mark identical to the closed one. Mark depth is therefore a function of position in the instruction stream, so a verifier could decide statically that pushes and ends balance on every path, that no MarkEnd runs at depth 0, and that no SendToAccount, SetCurrentAsset or Save sits at depth > 0. No such pass exists yet — the VM enforces it at execution time — but keep emission verifiable: never emit a mark op on only one side of a branch.
type MetaMonetary ¶
type MetaMonetary struct {
DestAsset Reg // str
DestAmount Reg // int
Account Reg // str
Key Reg // str
Scope *Reg
}
MetaMonetary is meta<monetary>: one store read yields both halves, so it is the only two-destination read and is not a MetaType.
func (MetaMonetary) String ¶
func (i MetaMonetary) String() string
type MetaPortion ¶
type MetaPortion struct{}
func (MetaPortion) String ¶
func (MetaPortion) String() string
type OpAddPortion ¶
type OpAddPortion struct{}
func (OpAddPortion) String ¶
func (OpAddPortion) String() string
type OpAddString ¶
type OpAddString struct{}
func (OpAddString) String ¶
func (OpAddString) String() string
type OpBoolCopy ¶
type OpBoolCopy struct{}
func (OpBoolCopy) String ¶
func (OpBoolCopy) String() string
type OpEqPortion ¶
type OpEqPortion struct{}
func (OpEqPortion) String ¶
func (OpEqPortion) String() string
type OpIntCopy ¶
type OpIntCopy struct{}
One copy per register bank. A monetary has none: it is a (str, int) pair, so copying one is a str_copy plus an int_copy.
type OpIntToPortion ¶
type OpIntToPortion struct{}
The two directions across the int/portion boundary. OpIntToPortion is exact; OpPortionToInt floors (big.Rat's denominator is always positive, so big.Int.Div is the floor). Together with OpMulPortion they are what an allotment share is made of.
func (OpIntToPortion) String ¶
func (OpIntToPortion) String() string
type OpIntToString ¶
type OpIntToString struct{}
func (OpIntToString) String ¶
func (OpIntToString) String() string
type OpIsZero ¶
type OpIsZero struct{}
OpIsZero projects an int onto a bool, which is how a quantity reaches a jump: the jumps take a bool, so the projection has to be explicit.
type OpLtInt ¶
type OpLtInt struct{}
The comparisons: only `<` and `==`, per type. `>`, `<=`, `>=` and `!=` are front-end normalisations over these plus OpNot — see the table in internal/vm/instruction.go.
type OpLtPortion ¶
type OpLtPortion struct{}
func (OpLtPortion) String ¶
func (OpLtPortion) String() string
type OpMakePortion ¶
type OpMakePortion struct{}
func (OpMakePortion) String ¶
func (OpMakePortion) String() string
type OpMonetaryToString ¶
type OpMonetaryToString struct{}
OpMonetaryToString takes the asset (str) and the amount (int) of a monetary and produces its "ASSET AMOUNT" form, the inverse of funds.ParseMonetary.
func (OpMonetaryToString) String ¶
func (OpMonetaryToString) String() string
type OpMulPortion ¶
type OpMulPortion struct{}
func (OpMulPortion) String ¶
func (OpMulPortion) String() string
type OpPortionCopy ¶
type OpPortionCopy struct{}
func (OpPortionCopy) String ¶
func (OpPortionCopy) String() string
type OpPortionToInt ¶
type OpPortionToInt struct{}
func (OpPortionToInt) String ¶
func (OpPortionToInt) String() string
type OpPortionToString ¶
type OpPortionToString struct{}
func (OpPortionToString) String ¶
func (OpPortionToString) String() string
type OpStrEq ¶
type OpStrEq struct{}
OpStrEq yields a bool: it is the one comparison that produces a value rather than trapping, and what the jumps branch on.
type OpSubPortion ¶
type OpSubPortion struct{}
func (OpSubPortion) String ¶
func (OpSubPortion) String() string
type PullAccount ¶
type PullAccount struct {
Dest Reg // int: amount pulled
Account Reg // str
Cap, Overdraft, Color, Scope *Reg // int, int, str, str
}
func (PullAccount) String ¶
func (i PullAccount) String() string
type Save ¶
type SendToAccount ¶
type SendToAccount struct {
Account, Cap, Scope *Reg // str, int, str
}
func (SendToAccount) String ¶
func (i SendToAccount) String() string
type SetAccountMeta ¶
func (SetAccountMeta) String ¶
func (i SetAccountMeta) String() string
type SetCurrentAsset ¶
type SetCurrentAsset struct{ Asset Reg } // str
func (SetCurrentAsset) String ¶
func (i SetCurrentAsset) String() string