value.go 7.3 KB

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