XCTLRuntimeSubContext.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //
  2. // XCTLRuntimeSubContext.swift
  3. // notebook
  4. //
  5. // Created by 邢铖 on 2023/5/25.
  6. //
  7. import Foundation
  8. internal class XCTLRuntimeSubContext: XCTLRuntimeAbstractContext {
  9. private let parent: XCTLRuntimeAbstractContext
  10. internal var nativeObjectInstance: NSObject {
  11. self.parent.nativeObjectInstance
  12. }
  13. private var values = [String : XCTLRuntimeVariable]()
  14. internal init(parent: XCTLRuntimeAbstractContext) {
  15. self.parent = parent
  16. }
  17. private var importNames = Set<String>()
  18. private var exportNames = Set<String>()
  19. internal func valueDefined(_ name: String) -> Bool {
  20. if self.values[name] != nil {
  21. return true
  22. }
  23. if self.importNames.contains(name) {
  24. return true
  25. }
  26. return self.parent.valueDefined(name)
  27. }
  28. internal func value(forName name: String) -> XCTLRuntimeVariable? {
  29. if name == "self" {
  30. return XCTLRuntimeVariable(rawObject: self.nativeObjectInstance)
  31. }
  32. if let value = self.values[name] {
  33. return value
  34. }
  35. if importNames.contains(name),
  36. let valueFromNative = self.nativeObjectInstance.value(forKey: name) as? NSObject {
  37. let object = XCTLRuntimeVariable(rawObject: valueFromNative)
  38. self.values[name] = object
  39. return object
  40. }
  41. return self.parent.value(forName: name)
  42. }
  43. internal func setValue(_ value: XCTLRuntimeVariable, forName name: String) {
  44. if self.exportNames.contains(name) {
  45. self.setValueToRoot(value, forName: name)
  46. return
  47. }
  48. if self.values[name] == nil {
  49. if self.valueDefined(name) {
  50. self.parent.setValue(value, forName: name)
  51. return
  52. }
  53. }
  54. self.values[name] = value
  55. }
  56. internal func setValueToRoot(_ value: XCTLRuntimeVariable, forName name: String) {
  57. self.parent.setValueToRoot(value, forName: name)
  58. }
  59. internal func setValueIgnoreParent(_ value: XCTLRuntimeVariable, forName name: String) {
  60. self.values[name] = value
  61. }
  62. internal func addImport(name: String) {
  63. self.importNames.insert(name)
  64. }
  65. internal func addExport(name: String) {
  66. self.exportNames.insert(name)
  67. }
  68. internal func allocateObject(name: String, args: [XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable {
  69. return try self.parent.allocateObject(name: name, args: args)
  70. }
  71. internal func addLazyStatement(_ stmt: XCTLStatement) {
  72. self.parent.addLazyStatement(stmt)
  73. }
  74. internal func makeSubContext() -> XCTLRuntimeAbstractContext {
  75. return XCTLRuntimeSubContext(parent: self)
  76. }
  77. private var conditionFrame: XCTLConditionParentStatementFrame?
  78. private var listFrame: XCTLListStatementFrame?
  79. private var forFrame: XCTLForStatementFrame?
  80. func findConditionFrame() -> XCTLConditionParentStatementFrame? {
  81. if let conditionFrame = self.conditionFrame {
  82. return conditionFrame
  83. }
  84. return self.parent.findConditionFrame()
  85. }
  86. func findListFrame() -> XCTLListStatementFrame? {
  87. if let listFrame = self.listFrame {
  88. return listFrame
  89. }
  90. return self.parent.findListFrame()
  91. }
  92. func recordListFrame(_ frame: XCTLListStatementFrame?) {
  93. self.listFrame = frame
  94. }
  95. func recordConditionFrame(_ frame: XCTLConditionParentStatementFrame?) {
  96. self.conditionFrame = frame
  97. }
  98. func getParentContext() -> XCTLRuntimeAbstractContext? {
  99. return self.parent
  100. }
  101. func findForFrame() -> XCTLForStatementFrame? {
  102. if let forFrame = self.forFrame {
  103. return forFrame
  104. }
  105. return self.parent.findForFrame()
  106. }
  107. func recordForFrame(_ frame: XCTLForStatementFrame?) {
  108. self.forFrame = frame
  109. }
  110. var variableStack = XCTLRuntimeVariableStackFrame()
  111. }