github.com/yuin/gopher-lua@v1.1.2-0.20231212122839-2348fd042596/value.go (about) 1 package lua 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 ) 8 9 type LValueType int 10 11 const ( 12 LTNil LValueType = iota 13 LTBool 14 LTNumber 15 LTString 16 LTFunction 17 LTUserData 18 LTThread 19 LTTable 20 LTChannel 21 ) 22 23 var lValueNames = [9]string{"nil", "boolean", "number", "string", "function", "userdata", "thread", "table", "channel"} 24 25 func (vt LValueType) String() string { 26 return lValueNames[int(vt)] 27 } 28 29 type LValue interface { 30 String() string 31 Type() LValueType 32 } 33 34 // LVIsFalse returns true if a given LValue is a nil or false otherwise false. 35 func LVIsFalse(v LValue) bool { return v == LNil || v == LFalse } 36 37 // LVIsFalse returns false if a given LValue is a nil or false otherwise true. 38 func LVAsBool(v LValue) bool { return v != LNil && v != LFalse } 39 40 // LVAsString returns string representation of a given LValue 41 // if the LValue is a string or number, otherwise an empty string. 42 func LVAsString(v LValue) string { 43 switch sn := v.(type) { 44 case LString, LNumber: 45 return sn.String() 46 default: 47 return "" 48 } 49 } 50 51 // LVCanConvToString returns true if a given LValue is a string or number 52 // otherwise false. 53 func LVCanConvToString(v LValue) bool { 54 switch v.(type) { 55 case LString, LNumber: 56 return true 57 default: 58 return false 59 } 60 } 61 62 // LVAsNumber tries to convert a given LValue to a number. 63 func LVAsNumber(v LValue) LNumber { 64 switch lv := v.(type) { 65 case LNumber: 66 return lv 67 case LString: 68 if num, err := parseNumber(string(lv)); err == nil { 69 return num 70 } 71 } 72 return LNumber(0) 73 } 74 75 type LNilType struct{} 76 77 func (nl *LNilType) String() string { return "nil" } 78 func (nl *LNilType) Type() LValueType { return LTNil } 79 80 var LNil = LValue(&LNilType{}) 81 82 type LBool bool 83 84 func (bl LBool) String() string { 85 if bool(bl) { 86 return "true" 87 } 88 return "false" 89 } 90 func (bl LBool) Type() LValueType { return LTBool } 91 92 var LTrue = LBool(true) 93 var LFalse = LBool(false) 94 95 type LString string 96 97 func (st LString) String() string { return string(st) } 98 func (st LString) Type() LValueType { return LTString } 99 100 // fmt.Formatter interface 101 func (st LString) Format(f fmt.State, c rune) { 102 switch c { 103 case 'd', 'i': 104 if nm, err := parseNumber(string(st)); err != nil { 105 defaultFormat(nm, f, 'd') 106 } else { 107 defaultFormat(string(st), f, 's') 108 } 109 default: 110 defaultFormat(string(st), f, c) 111 } 112 } 113 114 func (nm LNumber) String() string { 115 if isInteger(nm) { 116 return fmt.Sprint(int64(nm)) 117 } 118 return fmt.Sprint(float64(nm)) 119 } 120 121 func (nm LNumber) Type() LValueType { return LTNumber } 122 123 // fmt.Formatter interface 124 func (nm LNumber) Format(f fmt.State, c rune) { 125 switch c { 126 case 'q', 's': 127 defaultFormat(nm.String(), f, c) 128 case 'b', 'c', 'd', 'o', 'x', 'X', 'U': 129 defaultFormat(int64(nm), f, c) 130 case 'e', 'E', 'f', 'F', 'g', 'G': 131 defaultFormat(float64(nm), f, c) 132 case 'i': 133 defaultFormat(int64(nm), f, 'd') 134 default: 135 if isInteger(nm) { 136 defaultFormat(int64(nm), f, c) 137 } else { 138 defaultFormat(float64(nm), f, c) 139 } 140 } 141 } 142 143 type LTable struct { 144 Metatable LValue 145 146 array []LValue 147 dict map[LValue]LValue 148 strdict map[string]LValue 149 keys []LValue 150 k2i map[LValue]int 151 } 152 153 func (tb *LTable) String() string { return fmt.Sprintf("table: %p", tb) } 154 func (tb *LTable) Type() LValueType { return LTTable } 155 156 type LFunction struct { 157 IsG bool 158 Env *LTable 159 Proto *FunctionProto 160 GFunction LGFunction 161 Upvalues []*Upvalue 162 } 163 type LGFunction func(*LState) int 164 165 func (fn *LFunction) String() string { return fmt.Sprintf("function: %p", fn) } 166 func (fn *LFunction) Type() LValueType { return LTFunction } 167 168 type Global struct { 169 MainThread *LState 170 CurrentThread *LState 171 Registry *LTable 172 Global *LTable 173 174 builtinMts map[int]LValue 175 tempFiles []*os.File 176 gccount int32 177 } 178 179 type LState struct { 180 G *Global 181 Parent *LState 182 Env *LTable 183 Panic func(*LState) 184 Dead bool 185 Options Options 186 187 stop int32 188 reg *registry 189 stack callFrameStack 190 alloc *allocator 191 currentFrame *callFrame 192 wrapped bool 193 uvcache *Upvalue 194 hasErrorFunc bool 195 mainLoop func(*LState, *callFrame) 196 ctx context.Context 197 ctxCancelFn context.CancelFunc 198 } 199 200 func (ls *LState) String() string { return fmt.Sprintf("thread: %p", ls) } 201 func (ls *LState) Type() LValueType { return LTThread } 202 203 type LUserData struct { 204 Value interface{} 205 Env *LTable 206 Metatable LValue 207 } 208 209 func (ud *LUserData) String() string { return fmt.Sprintf("userdata: %p", ud) } 210 func (ud *LUserData) Type() LValueType { return LTUserData } 211 212 type LChannel chan LValue 213 214 func (ch LChannel) String() string { return fmt.Sprintf("channel: %p", ch) } 215 func (ch LChannel) Type() LValueType { return LTChannel }