value.go 4.5 KB

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