compiler

package
v0.4.23 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 21, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

pkg/compiler/compiler.go

pkg/compiler/liveness.go

pkg/compiler/opcode.go

pkg/compiler/optimizer.go Bytecode optimizer for compile-time transformations

pkg/compiler/options.go Configuration options for compiler optimizations

pkg/compiler/reg_compiler.go Register-based bytecode compiler

pkg/compiler/regalloc.go

pkg/compiler/serialize.go Bytecode serialization for saving and loading compiled code.

pkg/compiler/sourcemap.go Source map for mapping bytecode positions to source locations

Index

Constants

View Source
const (
	// NumRegisters is the number of registers per frame
	NumRegisters = 256

	// NumArgRegisters is the number of argument registers (R0-R7)
	NumArgRegisters = 8

	// ReturnRegister is the register index for return values
	ReturnRegister = 255

	// FirstLocalRegister is the first register available for local variables
	// R0-R7 are reserved for arguments
	FirstLocalRegister = 8
)
View Source
const (
	MagicHeader    = "XXLB" // Xxlang Bytecode
	CurrentVersion = 1
)

Magic header for bytecode files

View Source
const GlobalsSize = 65536

GlobalsSize is the maximum number of global variables

Variables

This section is empty.

Functions

func GetDefinitions added in v0.4.21

func GetDefinitions() map[Opcode]*Definition

GetDefinitions returns the opcode definitions map

func IsRegisterOpcode added in v0.4.21

func IsRegisterOpcode(op Opcode) bool

IsRegisterOpcode returns true if the opcode is a register-based operation

func Make

func Make(op Opcode, operands ...int) []byte

Make creates a bytecode instruction with operands

func MakeRegInstruction added in v0.4.21

func MakeRegInstruction(op Opcode, dst, src1, src2 int) []byte

MakeRegInstruction creates a fixed 4-byte register instruction Format: opcode(1) | dst(1) | src1(1) | src2(1)

func MakeRegInstruction1 added in v0.4.21

func MakeRegInstruction1(op Opcode, reg int) []byte

MakeRegInstruction1 creates a register instruction with 1 operand

func MakeRegInstruction2 added in v0.4.21

func MakeRegInstruction2(op Opcode, reg1, reg2 int) []byte

MakeRegInstruction2 creates a register instruction with 2 operands

func MakeRegInstructionConst added in v0.4.21

func MakeRegInstructionConst(op Opcode, reg, constIdx int) []byte

MakeRegInstructionConst creates a register instruction with a 16-bit constant index Format: opcode(1) | reg(1) | const_idx(2)

func MakeRegJump added in v0.4.21

func MakeRegJump(op Opcode, offset int) []byte

MakeRegJump creates a jump instruction with 16-bit offset Format: opcode(1) | unused(1) | offset(2)

func MakeRegJumpCond added in v0.4.21

func MakeRegJumpCond(op Opcode, condReg, offset int) []byte

MakeRegJumpCond creates a conditional jump instruction Format: opcode(1) | cond_reg(1) | offset(2)

func ReadOperands

func ReadOperands(def *Definition, ins []byte) ([]int, int)

ReadOperands reads operands from bytecode

func String

func String(ins []byte) string

String prints bytecode as a formatted string

Types

type Bytecode

type Bytecode struct {
	Instructions      []byte
	Constants         []objects.Object
	SourceMap         *SourceMap                  // Maps instruction positions to source locations
	InlineableGlobals map[int]*InlineableFuncInfo // Global index -> inlineable function info
}

Bytecode represents compiled bytecode

func CompileReg added in v0.4.21

func CompileReg(program *parser.Program) (*Bytecode, error)

CompileReg compiles a program using the register-based compiler

func Deserialize

func Deserialize(data []byte) (*Bytecode, error)

Deserialize decodes binary data to bytecode. Returns the bytecode or an error.

func DeserializeFromFile

func DeserializeFromFile(path string) (*Bytecode, error)

DeserializeFromFile reads bytecode from a file.

func (*Bytecode) Serialize

func (b *Bytecode) Serialize() ([]byte, error)

Serialize encodes bytecode to a binary format. Returns the serialized bytes or an error.

func (*Bytecode) SerializeToFile

func (b *Bytecode) SerializeToFile(path string) error

SerializeToFile writes bytecode to a file. The format is: magic(4) + version(4) + gob-encoded data

type CompilationScope

