// Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com) // All rights reserved. // Five pcode — stack-based bytecode for FRB interpreter mode. // Each opcode maps 1:1 to a Thread method call, making the pcode // a direct serialization of what gengo generates as Go code. // // Format: [opcode:1byte] [operands:variable] // Strings: [len:uint16 LE] [bytes] // Numbers: int64 = 8 bytes LE, float64 = 8 bytes LE package hbrt // Opcode definitions const ( // Stack operations PcOpNop byte = 0x00 PcOpPushNil byte = 0x01 PcOpPushTrue byte = 0x02 PcOpPushFalse byte = 0x03 PcOpPushInt byte = 0x04 // + int64 LE PcOpPushDouble byte = 0x05 // + float64 LE (8 bytes) PcOpPushString byte = 0x06 // + uint16 len + bytes PcOpPushLocal byte = 0x07 // + uint16 index PcOpPopLocal byte = 0x08 // + uint16 index PcOpPop byte = 0x09 PcOpDup byte = 0x0A // Arithmetic PcOpPlus byte = 0x10 PcOpMinus byte = 0x11 PcOpMult byte = 0x12 PcOpDivide byte = 0x13 PcOpMod byte = 0x14 PcOpPower byte = 0x15 PcOpNegate byte = 0x16 // Comparison PcOpEqual byte = 0x20 PcOpNotEqual byte = 0x21 PcOpLess byte = 0x22 PcOpGreater byte = 0x23 PcOpLessEq byte = 0x24 PcOpGreaterEq byte = 0x25 PcOpInString byte = 0x26 // Logical PcOpAnd byte = 0x28 PcOpOr byte = 0x29 PcOpNot byte = 0x2A // String PcOpConcat byte = 0x2C // same as Plus for strings // Flow control PcOpJump byte = 0x30 // + int32 LE (relative offset) PcOpJumpFalse byte = 0x31 // + int32 LE PcOpJumpTrue byte = 0x32 // + int32 LE PcOpReturn byte = 0x33 PcOpRetValue byte = 0x34 // Frame PcOpFrame byte = 0x38 // + uint16 params + uint16 locals PcOpEndProc byte = 0x39 // Function calls PcOpPushSymbol byte = 0x40 // + uint16 string len + name PcOpPushNilArg byte = 0x41 // push NIL for function self PcOpFunction byte = 0x42 // + uint16 nArgs PcOpDo byte = 0x43 // + uint16 nArgs // Workarea field access — skips PushSymbol + Function dispatch // for `FieldGet(n)` where n is a literal. Emitted by genpc as a // peephole optimization. Operand: uint16 1-based field position. PcOpFieldGet byte = 0x46 // `AllTrim(FieldGet(n))` peephole — fetch the field, trim the // result in place, push one string. Skips two Function dispatches // (FieldGet + AllTrim) and one intermediate string allocation // per invocation. Operand: uint16 1-based field position. PcOpFieldTrim byte = 0x47 // Self / OOP PcOpPushSelf byte = 0x48 PcOpPushSelfField byte = 0x49 // + uint16 len + name PcOpSetSelfField byte = 0x4A // + uint16 len + name PcOpSend byte = 0x4B // + uint16 len + name + uint16 nArgs // Array / Hash PcOpArrayGen byte = 0x50 // + uint16 count PcOpHashGen byte = 0x51 // + uint16 count PcOpArrayPush byte = 0x52 PcOpArrayPop byte = 0x53 // Block — operand layout: // PcOpPushBlock + uint32 codeLen + body bytes // + uint16 nParams + uint16 nDetached // + nDetached × uint16 (source-local index per slot) // Each captured slot snapshots the current frame's Local(idx) // into the block's Detached[i] at creation time. Body accesses // captured values via PcOpPushDetached / PcOpPopDetached with the // 0-based slot index. PcOpPushBlock byte = 0x58 PcOpPushDetached byte = 0x59 // + uint16 0-based detached slot PcOpPopDetached byte = 0x5A // + uint16 0-based detached slot // Local operations PcOpLocalAddInt byte = 0x60 // + uint16 index + int32 value PcOpInc byte = 0x61 PcOpDec byte = 0x62 // Special PcOpPopLogical byte = 0x70 // pop and store logical result PcOpPushBool byte = 0x71 // + 1 byte (0 or 1) // Memvar lookup — runtime resolution of an unresolved identifier. // Used by the macro evaluator and the debugger's expression evaluator: // at compile time we don't know which LOCAL frame an identifier // refers to, so we emit this op with the name and resolve at runtime // via t.Memvars (PRIVATE/PUBLIC). Pushes NIL if the name isn't set. PcOpPushMemvar byte = 0x72 // + uint16 len + name // Line info (for debugging) PcOpLine byte = 0xFE // + uint16 lineNo PcOpHalt byte = 0xFF ) // PcodeFunc represents a pcode-compiled function. type PcodeFunc struct { Name string Code []byte // bytecode Params int // number of parameters Locals int // number of locals } // PcodeModule represents a compiled pcode module (multiple functions). type PcodeModule struct { Name string Funcs map[string]*PcodeFunc Strings []string // string constant pool // Warnings captures compile-time diagnostics from genpc — most // commonly "AST node X not supported in pcode mode". Surfaced // by the build pipeline so users learn their PRG isn't fully // pcode-compilable instead of seeing silent wrong results from // no-op fallbacks. Empty slice = clean compile. Warnings []string }