github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/ir/code.go (about)

     1  package ir
     2  
     3  // Constant is the interface implemented by constant values (e.g. numbers,
     4  // strings, but also code chunks).
     5  type Constant interface {
     6  	ProcessConstant(p ConstantProcessor)
     7  }
     8  
     9  // A ConstantProcessor is able to process all the different types of constant
    10  // using the various ProcessXXX methods.
    11  type ConstantProcessor interface {
    12  	ProcessFloat(Float)
    13  	ProcessInt(Int)
    14  	ProcessBool(Bool)
    15  	ProcessString(String)
    16  	ProcessNil(NilType)
    17  	ProcessCode(Code)
    18  }
    19  
    20  // A Float is a constant representing a literal floating point number.
    21  type Float float64
    22  
    23  // ProcessConstant uses the given ConstantProcessor to process the receiver.
    24  func (f Float) ProcessConstant(p ConstantProcessor) {
    25  	p.ProcessFloat(f)
    26  }
    27  
    28  // An Int is a constant representing an integer literal.
    29  type Int int64
    30  
    31  // ProcessConstant uses the given ConstantProcessor to process the receiver.
    32  func (n Int) ProcessConstant(p ConstantProcessor) {
    33  	p.ProcessInt(n)
    34  }
    35  
    36  // A Bool is a constant representing a boolean literal.
    37  type Bool bool
    38  
    39  // ProcessConstant uses the given ConstantProcessor to process the receiver.
    40  func (b Bool) ProcessConstant(p ConstantProcessor) {
    41  	p.ProcessBool(b)
    42  }
    43  
    44  // A String is a constant representing a string literal.
    45  type String string
    46  
    47  // ProcessConstant uses the given ConstantProcessor to process the receiver.
    48  func (s String) ProcessConstant(p ConstantProcessor) {
    49  	p.ProcessString(s)
    50  }
    51  
    52  // NilType is the type of the nil literal.
    53  type NilType struct{}
    54  
    55  // ProcessConstant uses the given ConstantProcessor to process the receiver.
    56  func (n NilType) ProcessConstant(p ConstantProcessor) {
    57  	p.ProcessNil(n)
    58  }
    59  
    60  // Code is the type of code literals (i.e. function definitions).
    61  type Code struct {
    62  	Instructions []Instruction
    63  	Lines        []int
    64  	Constants    []Constant
    65  	UpvalueDests []Register
    66  	Registers    []RegData
    67  	UpNames      []string
    68  	Name         string
    69  }
    70  
    71  // ProcessConstant uses the given ConstantProcessor to process the receiver.
    72  func (c Code) ProcessConstant(p ConstantProcessor) {
    73  	p.ProcessCode(c)
    74  }
    75  
    76  // A ConstantPool accumulates constants and associates a stable integer with
    77  // each constant.
    78  type ConstantPool struct {
    79  	constants []Constant
    80  	kmap      map[Constant]uint // Makes a difference for large number of constants
    81  }
    82  
    83  func NewConstantPool() *ConstantPool {
    84  	return &ConstantPool{
    85  		kmap: map[Constant]uint{},
    86  	}
    87  }
    88  
    89  // GetConstantIndex returns the index associated with a given constant.  If
    90  // there is none, the constant is registered in the pool and the new index is
    91  // returned.
    92  func (c *ConstantPool) GetConstantIndex(k Constant) uint {
    93  	i, ok := c.kmap[k]
    94  	if !ok {
    95  		i = uint(len(c.constants))
    96  		c.kmap[k] = i
    97  		c.constants = append(c.constants, k)
    98  	}
    99  	return i
   100  }
   101  
   102  // Constants returns the list of all constants registered with this pool.
   103  func (c *ConstantPool) Constants() []Constant {
   104  	return c.constants
   105  }