type CompilationScope struct {
	// contains filtered or unexported fields
}

CompilationScope represents a compilation scope

type CompiledFunction

type CompiledFunction struct {
	Instructions  []byte
	NumLocals     int
	NumParameters int
	NumRegs       int      // Maximum register used (for frame initialization)
	FreeVariables []Symbol // Free variables captured from outer scope

	// Inlining support
	IsInlineable bool   // True if function body is a single return expression
	InlineBody   []byte // Inlined bytecode (without return)
}

CompiledFunction represents a compiled function

func (*CompiledFunction) HashKey

func (cf *CompiledFunction) HashKey() objects.HashKey

HashKey returns the hash key

func (*CompiledFunction) Inspect

func (cf *CompiledFunction) Inspect() string

Inspect returns the string representation

func (*CompiledFunction) ToBool

func (cf *CompiledFunction) ToBool() *objects.Bool

ToBool converts to boolean

func (*CompiledFunction) Type

func (cf *CompiledFunction) Type() objects.ObjectType

Type returns the object type

func (*CompiledFunction) TypeTag

func (cf *CompiledFunction) TypeTag() objects.TypeTag

TypeTag returns the type tag for fast type checking

type Compiler

type Compiler struct {
	// contains filtered or unexported fields
}

Compiler transforms AST into bytecode

func New

func New() *Compiler

New creates a new compiler with default optimizations

func NewWithOptions

func NewWithOptions(opts OptimizationFlags) *Compiler

NewWithOptions creates a new compiler with custom optimization settings

func NewWithState

func NewWithState(s *SymbolTable, constants []objects.Object) *Compiler

NewWithState creates a new compiler with existing state

func (*Compiler) Bytecode

func (c *Compiler) Bytecode() *Bytecode

Bytecode returns the compiled bytecode

func (*Compiler) Compile

func (c *Compiler) Compile(node parser.Node) error

Compile compiles an AST node into bytecode

func (*Compiler) DefineGlobal added in v0.4.19

func (c *Compiler) DefineGlobal(name string) Symbol

DefineGlobal defines a global variable in the symbol table This is used by runCode to pre-define arguments before compilation

func (*Compiler) ResolveSymbol added in v0.4.19

func (c *Compiler) ResolveSymbol(name string) (Symbol, bool)

ResolveSymbol resolves a symbol by name This is used by runCode to find argument indices after compilation

func (*Compiler) SetSource

func (c *Compiler) SetSource(path string, code string)

SetSource sets the source file path and code for error reporting

type Definition

type Definition struct {
	Name          string // Human-readable name
	OperandWidths []int  // Width in bytes of each operand
}

Definition describes an opcode's format

func Lookup

func Lookup(op byte) (*Definition, error)

Lookup finds an opcode's definition

type EmittedInstruction

type EmittedInstruction struct {
	Opcode   Opcode
	Position int
}

EmittedInstruction represents the last emitted instruction

type InlineableFuncInfo

type InlineableFuncInfo struct {
	ConstIndex int // Index in constants pool
	NumParams  int
	Body       []byte
}

InlineableFuncInfo stores information about an inlineable function

type LiveInterval added in v0.4.21

type LiveInterval struct {
	Var    *Symbol // The variable this interval represents
	Start  int     // Definition point (instruction index)
	End    int     // Last use point (instruction index)
	Reg    int     // Assigned register (-1 if not assigned, -2 if spilled)
	Spill  int     // Spill slot index if spilled
	Active bool    // Whether this interval is currently active
}

LiveInterval represents the lifetime of a variable in the code

type LivenessAnalyzer added in v0.4.21

type LivenessAnalyzer struct {
	// contains filtered or unexported fields
}

LivenessAnalyzer computes live intervals for variables in a function

func NewLivenessAnalyzer added in v0.4.21

func NewLivenessAnalyzer() *LivenessAnalyzer

NewLivenessAnalyzer creates a new liveness analyzer

func (*LivenessAnalyzer) Analyze added in v0.4.21

Analyze performs liveness analysis on a function body Returns a map from variable name to its live interval

func (*LivenessAnalyzer) GetIntervals added in v0.4.21

func (la *LivenessAnalyzer) GetIntervals() []*LiveInterval

GetIntervals returns all live intervals as a slice

type Opcode

type Opcode byte

Opcode represents a single bytecode instruction

