XCTLRuntimeVariable.swift 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. //
  2. // XCTLRuntimeVariable.swift
  3. // notebook
  4. //
  5. // Created by 邢铖 on 2023/5/18.
  6. //
  7. import Foundation
  8. public class XCTLRuntimeVariable: NSObject {
  9. public var type: XCTLRuntimeVariableType
  10. public var rawValue: String
  11. public var rawObject: NSObject?
  12. public var rawFunction: (([XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable)?
  13. // public var leftValue: XCTLRuntimeVariable?
  14. // public var leftValueMemberName: String?
  15. internal weak var rawFunctionStatement: XCTLStatement?
  16. public func toString() -> String {
  17. if type == .typeFuncImpl || type == .typeFuncIntrinsic {
  18. return "Function"
  19. }
  20. if type == .typeObject {
  21. return self.rawObject?.description ?? ""
  22. }
  23. return self.rawValue
  24. }
  25. public class func variableFromSwiftAny(_ value: Any) throws -> XCTLRuntimeVariable {
  26. if value is NSNull {
  27. return .void
  28. }
  29. if let value = value as? String {
  30. return XCTLRuntimeVariable(type: .typeString, rawValue: value)
  31. }
  32. if let value = value as? Double {
  33. return XCTLRuntimeVariable(type: .typeNumber, rawValue: value.description)
  34. }
  35. if let value = value as? Bool {
  36. return XCTLRuntimeVariable(type: .typeBoolean, rawValue: value.description)
  37. }
  38. if let value = value as? NSObject {
  39. return XCTLRuntimeVariable(rawObject: value)
  40. }
  41. throw XCTLRuntimeError.callingTypeEncodingError
  42. }
  43. public init(type: XCTLRuntimeVariableType, rawValue: String) {
  44. self.type = type
  45. self.rawValue = rawValue
  46. self.rawObject = nil
  47. self.rawFunction = nil
  48. }
  49. public init(rawObject: NSObject) {
  50. self.type = .typeObject
  51. self.rawValue = ""
  52. self.rawObject = rawObject
  53. self.rawFunction = nil
  54. }
  55. public init(funcImpl: @escaping ([XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable) {
  56. self.type = .typeFuncIntrinsic
  57. self.rawValue = ""
  58. self.rawObject = nil
  59. self.rawFunction = funcImpl
  60. }
  61. internal init(funcImplStmt: XCTLStatement) {
  62. self.type = .typeFuncImpl
  63. self.rawValue = ""
  64. self.rawObject = nil
  65. self.rawFunction = nil
  66. self.rawFunctionStatement = funcImplStmt
  67. }
  68. public var stringValue: String {
  69. return self.rawValue
  70. }
  71. public var intValue: Int {
  72. return Int(self.rawValue)!
  73. }
  74. public var doubleValue: Double {
  75. return Double(self.rawValue)!
  76. }
  77. public var boolValue: Bool {
  78. return Bool(self.rawValue)!
  79. }
  80. public var objectValue: NSObject {
  81. return self.rawObject!
  82. }
  83. public static var void: XCTLRuntimeVariable {
  84. return XCTLRuntimeVariable(type: .typeVoid, rawValue: "")
  85. }
  86. public var nativeValue: Any {
  87. switch self.type {
  88. case .typeVoid:
  89. return NSNull()
  90. case .typeObject:
  91. return self.objectValue
  92. case .typeString:
  93. return self.stringValue
  94. case .typeNumber:
  95. return self.doubleValue
  96. case .typeBoolean:
  97. return self.boolValue
  98. case .typeFuncIntrinsic:
  99. return self.rawFunction ?? NSNull()
  100. case .typeFuncImpl:
  101. return NSNull()
  102. }
  103. }
  104. public func nativeValue(typeId: Character) throws -> Any {
  105. switch typeId {
  106. case "i":
  107. guard let nativeValue = self.nativeValue as? Double else {
  108. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  109. }
  110. return Int32(nativeValue)
  111. case "I":
  112. guard let nativeValue = self.nativeValue as? Double else {
  113. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  114. }
  115. return UInt32(nativeValue)
  116. case "s":
  117. guard let nativeValue = self.nativeValue as? Double else {
  118. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  119. }
  120. return Int16(nativeValue)
  121. case "S":
  122. guard let nativeValue = self.nativeValue as? Double else {
  123. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  124. }
  125. return UInt16(nativeValue)
  126. case "f":
  127. guard let nativeValue = self.nativeValue as? Double else {
  128. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  129. }
  130. return Float(nativeValue)
  131. case "d":
  132. guard let nativeValue = self.nativeValue as? Double else {
  133. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  134. }
  135. return nativeValue
  136. case "l":
  137. guard let nativeValue = self.nativeValue as? Double else {
  138. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  139. }
  140. return Int64(nativeValue)
  141. case "L":
  142. guard let nativeValue = self.nativeValue as? Double else {
  143. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  144. }
  145. return UInt64(nativeValue)
  146. case "q":
  147. guard let nativeValue = self.nativeValue as? Double else {
  148. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  149. }
  150. return Int64(nativeValue)
  151. case "Q":
  152. guard let nativeValue = self.nativeValue as? Double else {
  153. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  154. }
  155. return UInt64(nativeValue)
  156. case "c":
  157. guard let nativeValue = self.nativeValue as? Double else {
  158. guard let nativeValue = self.nativeValue as? String else {
  159. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  160. }
  161. return Int8((nativeValue.first ?? " ").utf8.first!)
  162. }
  163. return Int8(nativeValue)
  164. case "C":
  165. guard let nativeValue = self.nativeValue as? Double else {
  166. guard let nativeValue = self.nativeValue as? String else {
  167. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  168. }
  169. return UInt8((nativeValue.first ?? " ").utf8.first!)
  170. }
  171. return UInt8(nativeValue)
  172. case "b":
  173. guard let nativeValue = self.nativeValue as? Bool else {
  174. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  175. }
  176. return nativeValue
  177. case "@":
  178. guard let nativeValue = self.nativeValue as? NSObject else {
  179. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: typeId.description, nativeType: self.type.rawValue)
  180. }
  181. return nativeValue
  182. default:
  183. throw XCTLRuntimeError.cannotCastObjectToNativeTypeWhenSetProperty(runtimeType: "\(typeId) (Unknown TypeId)", nativeType: self.type.rawValue)
  184. }
  185. }
  186. public func executeFunc(arg: [XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable {
  187. return try self.rawFunction!(arg)
  188. }
  189. }