Explorar o código

Fix bugs for lazy run

xcbosa mbp16 %!s(int64=2) %!d(string=hai) anos
pai
achega
ff7bc5b332

+ 32 - 0
XCTreeLang.xcodeproj/xcuserdata/xcbosa.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -1572,5 +1572,37 @@
             landmarkType = "7">
             landmarkType = "7">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "6CB59A97-9D25-43E6-A121-928B7E6173AB"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/VirtualStatement/XCTLPrefixExpression.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "68"
+            endingLineNumber = "68"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "1F7E1418-8F5A-4947-9C07-F22A8406BA72"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLFunctionCallStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "94"
+            endingLineNumber = "94"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
    </Breakpoints>
 </Bucket>
 </Bucket>

+ 4 - 2
XCTreeLang/Runtime/XCTLRuntimeAbstractContext.swift

@@ -32,14 +32,16 @@ internal protocol XCTLRuntimeAbstractContext: AnyObject {
     func valueDefined(_ name: String) -> Bool
     func valueDefined(_ name: String) -> Bool
     func value(forName name: String) -> XCTLRuntimeVariable?
     func value(forName name: String) -> XCTLRuntimeVariable?
     func setValue(_ value: XCTLRuntimeVariable, forName name: String)
     func setValue(_ value: XCTLRuntimeVariable, forName name: String)
-    func setValueToRoot(_ value: XCTLRuntimeVariable, forName name: String)
+    func setValueToRoot(_ value: XCTLRuntimeVariable, forName name: String, assumeExport export: Bool)
+    func setValueToRootAssumeExport(_ value: XCTLRuntimeVariable, forName name: String)
     func setValueIgnoreParent(_ value: XCTLRuntimeVariable, forName name: String)
     func setValueIgnoreParent(_ value: XCTLRuntimeVariable, forName name: String)
     
     
     func addImport(name: String)
     func addImport(name: String)
     func addExport(name: String)
     func addExport(name: String)
+    func hasExport(name: String) -> Bool
     
     
     func allocateObject(name: String, args: [XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable
     func allocateObject(name: String, args: [XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable
-    func addLazyStatement(_ stmt: XCTLStatement)
+    func addLazyStatement(_ stmt: XCTLReferencedVariableStatement)
     
     
     func makeSubContext() -> XCTLRuntimeAbstractContext
     func makeSubContext() -> XCTLRuntimeAbstractContext
     
     

+ 15 - 3
XCTreeLang/Runtime/XCTLRuntimeContext.swift

@@ -16,7 +16,7 @@ internal class XCTLRuntimeContext: XCTLRuntimeAbstractContext {
     
     
     private var values = [String : XCTLRuntimeVariable]()
     private var values = [String : XCTLRuntimeVariable]()
     
     
-    internal private(set) var lazyRunStatements = [XCTLStatement]()
+    internal private(set) var lazyRunStatements = [XCTLReferencedVariableStatement]()
     
     
     internal let stdout = XCTLStream(onAppendBlock: {
     internal let stdout = XCTLStream(onAppendBlock: {
         print($0, terminator: "")
         print($0, terminator: "")
@@ -189,11 +189,19 @@ internal class XCTLRuntimeContext: XCTLRuntimeAbstractContext {
         }
         }
     }
     }
     
     
-    internal func setValueToRoot(_ value: XCTLRuntimeVariable, forName name: String) {
+    internal func setValueToRootAssumeExport(_ value: XCTLRuntimeVariable, forName name: String) {
         self.values[name] = value
         self.values[name] = value
         self.nativeObjectInstance.setValue(value.nativeValue, forKey: name)
         self.nativeObjectInstance.setValue(value.nativeValue, forKey: name)
     }
     }
     
     
+    internal func setValueToRoot(_ value: XCTLRuntimeVariable, forName name: String, assumeExport export: Bool) {
+        self.values[name] = value
+        let doExport = export || self.exportNames.contains(name)
+        if doExport {
+            self.nativeObjectInstance.setValue(value.nativeValue, forKey: name)
+        }
+    }
+    
     internal func setValueIgnoreParent(_ value: XCTLRuntimeVariable, forName name: String) {
     internal func setValueIgnoreParent(_ value: XCTLRuntimeVariable, forName name: String) {
         self.setValue(value, forName: name)
         self.setValue(value, forName: name)
     }
     }
@@ -206,6 +214,10 @@ internal class XCTLRuntimeContext: XCTLRuntimeAbstractContext {
         self.exportNames.insert(name)
         self.exportNames.insert(name)
     }
     }
     
     
+    internal func hasExport(name: String) -> Bool {
+        return self.exportNames.contains(name)
+    }
+    
     internal func allocateObject(name: String, args: [XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable {
     internal func allocateObject(name: String, args: [XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable {
         if let generator = self.generators[name] {
         if let generator = self.generators[name] {
             let nativeObject = try generator.initWithXCT(args.compactMap({ $0.nativeValue }))
             let nativeObject = try generator.initWithXCT(args.compactMap({ $0.nativeValue }))
@@ -223,7 +235,7 @@ internal class XCTLRuntimeContext: XCTLRuntimeAbstractContext {
         throw XCTLRuntimeError.generateProtocolNotFoundedError(name: name)
         throw XCTLRuntimeError.generateProtocolNotFoundedError(name: name)
     }
     }
     
     
-    internal func addLazyStatement(_ stmt: XCTLStatement) {
+    internal func addLazyStatement(_ stmt: XCTLReferencedVariableStatement) {
         self.lazyRunStatements.append(stmt)
         self.lazyRunStatements.append(stmt)
     }
     }
     
     

+ 18 - 5
XCTreeLang/Runtime/XCTLRuntimeSubContext.swift

@@ -51,8 +51,8 @@ internal class XCTLRuntimeSubContext: XCTLRuntimeAbstractContext {
     }
     }
     
     
     internal func setValue(_ value: XCTLRuntimeVariable, forName name: String) {
     internal func setValue(_ value: XCTLRuntimeVariable, forName name: String) {
-        if self.exportNames.contains(name) {
-            self.setValueToRoot(value, forName: name)
+        if self.hasExport(name: name) {
+            self.setValueToRootAssumeExport(value, forName: name)
             return
             return
         }
         }
         if self.values[name] == nil {
         if self.values[name] == nil {
@@ -64,8 +64,14 @@ internal class XCTLRuntimeSubContext: XCTLRuntimeAbstractContext {
         self.values[name] = value
         self.values[name] = value
     }
     }
     
     
-    internal func setValueToRoot(_ value: XCTLRuntimeVariable, forName name: String) {
-        self.parent.setValueToRoot(value, forName: name)
+    internal func setValueToRootAssumeExport(_ value: XCTLRuntimeVariable, forName name: String) {
+        self.parent.setValueToRootAssumeExport(value, forName: name)
+    }
+    
+    internal func setValueToRoot(_ value: XCTLRuntimeVariable, forName name: String, assumeExport export: Bool) {
+        self.parent.setValueToRoot(value,
+                                   forName: name,
+                                   assumeExport: export || self.exportNames.contains(name))
     }
     }
     
     
     internal func setValueIgnoreParent(_ value: XCTLRuntimeVariable, forName name: String) {
     internal func setValueIgnoreParent(_ value: XCTLRuntimeVariable, forName name: String) {
@@ -80,11 +86,18 @@ internal class XCTLRuntimeSubContext: XCTLRuntimeAbstractContext {
         self.exportNames.insert(name)
         self.exportNames.insert(name)
     }
     }
     
     
+    internal func hasExport(name: String) -> Bool {
+        if self.exportNames.contains(name) {
+            return true
+        }
+        return self.parent.hasExport(name: name)
+    }
+    
     internal func allocateObject(name: String, args: [XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable {
     internal func allocateObject(name: String, args: [XCTLRuntimeVariable]) throws -> XCTLRuntimeVariable {
         return try self.parent.allocateObject(name: name, args: args)
         return try self.parent.allocateObject(name: name, args: args)
     }
     }
     
     
-    internal func addLazyStatement(_ stmt: XCTLStatement) {
+    internal func addLazyStatement(_ stmt: XCTLReferencedVariableStatement) {
         self.parent.addLazyStatement(stmt)
         self.parent.addLazyStatement(stmt)
     }
     }
     
     

+ 3 - 1
XCTreeLang/Statements/XCTLInitStatement.swift

@@ -97,8 +97,10 @@ internal class XCTLInitStatement: XCTLStatement, XCTLExpressionPart {
         context.setValue(object, forName: self.defineName)
         context.setValue(object, forName: self.defineName)
         self.holdingObject = object
         self.holdingObject = object
         for it in self.lazyInitStatements {
         for it in self.lazyInitStatements {
-            context.addLazyStatement(it)
+            let referencedStmt = XCTLReferencedVariableStatement(objectReferenced: object, statement: it)
+            context.addLazyStatement(referencedStmt)
         }
         }
+        context.variableStack.pushVariable(object)
         return object
         return object
     }
     }
     
     

+ 6 - 2
XCTreeLang/Statements/XCTLLazyEqualStatement.swift

@@ -7,7 +7,7 @@
 
 
 import Foundation
 import Foundation
 
 
-internal class XCTLLazyEqualStatement: XCTLStatement {
+internal class XCTLLazyEqualStatement: XCTLStatement, XCTLVariableRequiredLazyStatement {
     
     
     var type: XCTLStatementType { .typeLazyEqual }
     var type: XCTLStatementType { .typeLazyEqual }
     
     
@@ -48,8 +48,12 @@ internal class XCTLLazyEqualStatement: XCTLStatement {
     }
     }
     
     
     func evaluate(inContext context: XCTLRuntimeAbstractContext) throws -> XCTLRuntimeVariable {
     func evaluate(inContext context: XCTLRuntimeAbstractContext) throws -> XCTLRuntimeVariable {
+        throw XCTLRuntimeError.invalidReferencingObject
+    }
+    
+    func evaluate(inContext context: XCTLRuntimeAbstractContext, withVariableReferenced variable: XCTLRuntimeVariable) throws -> XCTLRuntimeVariable {
         let rightValue = try equalToStatement.evaluate(inContext: context)
         let rightValue = try equalToStatement.evaluate(inContext: context)
-        return try self.leftStatement.evaluateBack(rightValue, inContext: context)
+        return try self.leftStatement.evaluateBack(rightValue, inContext: context, withReferencingObject: variable)
     }
     }
     
     
 }
 }

+ 19 - 0
XCTreeLang/Statements/XCTLStatement.swift

@@ -52,6 +52,25 @@ internal protocol XCTLBackableStatement: AnyObject {
     
     
 }
 }
 
 
+internal class XCTLReferencedVariableStatement {
+    
+    internal var objectReferenced: XCTLRuntimeVariable
+    internal var statement: XCTLStatement
+    
+    internal init(objectReferenced: XCTLRuntimeVariable, statement: XCTLStatement) {
+        self.objectReferenced = objectReferenced
+        self.statement = statement
+    }
+    
+}
+
+internal protocol XCTLVariableRequiredLazyStatement {
+    
+    func evaluate(inContext context: XCTLRuntimeAbstractContext,
+                  withVariableReferenced variable: XCTLRuntimeVariable) throws -> XCTLRuntimeVariable
+    
+}
+
 internal class XCTLConditionParentStatementFrame {
 internal class XCTLConditionParentStatementFrame {
     var doElse: Bool
     var doElse: Bool
     var doNext: Bool
     var doNext: Bool

+ 44 - 0
XCTreeLang/Statements/XCTLVariableRefStatement.swift

@@ -143,6 +143,50 @@ internal class XCTLVariableRefStatement: XCTLStatement, XCTLBackableStatement, X
             
             
             let newValue = XCTLRuntimeVariable(rawObject: obj)
             let newValue = XCTLRuntimeVariable(rawObject: obj)
 //            newValue.leftValue = currentValue
 //            newValue.leftValue = currentValue
+//            newValue.leftValueMemberName = memberName
+            currentValue = newValue
+            nextMemberStmt = nextStmt.nextVariableRefStmt
+        }
+        return valueToBack
+    }
+    
+    func evaluateBack(_ valueToBack: XCTLRuntimeVariable,
+                      inContext context: XCTLRuntimeAbstractContext,
+                      withReferencingObject referencing: XCTLRuntimeVariable) throws -> XCTLRuntimeVariable {
+        var nextMemberStmt = self.nextVariableRefStmt
+        var currentValue = referencing
+        var refName = self.variableName
+        
+        if nextMemberStmt == nil {
+            context.setValue(valueToBack, forName: self.variableName)
+        }
+        while let nextStmt = nextMemberStmt {
+            let memberName = nextStmt.variableName
+            refName.append(".")
+            refName.append(memberName)
+            if currentValue.type != .typeObject {
+                throw XCTLRuntimeError.unknownMemberForVariable(memberName: memberName, variableName: refName)
+            }
+            let rawObject = currentValue.objectValue
+            
+            if nextStmt.nextVariableRefStmt == nil {
+                rawObject.setValue(valueToBack.nativeValue, forKey: memberName)
+                break
+            }
+            
+            var obj: Any?
+            let exception = ocTryCatch {
+                obj = rawObject.value(forKey: memberName)
+            }
+            if exception != nil {
+                throw XCTLRuntimeError.unknownMemberForVariable(memberName: memberName, variableName: refName)
+            }
+            guard let obj = obj as? NSObject else {
+                throw XCTLRuntimeError.unknownMemberForVariable(memberName: memberName, variableName: refName)
+            }
+            
+            let newValue = XCTLRuntimeVariable(rawObject: obj)
+//            newValue.leftValue = currentValue
 //            newValue.leftValueMemberName = memberName
 //            newValue.leftValueMemberName = memberName
             currentValue = newValue
             currentValue = newValue
             nextMemberStmt = nextStmt.nextVariableRefStmt
             nextMemberStmt = nextStmt.nextVariableRefStmt

+ 6 - 1
XCTreeLang/XCTLEngine.swift

@@ -115,7 +115,12 @@ public class XCTLEngine: NSObject {
         context.stdout.delegate = ast.stdoutDelegate
         context.stdout.delegate = ast.stdoutDelegate
         _ = try rootStatement.evaluate(inContext: context)
         _ = try rootStatement.evaluate(inContext: context)
         for it in context.lazyRunStatements {
         for it in context.lazyRunStatements {
-            _ = try it.evaluate(inContext: context)
+            let stmt = it.statement
+            if let stmt = stmt as? XCTLVariableRequiredLazyStatement {
+                _ = try stmt.evaluate(inContext: context, withVariableReferenced: it.objectReferenced)
+            } else {
+                _ = try stmt.evaluate(inContext: context)
+            }
         }
         }
     }
     }
     
     

+ 4 - 0
XCTreeLang/XCTLRuntimeError.swift

@@ -33,6 +33,8 @@ public enum XCTLRuntimeError: Error, CustomStringConvertible, CustomNSError {
     case unknownTypeEncoding(name: String)
     case unknownTypeEncoding(name: String)
     case callingTypeEncodingError
     case callingTypeEncodingError
     
     
+    case invalidReferencingObject
+    
     public var description: String {
     public var description: String {
         switch self {
         switch self {
         case .importUnknownMember(variableName: let variableName):
         case .importUnknownMember(variableName: let variableName):
@@ -67,6 +69,8 @@ public enum XCTLRuntimeError: Error, CustomStringConvertible, CustomNSError {
             return "unknownTypeEncoding: \(name)"
             return "unknownTypeEncoding: \(name)"
         case .callingTypeEncodingError:
         case .callingTypeEncodingError:
             return "callingTypeEncodingError"
             return "callingTypeEncodingError"
+        case .invalidReferencingObject:
+            return "invalidReferencingObject"
         }
         }
     }
     }