const (
	// Stack operations
	OpConstant Opcode = iota // Load constant from constant pool
	OpPop                    // Pop value from stack
	OpDup                    // Duplicate top of stack

	// Arithmetic operations
	OpAdd // Addition
	OpSub // Subtraction
	OpMul // Multiplication
	OpDiv // Division
	OpMod // Modulo
	OpNeg // Unary minus (negation)

	// Comparison operations
	OpEqual        // Equality check
	OpNotEqual     // Inequality check
	OpLess         // Less than
	OpGreater      // Greater than
	OpLessEqual    // Less than or equal
	OpGreaterEqual // Greater than or equal

	// Logical operations
	OpAnd // Logical AND
	OpOr  // Logical OR
	OpNot // Logical NOT

	// Variable operations
	OpGetLocal    // Get local variable
	OpSetLocal    // Set local variable
	OpDefineLocal // Define local variable
	OpGetGlobal   // Get global variable
	OpSetGlobal   // Set global variable
	OpGetFree     // Get free variable (from closure)
	OpSetFree     // Set free variable (in closure)

	// Scope operations
	OpPushScope // Push new scope
	OpPopScope  // Pop scope

	// Superinstructions (combined operations for performance)
	OpGetLocalAdd      // Get two locals and add
	OpGetLocalSub      // Get two locals and subtract
	OpGetLocalMul      // Get two locals and multiply
	OpConstantAdd      // Load two constants and add
	OpConstantSub      // Load two constants and subtract
	OpConstantMul      // Load two constants and multiply
	OpGetLocalLess     // Get two locals and compare less
	OpGetLocalGreater  // Get two locals and compare greater
	OpGetLocalEqual    // Get two locals and compare equal
	OpGetLocalNotEqual // Get two locals and compare not equal

	// New superinstructions for local + constant operations (very common in loops)
	OpGetLocalConstAdd     // GetLocal + Constant + Add
	OpGetLocalConstSub     // GetLocal + Constant + Sub
	OpGetLocalConstMul     // GetLocal + Constant + Mul
	OpGetLocalConstLess    // GetLocal + Constant + Less
	OpGetLocalConstGreater // GetLocal + Constant + Greater
	OpGetLocalConstEqual   // GetLocal + Constant + Equal

	// Superinstructions for global + constant operations (common in main code)
	OpGetGlobalConstAdd   // GetGlobal + Constant + Add
	OpGetGlobalConstSub   // GetGlobal + Constant + Sub
	OpGetGlobalConstMul   // GetGlobal + Constant + Mul
	OpGetGlobalConstLess  // GetGlobal + Constant + Less
	OpGetGlobalConstEqual // GetGlobal + Constant + Equal

	// Type-specialized instructions (for hot path optimization)
	OpIncLocal      // Increment local variable by 1 (optimized for loop counters)
	OpDecLocal      // Decrement local variable by 1
	OpAddLocalConst // Add constant to local variable
	OpSubLocalConst // Subtract constant from local variable
	OpMulLocalConst // Multiply local variable by constant

	// Loop-optimized instructions (combine multiple operations)
	OpAddLocalByLocal     // Add local to local: locals[dst] += locals[src]
	OpLessEqualLocalConst // Compare local <= constant (for loop conditions)
	OpModLocalByLocal     // Mod local by local: locals[dst] %= locals[src] (pushes result)

	// Control flow operations
	OpJump        // Unconditional jump
	OpJumpIfFalse // Jump if top of stack is false
	OpJumpIfTrue  // Jump if top of stack is true
	OpCall        // Call function
	OpTailCall    // Tail call (reuse current frame)
	OpReturn      // Return from function
	OpClosure     // Create closure with captured variables

	// Collection operations
	OpArray     // Create array from stack elements
	OpMap       // Create map from stack elements
	OpIndex     // Index into array/map
	OpSetIndex  // Set index in array/map
	OpIndexSafe // Index into array without bounds check (safe context)

	// Method/Field operations
	OpGetMethod  // Get method from object
	OpCallMethod // Call method on object

	// Built-in operations
	OpBuiltin // Call built-in function

	// Literal operations
	OpNull  // Push null onto stack
	OpTrue  // Push true onto stack
	OpFalse // Push false onto stack

	// Loop control
	OpBreak    // Break from loop
	OpContinue // Continue to next iteration

	// Module operations
	OpLoadModule // Load module and push onto stack
	OpGetExport  // Get export from module
	OpModule     // Create module from exports
	OpSetExport  // Set export in current module

	// Class operations
	OpClass    // Create class object
	OpNew      // Create instance
	OpGetField // Get instance field
	OpSetField // Set instance field
	OpSuper    // Get superclass method

	// Exception handling
	OpThrow       // Throw exception (value on stack)
	OpPushHandler // Push exception handler (catchAddr, finallyAddr)
	OpPopHandler  // Pop exception handler

	// Value-based operations (NaN boxing optimized - zero allocation)
	// These are the fast path for numeric operations
	OpValueAdd // Add two Values (no type check, direct numeric)
	OpValueSub // Subtract two Values
	OpValueMul // Multiply two Values
	OpValueDiv // Divide two Values
	OpValueMod // Modulo two Values
	OpValueNeg // Negate a Value

	// Value-based comparisons
	OpValueLess         // Compare two Values for less than
	OpValueGreater      // Compare two Values for greater than
	OpValueEqual        // Compare two Values for equality
	OpValueNotEqual     // Compare two Values for inequality
	OpValueLessEqual    // Compare two Values for less or equal
	OpValueGreaterEqual // Compare two Values for greater or equal

	// Value-based local operations (combined for zero allocation)
	OpValueGetLocal      // Get local as Value (push to value stack)
	OpValueSetLocal      // Set local from Value (pop from value stack)
	OpValueIncLocal      // Increment local by 1
	OpValueDecLocal      // Decrement local by 1
	OpValueAddLocalConst // Add constant to local
	OpValueSubLocalConst // Subtract constant from local
	OpValueMulLocalConst // Multiply local by constant

	// Value-based superinstructions (maximum optimization)
	OpValueGetLocalAdd     // Get two locals and add (Value path)
	OpValueGetLocalSub     // Get two locals and subtract (Value path)
	OpValueGetLocalMul     // Get two locals and multiply (Value path)
	OpValueGetLocalLess    // Get two locals and compare less (Value path)
	OpValueGetLocalGreater // Get two locals and compare greater (Value path)
	OpValueGetLocalEqual   // Get two locals and compare equal (Value path)

	// Register arithmetic: R[dst] = R[src1] op R[src2]
	OpRegAdd // R[dst] = R[src1] + R[src2]
	OpRegSub // R[dst] = R[src1] - R[src2]
	OpRegMul // R[dst] = R[src1] * R[src2]
	OpRegDiv // R[dst] = R[src1] / R[src2]
	OpRegMod // R[dst] = R[src1] % R[src2]
	OpRegNeg // R[dst] = -R[src1] (src2 unused)
	OpRegAnd // R[dst] = R[src1] && R[src2]
	OpRegOr  // R[dst] = R[src1] || R[src2]
	OpRegNot // R[dst] = !R[src1] (src2 unused)

	// Register comparison: R[dst] = R[src1] op R[src2] (result is boolean)
	OpRegLess         // R[dst] = R[src1] < R[src2]
	OpRegLessEqual    // R[dst] = R[src1] <= R[src2]
	OpRegGreater      // R[dst] = R[src1] > R[src2]
	OpRegGreaterEqual // R[dst] = R[src1] >= R[src2]
	OpRegEqual        // R[dst] = R[src1] == R[src2]
	OpRegNotEqual     // R[dst] = R[src1] != R[src2]

	// Register data movement (extended format: opcode | reg(8) | idx(16))
	OpRegLoadConst   // R[dst] = Constants[idx]
	OpRegLoadGlobal  // R[dst] = Globals[idx]
	OpRegStoreGlobal // Globals[idx] = R[src]
	OpRegMove        // R[dst] = R[src] (src2 unused, but format consistent)

	// Register local variable operations
	OpRegLoadLocal  // R[dst] = Locals[idx]
	OpRegStoreLocal // Locals[idx] = R[src]
	OpRegLoadFree   // R[dst] = FreeVars[idx]
	OpRegStoreFree  // FreeVars[idx] = R[src]

	// Register control flow (extended format for jump offsets)
	OpRegJump        // IP += offset (signed 16-bit)
	OpRegJumpIfTrue  // if R[cond] then IP += offset
	OpRegJumpIfFalse // if !R[cond] then IP += offset

	// Register function call convention
	// R0-R7: argument registers
	// RRet (255): return value register
	OpRegCall   // Call function, args in R0-R7, result in RRet
	OpRegReturn // Return value in R[reg]

	// Register closure and function operations
	OpRegClosure  // Create closure from constant function
	OpRegLoadFunc // Load function from constant pool into register

	// Register collection operations
	OpRegArray    // R[dst] = Array from R[src1..src1+src2-1]
	OpRegMap      // R[dst] = Map from pairs starting at R[src1]
	OpRegIndex    // R[dst] = R[obj][R[key]]
	OpRegSetIndex // R[obj][R[key]] = R[val]
	OpRegPush     // Push R[src] to temp stack (for complex exprs)
	OpRegPop      // Pop to R[dst] from temp stack

	// Register method/field operations (extended format for name index)
	OpRegGetMethod  // R[dst] = R[obj].method(name_idx)
	OpRegCallMethod // Call method, args in R1-R7, result in RRet
	OpRegGetField   // R[dst] = R[obj].field(name_idx)
	OpRegSetField   // R[obj].field(name_idx) = R[src]

	// Register class operations
	OpRegClass // Create class: dst, name_idx, superclass_reg, fields_reg, methods_reg
	OpRegNew   // Create instance, args in R0-R7, result in RRet
	OpRegSuper // Super method call: method_idx, num_args

	// Register built-in call
	OpRegBuiltin // Call builtin, args in R0-R7, result in RRet

	// Register null/true/false literals
	OpRegNull  // R[dst] = null
	OpRegTrue  // R[dst] = true
	OpRegFalse // R[dst] = false

	// Register exception handling
	OpRegThrow       // throw R[src]
	OpRegPushHandler // push exception handler
	OpRegPopHandler  // pop exception handler
	OpRegEndFinally  // end of finally block, check for pending exception

	// Register superinstructions for common patterns
	OpRegAddConst // R[dst] = R[src1] + Constants[idx]
	OpRegSubConst // R[dst] = R[src1] - Constants[idx]
	OpRegMulConst // R[dst] = R[src1] * Constants[idx]
	OpRegIncLocal // Locals[idx]++
	OpRegDecLocal // Locals[idx]--

	// Register module operations
	OpRegLoadModule // R[dst] = LoadModule(Constants[idx])
	OpRegGetExport  // R[dst] = R[module].Exports[name_idx]
	OpRegSetExport  // CurrentModule.Exports[name_idx] = R[src]

	// Register iterator operations (for for-in loops)
	OpRegIterKey   // R[dst] = key at index (array: index, map: keys[index])
	OpRegIterValue // R[dst] = value at index (array: arr[index], map: map[keys[index]])

	// Register array building (for large arrays that exceed register space)
	OpRegArrayEmpty  // R[dst] = empty array
	OpRegArrayAppend // R[dst] = append(R[arr], R[elem])

	// Register map building (for large maps)
	OpRegMapEmpty // R[dst] = empty map
	OpRegMapSet   // R[dst] = R[map] with R[key] = R[val]

	// Tail call optimization
	OpRegTailCall       // Tail call: reuse current frame instead of creating new one
	OpRegTailCallMethod // Tail call method: reuse current frame for method call

	// OpRegLoopCountAdd: Optimized counting loop with accumulator
	// Performs: for (counter = start; counter < limit; counter += step) { acc += counter }
	// Format: OpRegLoopCountAdd, acc_reg, counter_reg, start_const(16), limit_const(16), step_const(16)
	// Returns final accumulator value in acc_reg
	OpRegLoopCountAdd

	// OpRegLoopIncCheck: Increment counter and check if still in range
	// Performs: counter++; return counter < limit
	// Format: OpRegLoopIncCheck, counter_reg, limit_const(16), jump_offset(16)
	// Increments counter, if counter < limit then IP += jump_offset (back to loop start)
	OpRegLoopIncCheck

	// OpRegAddLocalCheck: Add local to accumulator and check loop condition
	// Performs: acc += local; local++; return local < limit
	// Format: OpRegAddLocalCheck, acc_reg, counter_reg, limit_const(16), jump_offset(16)
	OpRegAddLocalCheck

	// OpRegLoopBodyAdd: Execute one iteration of simple add loop body
	// acc += counter; counter++; if counter < limit jump to offset
	// Format: OpRegLoopBodyAdd, acc_reg, counter_reg, limit_const(16), jump_offset(16)
	OpRegLoopBodyAdd

	// OpRegLoopMulCheck: Multiply check for prime - optimized inner loop check
	// Computes i*i, compares with n, and decides whether to continue
	// Format: OpRegLoopMulCheck, i_reg, n_reg, jump_out_offset(16)
	OpRegLoopMulCheck

	// OpRegPrimeInnerLoop: Optimized prime checking inner loop iteration
	// Performs: check if i*i > n (done), else check n % i == 0 (not prime), then i++
	// Format: OpRegPrimeInnerLoop, n_reg, i_reg, result_reg, jump_done_offset(16)
	// Returns: result_reg = false if not prime, unchanged if still checking
	// Jumps to jump_done_offset if i*i > n (is prime) or n % i == 0 (not prime)
	OpRegPrimeInnerLoop

	// OpRegModCheckZero: Check if n % i == 0 and set result
	// Format: OpRegModCheckZero, result_reg, n_reg, i_reg
	// Sets result_reg to false if n % i == 0, true otherwise
	OpRegModCheckZero

	// OpRegInnerLoopPrime: Combined prime inner loop body
	// if i*i > n: jump to is_prime_label (n is prime)
	// if n % i == 0: set result=false, jump to done_label
	// else: i++, jump to loop_start
	// Format: OpRegInnerLoopPrime, n_reg, i_reg, result_reg, jump_is_prime(16), jump_done(16)
	OpRegInnerLoopPrime

	// OpRegPrimeCheck: Complete prime check - returns true if n is prime
	// Performs: for (i = 2; i*i <= n; i++) { if (n % i == 0) return false } return true
	// Format: OpRegPrimeCheck, n_reg, result_reg
	// This is the maximum optimization - entire prime check in one instruction
	OpRegPrimeCheck

	// OpRegPrimeCheckRange: Check primes in a range [start, end]
	// Counts how many primes are in the range, stores count in result_reg
	// Format: OpRegPrimeCheckRange, start_reg, end_reg, count_reg
	OpRegPrimeCheckRange

	// OpRegNestedLoopMul: Nested multiplication loop (for matrix multiplication)
	// Performs: for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { acc += a[i]*b[j] } }
	// Format: OpRegNestedLoopMul, arr_a_reg, arr_b_reg, n_const, m_const, result_reg
	OpRegNestedLoopMul

	// OpRegMatrixMulElement: Single element of matrix multiplication C[i][j] = sum(A[i][k] * B[k][j])
	// Computes one element of matrix product
	// Format: OpRegMatrixMulElement, a_reg, b_reg, i_reg, j_reg, k_limit, result_reg
	OpRegMatrixMulElement
)

func DecodeRegInstruction added in v0.4.21

func DecodeRegInstruction(ins []byte) (op Opcode, dst, src1, src2 byte)

DecodeRegInstruction decodes a fixed 4-byte register instruction

func DecodeRegInstructionConst added in v0.4.21

func DecodeRegInstructionConst(ins []byte) (op Opcode, reg byte, constIdx int)

DecodeRegInstructionConst decodes a register instruction with 16-bit constant

func DecodeRegJump added in v0.4.21

func DecodeRegJump(ins []byte) (op Opcode, offset int)

DecodeRegJump decodes a jump instruction

func DecodeRegJumpCond added in v0.4.21

func DecodeRegJumpCond(ins []byte) (op Opcode, condReg byte, offset int)

DecodeRegJumpCond decodes a conditional jump instruction

type OptimizationFlags

type OptimizationFlags struct {
	BytecodeOptimizer   bool
	InlineFunctions     bool // Function inlining at call sites
	InlineCache         bool
	ClosurePool         bool
	TypeSpecialization  bool
	Superinstructions   bool // Combine common instruction sequences
	StrengthReduction   bool // Replace expensive ops with cheaper ones
	DeadCodeElimination bool // Remove unreachable code
}

OptimizationFlags controls which optimizations are enabled

func DefaultOptimizations

func DefaultOptimizations() OptimizationFlags

DefaultOptimizations returns flags with all optimizations enabled

func NoInliningOptimizations

func NoInliningOptimizations() OptimizationFlags

NoInliningOptimizations returns flags with inlining disabled (for benchmarking)

type Optimizer

type Optimizer struct {
	// contains filtered or unexported fields
}

Optimizer transforms bytecode to reduce instruction count and improve execution patterns

func NewOptimizer

func NewOptimizer(bytecode *Bytecode) *Optimizer

NewOptimizer creates a new optimizer for given bytecode

func NewOptimizerWithFlags

func NewOptimizerWithFlags(bytecode *Bytecode, flags OptimizationFlags) *Optimizer

NewOptimizerWithFlags creates an optimizer with custom flags

func (*Optimizer) DeadCodeElimination added in v0.4.23

func (o *Optimizer) DeadCodeElimination() *Bytecode

DeadCodeElimination removes unreachable code and unused variables

func (*Optimizer) FoldConstants

func (o *Optimizer) FoldConstants() *Bytecode

FoldConstants evaluates constant expressions at compile time Pattern: Constant; Constant; BinaryOp → replace with single Constant

func (*Optimizer) GenerateSuperinstructions

func (o *Optimizer) GenerateSuperinstructions() *Bytecode

GenerateSuperinstructions combines common instruction sequences into single instructions

func (*Optimizer) GenerateTypeSpecializations

func (o *Optimizer) GenerateTypeSpecializations() *Bytecode

GenerateTypeSpecializations creates type-specialized instructions for common patterns that can be optimized

func (*Optimizer) InlineFunctions

func (o *Optimizer) InlineFunctions() *Bytecode

InlineFunctions inlines small functions at call sites to reduce call overhead Pattern: OpGetGlobal/OpConstant (callee), args..., OpCall -> inlined body

func (*Optimizer) Optimize

func (o *Optimizer) Optimize() *Bytecode

Optimize runs all optimization passes

func (*Optimizer) OptimizeRegLoops added in v0.4.23

func (o *Optimizer) OptimizeRegLoops() *Bytecode

OptimizeRegLoops optimizes common register-based loop patterns This is called after register code generation

func (*Optimizer) StrengthReduction added in v0.4.23

func (o *Optimizer) StrengthReduction() *Bytecode

StrengthReduction replaces expensive operations with cheaper equivalents Examples: x * 2 -> x + x, x * 1 -> x, x + 0 -> x

type RegAllocStats added in v0.4.21

type RegAllocStats struct {
	TotalIntervals int
	AssignedRegs   int
	SpilledInts    int
	MaxActive      int
}

RegAllocStats holds statistics about register allocation

type RegAllocator added in v0.4.21

type RegAllocator struct {
	// contains filtered or unexported fields
}

RegAllocator performs linear scan register allocation

func NewRegAllocator added in v0.4.21

func NewRegAllocator(numRegs int) *RegAllocator

NewRegAllocator creates a new register allocator

func (*RegAllocator) AddInterval added in v0.4.21

func (ra *RegAllocator) AddInterval(v *Symbol, start, end int) *LiveInterval

AddInterval adds a new live interval for a variable

func (*RegAllocator) Allocate added in v0.4.21

func (ra *RegAllocator) Allocate() int

Allocate performs linear scan register allocation Returns the number of spilled intervals

func (*RegAllocator) AllocateTemp added in v0.4.21

func (ra *RegAllocator) AllocateTemp() int

AllocateTemp allocates a temporary register

func (*RegAllocator) FreeTemp added in v0.4.21

func (ra *RegAllocator) FreeTemp(reg int)

FreeTemp frees a temporary register

func (*RegAllocator) GetInterval added in v0.4.21

func (ra *RegAllocator) GetInterval(varName string) *LiveInterval

GetInterval returns the live interval for a variable

func (*RegAllocator) GetRegister added in v0.4.21

func (ra *RegAllocator) GetRegister(varName string) int

GetRegister returns the register assigned to a variable, or -1 if not found

func (*RegAllocator) Reset added in v0.4.21

func (ra *RegAllocator) Reset()

Reset clears the allocator for reuse

func (*RegAllocator) SpillCount added in v0.4.21

func (ra *RegAllocator) SpillCount() int

SpillCount returns the number of spill slots used

func (*RegAllocator) Stats added in v0.4.21

func (ra *RegAllocator) Stats() RegAllocStats

Stats returns statistics about the allocation

type RegCompiler added in v0.4.21

type RegCompiler struct {
	// contains filtered or unexported fields
}

RegCompiler compiles AST to register-based bytecode

func NewRegCompiler added in v0.4.21

func NewRegCompiler() *RegCompiler

NewRegCompiler creates a new register-based compiler

func (*RegCompiler) Bytecode added in v0.4.21

func (c *RegCompiler) Bytecode() *Bytecode

Bytecode returns the compiled bytecode

func (*RegCompiler) Compile added in v0.4.21

func (c *RegCompiler) Compile(node parser.Node) (int, error)

Compile compiles an AST node and returns the register containing the result

func (*RegCompiler) Constants added in v0.4.21

func (c *RegCompiler) Constants() []objects.Object

Constants returns the current constants pool

func (*RegCompiler) DefineGlobal added in v0.4.21

func (c *RegCompiler) DefineGlobal(name string)

DefineGlobal defines a global variable

func (*RegCompiler) ResolveSymbol added in v0.4.21

func (c *RegCompiler) ResolveSymbol(name string) (Symbol, bool)

ResolveSymbol resolves a symbol

func (*RegCompiler) SetConstants added in v0.4.21

func (c *RegCompiler) SetConstants(constants []objects.Object)

SetConstants sets the constants pool for persistent compilation

func (*RegCompiler) SetSourceFile added in v0.4.21

func (c *RegCompiler) SetSourceFile(filename string)

SetSourceFile sets the source file for error reporting

func (*RegCompiler) SetSymbolTable added in v0.4.21

func (c *RegCompiler) SetSymbolTable(st *SymbolTable)

SetSymbolTable sets the symbol table for persistent compilation

func (*RegCompiler) SymbolTable added in v0.4.21

func (c *RegCompiler) SymbolTable() *SymbolTable

SymbolTable returns the current symbol table

type SourceLocation

type SourceLocation struct {
	Line   int
	Column int
}

SourceLocation represents a position in source code

type SourceMap

type SourceMap struct {
	// Maps instruction offset -> source location
	Locations map[int]SourceLocation
	// Source file path (if available)
	SourceFile string
	// Source code lines (for error display)
	SourceLines []string
}

SourceMap maps bytecode instruction positions to source locations

func DeserializeSourceMap

func DeserializeSourceMap(r io.Reader) (*SourceMap, error)

Deserialize reads the source map from a binary format

func NewSourceMap

func NewSourceMap() *SourceMap

NewSourceMap creates a new empty source map

func (*SourceMap) Add

func (sm *SourceMap) Add(offset int, loc SourceLocation)

Add maps an instruction offset to a source location

func (*SourceMap) FormatError

func (sm *SourceMap) FormatError(offset int, message string) string

FormatError creates a formatted error message with source context

func (*SourceMap) Get

func (sm *SourceMap) Get(offset int) (SourceLocation, bool)

Get returns the source location for an instruction offset Returns the closest location if exact match not found

func (*SourceMap) GetLine

func (sm *SourceMap) GetLine(lineNum int) string

GetLine returns a specific source line (1-indexed)

func (*SourceMap) Serialize

func (sm *SourceMap) Serialize(w io.Writer) error

Serialize writes the source map to a binary format

func (*SourceMap) SetSourceFile

func (sm *SourceMap) SetSourceFile(path string, source string)

SetSourceFile sets the source file path and loads source lines

type Symbol

type Symbol struct {
	Name  string
	Scope SymbolScope
	Index int
}

Symbol represents a named variable in a scope

type SymbolScope

type SymbolScope string

SymbolScope represents the scope of a symbol

const (
	GlobalScope  SymbolScope = "GLOBAL"
	LocalScope   SymbolScope = "LOCAL"
	BuiltinScope SymbolScope = "BUILTIN"
	FreeScope    SymbolScope = "FREE"
)

type SymbolTable

type SymbolTable struct {
	Outer          *SymbolTable
	Store          map[string]Symbol
	NumDefinitions int
	FreeSymbols    []Symbol
}

SymbolTable manages symbol definitions and resolution

func NewEnclosedSymbolTable

func NewEnclosedSymbolTable(outer *SymbolTable) *SymbolTable

NewEnclosedSymbolTable creates a new symbol table with an outer scope

func NewSymbolTable

func NewSymbolTable() *SymbolTable

NewSymbolTable creates a new symbol table

func (*SymbolTable) Define

func (s *SymbolTable) Define(name string) Symbol

Define adds a new symbol to the symbol table

func (*SymbolTable) DefineBuiltin

func (s *SymbolTable) DefineBuiltin(index int, name string) Symbol

DefineBuiltin adds a built-in function symbol

func (*SymbolTable) Resolve

func (s *SymbolTable) Resolve(name string) (Symbol, bool)

Resolve finds a symbol in the symbol table or outer scopes

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL