瀏覽代碼

Add for statement (also break, continue)

xcbosa mbp16 2 年之前
父節點
當前提交
73de639da2

+ 24 - 8
XCTreeLang.xcodeproj/project.pbxproj

@@ -48,8 +48,12 @@
 		7569167A2A283E78005FF14B /* XCTreeLang.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7520C3DA2A283AFC0010E7F8 /* XCTreeLang.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		7569167A2A283E78005FF14B /* XCTreeLang.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7520C3DA2A283AFC0010E7F8 /* XCTreeLang.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		756916872A2851DF005FF14B /* XCTLStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756916862A2851DF005FF14B /* XCTLStream.swift */; };
 		756916872A2851DF005FF14B /* XCTLStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756916862A2851DF005FF14B /* XCTLStream.swift */; };
 		756916892A286A90005FF14B /* XCTLSetStatement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756916882A286A90005FF14B /* XCTLSetStatement.swift */; };
 		756916892A286A90005FF14B /* XCTLSetStatement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756916882A286A90005FF14B /* XCTLSetStatement.swift */; };
-		7569168C2A2880CD005FF14B /* Invocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7569168B2A2880CD005FF14B /* Invocation.swift */; };
 		7569168E2A2896FE005FF14B /* XCTLReturnStatement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7569168D2A2896FE005FF14B /* XCTLReturnStatement.swift */; };
 		7569168E2A2896FE005FF14B /* XCTLReturnStatement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7569168D2A2896FE005FF14B /* XCTLReturnStatement.swift */; };
+		756916912A28C46D005FF14B /* XCTLEnumerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756916902A28C46D005FF14B /* XCTLEnumerator.swift */; };
+		756916932A28C4B6005FF14B /* XCTLRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756916922A28C4B6005FF14B /* XCTLRange.swift */; };
+		756916952A28C622005FF14B /* XCTLForStatement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756916942A28C622005FF14B /* XCTLForStatement.swift */; };
+		756916972A28DFE7005FF14B /* XCTLBreakStatement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756916962A28DFE7005FF14B /* XCTLBreakStatement.swift */; };
+		756916992A28E1D9005FF14B /* XCTLContinueStatement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756916982A28E1D9005FF14B /* XCTLContinueStatement.swift */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
 /* Begin PBXContainerItemProxy section */
 /* Begin PBXContainerItemProxy section */
@@ -122,8 +126,12 @@
 		7520C4572A283CCC0010E7F8 /* TestApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TestApp.entitlements; sourceTree = "<group>"; };
 		7520C4572A283CCC0010E7F8 /* TestApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TestApp.entitlements; sourceTree = "<group>"; };
 		756916862A2851DF005FF14B /* XCTLStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLStream.swift; sourceTree = "<group>"; };
 		756916862A2851DF005FF14B /* XCTLStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLStream.swift; sourceTree = "<group>"; };
 		756916882A286A90005FF14B /* XCTLSetStatement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLSetStatement.swift; sourceTree = "<group>"; };
 		756916882A286A90005FF14B /* XCTLSetStatement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLSetStatement.swift; sourceTree = "<group>"; };
-		7569168B2A2880CD005FF14B /* Invocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Invocation.swift; sourceTree = "<group>"; };
 		7569168D2A2896FE005FF14B /* XCTLReturnStatement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLReturnStatement.swift; sourceTree = "<group>"; };
 		7569168D2A2896FE005FF14B /* XCTLReturnStatement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLReturnStatement.swift; sourceTree = "<group>"; };
+		756916902A28C46D005FF14B /* XCTLEnumerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLEnumerator.swift; sourceTree = "<group>"; };
+		756916922A28C4B6005FF14B /* XCTLRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLRange.swift; sourceTree = "<group>"; };
+		756916942A28C622005FF14B /* XCTLForStatement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLForStatement.swift; sourceTree = "<group>"; };
+		756916962A28DFE7005FF14B /* XCTLBreakStatement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLBreakStatement.swift; sourceTree = "<group>"; };
+		756916982A28E1D9005FF14B /* XCTLContinueStatement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTLContinueStatement.swift; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
 
 
 /* Begin PBXFrameworksBuildPhase section */
 /* Begin PBXFrameworksBuildPhase section */
@@ -167,16 +175,16 @@
 		7520C3DC2A283AFC0010E7F8 /* XCTreeLang */ = {
 		7520C3DC2A283AFC0010E7F8 /* XCTreeLang */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				7569168A2A2880C4005FF14B /* Utils */,
+				7569168F2A28C447005FF14B /* NativeTypes */,
 				7520C3DD2A283AFC0010E7F8 /* XCTreeLang.h */,
 				7520C3DD2A283AFC0010E7F8 /* XCTreeLang.h */,
 				7520C4172A283B1E0010E7F8 /* InitializerImpl */,
 				7520C4172A283B1E0010E7F8 /* InitializerImpl */,
 				7520C3F32A283B1E0010E7F8 /* Lex */,
 				7520C3F32A283B1E0010E7F8 /* Lex */,
 				7520C40D2A283B1E0010E7F8 /* Runtime */,
 				7520C40D2A283B1E0010E7F8 /* Runtime */,
 				7520C3F72A283B1E0010E7F8 /* Statements */,
 				7520C3F72A283B1E0010E7F8 /* Statements */,
 				7520C3F22A283B1E0010E7F8 /* XCTLCompileTimeError.swift */,
 				7520C3F22A283B1E0010E7F8 /* XCTLCompileTimeError.swift */,
+				7520C40C2A283B1E0010E7F8 /* XCTLRuntimeError.swift */,
 				7520C4162A283B1E0010E7F8 /* XCTLEngine.swift */,
 				7520C4162A283B1E0010E7F8 /* XCTLEngine.swift */,
 				7520C40B2A283B1E0010E7F8 /* XCTLGenerateProtocol.swift */,
 				7520C40B2A283B1E0010E7F8 /* XCTLGenerateProtocol.swift */,
-				7520C40C2A283B1E0010E7F8 /* XCTLRuntimeError.swift */,
 			);
 			);
 			path = XCTreeLang;
 			path = XCTreeLang;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -214,6 +222,9 @@
 				7520C40A2A283B1E0010E7F8 /* XCTLVariableRefStatement.swift */,
 				7520C40A2A283B1E0010E7F8 /* XCTLVariableRefStatement.swift */,
 				756916882A286A90005FF14B /* XCTLSetStatement.swift */,
 				756916882A286A90005FF14B /* XCTLSetStatement.swift */,
 				7569168D2A2896FE005FF14B /* XCTLReturnStatement.swift */,
 				7569168D2A2896FE005FF14B /* XCTLReturnStatement.swift */,
+				756916942A28C622005FF14B /* XCTLForStatement.swift */,
+				756916962A28DFE7005FF14B /* XCTLBreakStatement.swift */,
+				756916982A28E1D9005FF14B /* XCTLContinueStatement.swift */,
 			);
 			);
 			path = Statements;
 			path = Statements;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -270,12 +281,13 @@
 			name = Frameworks;
 			name = Frameworks;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
-		7569168A2A2880C4005FF14B /* Utils */ = {
+		7569168F2A28C447005FF14B /* NativeTypes */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				7569168B2A2880CD005FF14B /* Invocation.swift */,
+				756916902A28C46D005FF14B /* XCTLEnumerator.swift */,
+				756916922A28C4B6005FF14B /* XCTLRange.swift */,
 			);
 			);
-			path = Utils;
+			path = NativeTypes;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
 /* End PBXGroup section */
 /* End PBXGroup section */
@@ -392,7 +404,6 @@
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
 				7520C42B2A283B1E0010E7F8 /* XCTLElseStatement.swift in Sources */,
 				7520C42B2A283B1E0010E7F8 /* XCTLElseStatement.swift in Sources */,
-				7569168C2A2880CD005FF14B /* Invocation.swift in Sources */,
 				7520C4212A283B1E0010E7F8 /* XCTLNextthanStatement.swift in Sources */,
 				7520C4212A283B1E0010E7F8 /* XCTLNextthanStatement.swift in Sources */,
 				7520C4342A283B1E0010E7F8 /* XCTLRuntimeAbstractContext.swift in Sources */,
 				7520C4342A283B1E0010E7F8 /* XCTLRuntimeAbstractContext.swift in Sources */,
 				7520C4352A283B1E0010E7F8 /* XCTLRuntimeContext.swift in Sources */,
 				7520C4352A283B1E0010E7F8 /* XCTLRuntimeContext.swift in Sources */,
@@ -400,6 +411,7 @@
 				7520C41B2A283B1E0010E7F8 /* XCTLTokenType.swift in Sources */,
 				7520C41B2A283B1E0010E7F8 /* XCTLTokenType.swift in Sources */,
 				7520C4322A283B1E0010E7F8 /* XCTLRuntimeSubContext.swift in Sources */,
 				7520C4322A283B1E0010E7F8 /* XCTLRuntimeSubContext.swift in Sources */,
 				7520C42F2A283B1E0010E7F8 /* XCTLGenerateProtocol.swift in Sources */,
 				7520C42F2A283B1E0010E7F8 /* XCTLGenerateProtocol.swift in Sources */,
+				756916952A28C622005FF14B /* XCTLForStatement.swift in Sources */,
 				7520C41C2A283B1E0010E7F8 /* XCTLLexer.swift in Sources */,
 				7520C41C2A283B1E0010E7F8 /* XCTLLexer.swift in Sources */,
 				7520C41D2A283B1E0010E7F8 /* XCTLImportStatement.swift in Sources */,
 				7520C41D2A283B1E0010E7F8 /* XCTLImportStatement.swift in Sources */,
 				7520C41F2A283B1E0010E7F8 /* XCTLLazyEqualStatement.swift in Sources */,
 				7520C41F2A283B1E0010E7F8 /* XCTLLazyEqualStatement.swift in Sources */,
@@ -408,15 +420,19 @@
 				7520C4302A283B1E0010E7F8 /* XCTLRuntimeError.swift in Sources */,
 				7520C4302A283B1E0010E7F8 /* XCTLRuntimeError.swift in Sources */,
 				7520C41A2A283B1E0010E7F8 /* XCTLToken.swift in Sources */,
 				7520C41A2A283B1E0010E7F8 /* XCTLToken.swift in Sources */,
 				7520C42E2A283B1E0010E7F8 /* XCTLVariableRefStatement.swift in Sources */,
 				7520C42E2A283B1E0010E7F8 /* XCTLVariableRefStatement.swift in Sources */,
+				756916992A28E1D9005FF14B /* XCTLContinueStatement.swift in Sources */,
 				7520C42D2A283B1E0010E7F8 /* XCTLListStatement.swift in Sources */,
 				7520C42D2A283B1E0010E7F8 /* XCTLListStatement.swift in Sources */,
 				7520C4222A283B1E0010E7F8 /* XCTLInitStatement.swift in Sources */,
 				7520C4222A283B1E0010E7F8 /* XCTLInitStatement.swift in Sources */,
 				756916872A2851DF005FF14B /* XCTLStream.swift in Sources */,
 				756916872A2851DF005FF14B /* XCTLStream.swift in Sources */,
 				7520C41E2A283B1E0010E7F8 /* XCTLImmediateStatement.swift in Sources */,
 				7520C41E2A283B1E0010E7F8 /* XCTLImmediateStatement.swift in Sources */,
 				756916892A286A90005FF14B /* XCTLSetStatement.swift in Sources */,
 				756916892A286A90005FF14B /* XCTLSetStatement.swift in Sources */,
+				756916972A28DFE7005FF14B /* XCTLBreakStatement.swift in Sources */,
 				7520C4312A283B1E0010E7F8 /* XCTLRuntimeVariable.swift in Sources */,
 				7520C4312A283B1E0010E7F8 /* XCTLRuntimeVariable.swift in Sources */,
+				756916912A28C46D005FF14B /* XCTLEnumerator.swift in Sources */,
 				7520C42C2A283B1E0010E7F8 /* XCTLLessthanStatement.swift in Sources */,
 				7520C42C2A283B1E0010E7F8 /* XCTLLessthanStatement.swift in Sources */,
 				7520C4332A283B1E0010E7F8 /* XCTLRuntimeVariableType.swift in Sources */,
 				7520C4332A283B1E0010E7F8 /* XCTLRuntimeVariableType.swift in Sources */,
 				7520C4202A283B1E0010E7F8 /* XCTLRootStatement.swift in Sources */,
 				7520C4202A283B1E0010E7F8 /* XCTLRootStatement.swift in Sources */,
+				756916932A28C4B6005FF14B /* XCTLRange.swift in Sources */,
 				7520C42A2A283B1E0010E7F8 /* XCTLMorethanStatement.swift in Sources */,
 				7520C42A2A283B1E0010E7F8 /* XCTLMorethanStatement.swift in Sources */,
 				7520C4292A283B1E0010E7F8 /* XCTLEqualthanStatement.swift in Sources */,
 				7520C4292A283B1E0010E7F8 /* XCTLEqualthanStatement.swift in Sources */,
 				7569168E2A2896FE005FF14B /* XCTLReturnStatement.swift in Sources */,
 				7569168E2A2896FE005FF14B /* XCTLReturnStatement.swift in Sources */,

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

@@ -84,5 +84,165 @@
             landmarkType = "7">
             landmarkType = "7">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "F9CC256C-1B93-464D-9004-6BB6EE749095"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLNextthanStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "37"
+            endingLineNumber = "37"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "A7C12A73-E896-4CFC-8D9B-063BEDC41511"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLNextthanStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "40"
+            endingLineNumber = "40"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "20B938DB-244D-4B20-ACBD-5D1F98A9EBE2"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLParagraphStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "67"
+            endingLineNumber = "67"
+            landmarkName = "doRealEvaluate(inContext:withArgs:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "1157454B-7DC1-435C-810F-6DAF5F2B563C"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLEqualthanStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "59"
+            endingLineNumber = "59"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "B991C77B-91F4-4A57-AC7E-D5C29D505801"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLMorethanStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "47"
+            endingLineNumber = "47"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "DE99138A-2D5F-4CC4-A11F-FAD9B843566D"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLMorethanStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "51"
+            endingLineNumber = "51"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "4D995B8D-8DF5-4246-B928-809413B74EE8"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLMorethanStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "60"
+            endingLineNumber = "60"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "587D9FDF-0913-4C57-A5C2-CACC492FAA36"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLMorethanStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "63"
+            endingLineNumber = "63"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "BFE888DF-761B-43C6-8561-25412C711F3F"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLLessthanStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "60"
+            endingLineNumber = "60"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "E6E67FFE-B566-47BA-8D1F-AAE8337CB438"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "XCTreeLang/Statements/XCTLLessthanStatement.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "63"
+            endingLineNumber = "63"
+            landmarkName = "evaluate(inContext:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
    </Breakpoints>
 </Bucket>
 </Bucket>

+ 8 - 0
XCTreeLang/Lex/XCTLLexer.swift

@@ -80,6 +80,14 @@ internal class XCTLLexer {
                 return XCTLToken(type: .typeElse, rawValue: buffer)
                 return XCTLToken(type: .typeElse, rawValue: buffer)
             case "return":
             case "return":
                 return XCTLToken(type: .typeReturn, rawValue: buffer)
                 return XCTLToken(type: .typeReturn, rawValue: buffer)
+            case "for":
+                return XCTLToken(type: .typeFor, rawValue: buffer)
+            case "in":
+                return XCTLToken(type: .typeIn, rawValue: buffer)
+            case "break":
+                return XCTLToken(type: .typeBreak, rawValue: buffer)
+            case "continue":
+                return XCTLToken(type: .typeContinue, rawValue: buffer)
             default:
             default:
                 return XCTLToken(type: .typeIdentifier, rawValue: buffer)
                 return XCTLToken(type: .typeIdentifier, rawValue: buffer)
             }
             }

+ 5 - 0
XCTreeLang/Lex/XCTLTokenType.swift

@@ -50,4 +50,9 @@ internal enum XCTLTokenType: String {
     /// return
     /// return
     case typeReturn
     case typeReturn
     
     
+    case typeFor
+    case typeIn
+    case typeBreak
+    case typeContinue
+    
 }
 }

+ 14 - 0
XCTreeLang/NativeTypes/XCTLEnumerator.swift

@@ -0,0 +1,14 @@
+//
+//  XCTLEnumerator.swift
+//  XCTreeLang
+//
+//  Created by 邢铖 on 2023/6/1.
+//
+
+import Foundation
+
+public protocol XCTLEnumerator {
+    
+    func moveNext() -> XCTLRuntimeVariable
+    
+}

+ 33 - 0
XCTreeLang/NativeTypes/XCTLRange.swift

@@ -0,0 +1,33 @@
+//
+//  XCTLRange.swift
+//  XCTreeLang
+//
+//  Created by 邢铖 on 2023/6/1.
+//
+
+import Foundation
+
+public class XCTLRange: NSObject, XCTLEnumerator {
+    
+    public var begin: Double
+    public var length: Double
+    public var step: Double
+    public var current: Double
+    
+    public init(begin: Double, length: Double, step: Double) {
+        self.begin = begin
+        self.length = length
+        self.step = step
+        self.current = begin
+    }
+    
+    public func moveNext() -> XCTLRuntimeVariable {
+        let value = self.current
+        if value >= begin + length {
+            return .void
+        }
+        self.current += step
+        return XCTLRuntimeVariable(type: .typeNumber, rawValue: value.description)
+    }
+    
+}

+ 2 - 0
XCTreeLang/Runtime/XCTLRuntimeAbstractContext.swift

@@ -27,8 +27,10 @@ internal protocol XCTLRuntimeAbstractContext: AnyObject {
     
     
     func findConditionFrame() -> XCTLConditionParentStatementFrame?
     func findConditionFrame() -> XCTLConditionParentStatementFrame?
     func findListFrame() -> XCTLListStatementFrame?
     func findListFrame() -> XCTLListStatementFrame?
+    func findForFrame() -> XCTLForStatementFrame?
     func recordConditionFrame(_ frame: XCTLConditionParentStatementFrame?)
     func recordConditionFrame(_ frame: XCTLConditionParentStatementFrame?)
     func recordListFrame(_ frame: XCTLListStatementFrame?)
     func recordListFrame(_ frame: XCTLListStatementFrame?)
+    func recordForFrame(_ frame: XCTLForStatementFrame?)
     
     
     func getParentContext() -> XCTLRuntimeAbstractContext?
     func getParentContext() -> XCTLRuntimeAbstractContext?
     
     

+ 29 - 1
XCTreeLang/Runtime/XCTLRuntimeContext.swift

@@ -92,7 +92,7 @@ internal class XCTLRuntimeContext: XCTLRuntimeAbstractContext {
             return XCTLRuntimeVariable(type: .typeNumber, rawValue: dest.description)
             return XCTLRuntimeVariable(type: .typeNumber, rawValue: dest.description)
         }), forName: "minus")
         }), forName: "minus")
         self.setValue(XCTLRuntimeVariable(funcImpl: {
         self.setValue(XCTLRuntimeVariable(funcImpl: {
-            var dest: Double = 0
+            var dest: Double = 1
             for it in $0 {
             for it in $0 {
                 if it.type == .typeNumber {
                 if it.type == .typeNumber {
                     dest *= it.doubleValue
                     dest *= it.doubleValue
@@ -112,6 +112,25 @@ internal class XCTLRuntimeContext: XCTLRuntimeAbstractContext {
             }
             }
             return XCTLRuntimeVariable(type: .typeNumber, rawValue: dest.description)
             return XCTLRuntimeVariable(type: .typeNumber, rawValue: dest.description)
         }), forName: "div")
         }), forName: "div")
+        self.setValue(XCTLRuntimeVariable(funcImpl: {
+            var begin: Double = 0
+            var length: Double = 0
+            var step: Double = 1
+            let args = $0.filter({ $0.type == .typeNumber }).map({ $0.doubleValue })
+            if args.count == 1 {
+                length = args[0]
+            }
+            if args.count == 2 {
+                begin = args[0]
+                length = args[1]
+            }
+            if args.count == 3 {
+                begin = args[0]
+                length = args[1]
+                step = args[2]
+            }
+            return XCTLRuntimeVariable(rawObject: XCTLRange(begin: begin, length: length, step: step))
+        }), forName: "range")
         self.setValue(XCTLRuntimeVariable(type: .typeNumber, rawValue: "\(Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "-1")"), forName: "appBundleVersion")
         self.setValue(XCTLRuntimeVariable(type: .typeNumber, rawValue: "\(Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "-1")"), forName: "appBundleVersion")
         for it in paragraphMembers {
         for it in paragraphMembers {
             self.setValue(XCTLRuntimeVariable(funcImplStmt: it.value), forName: it.key)
             self.setValue(XCTLRuntimeVariable(funcImplStmt: it.value), forName: it.key)
@@ -194,6 +213,7 @@ internal class XCTLRuntimeContext: XCTLRuntimeAbstractContext {
     
     
     private var conditionFrame: XCTLConditionParentStatementFrame?
     private var conditionFrame: XCTLConditionParentStatementFrame?
     private var listFrame: XCTLListStatementFrame?
     private var listFrame: XCTLListStatementFrame?
+    private var forFrame: XCTLForStatementFrame?
     
     
     func findConditionFrame() -> XCTLConditionParentStatementFrame? {
     func findConditionFrame() -> XCTLConditionParentStatementFrame? {
         return self.conditionFrame
         return self.conditionFrame
@@ -211,6 +231,14 @@ internal class XCTLRuntimeContext: XCTLRuntimeAbstractContext {
         self.conditionFrame = frame
         self.conditionFrame = frame
     }
     }
     
     
+    func findForFrame() -> XCTLForStatementFrame? {
+        return self.forFrame
+    }
+    
+    func recordForFrame(_ frame: XCTLForStatementFrame?) {
+        self.forFrame = frame
+    }
+    
     func getParentContext() -> XCTLRuntimeAbstractContext? {
     func getParentContext() -> XCTLRuntimeAbstractContext? {
         return nil
         return nil
     }
     }

+ 12 - 0
XCTreeLang/Runtime/XCTLRuntimeSubContext.swift

@@ -94,6 +94,7 @@ internal class XCTLRuntimeSubContext: XCTLRuntimeAbstractContext {
     
     
     private var conditionFrame: XCTLConditionParentStatementFrame?
     private var conditionFrame: XCTLConditionParentStatementFrame?
     private var listFrame: XCTLListStatementFrame?
     private var listFrame: XCTLListStatementFrame?
+    private var forFrame: XCTLForStatementFrame?
     
     
     func findConditionFrame() -> XCTLConditionParentStatementFrame? {
     func findConditionFrame() -> XCTLConditionParentStatementFrame? {
         if let conditionFrame = self.conditionFrame {
         if let conditionFrame = self.conditionFrame {
@@ -121,4 +122,15 @@ internal class XCTLRuntimeSubContext: XCTLRuntimeAbstractContext {
         return self.parent
         return self.parent
     }
     }
     
     
+    func findForFrame() -> XCTLForStatementFrame? {
+        if let forFrame = self.forFrame {
+            return forFrame
+        }
+        return self.parent.findForFrame()
+    }
+    
+    func recordForFrame(_ frame: XCTLForStatementFrame?) {
+        self.forFrame = frame
+    }
+    
 }
 }

+ 1 - 0
XCTreeLang/Statements/VirtualStatement/XCTLListStatement.swift

@@ -68,6 +68,7 @@ internal class XCTLListStatement: XCTLStatement, XCTLListStatementProtocol {
                             throw XCTLRuntimeError.invalidListFrame
                             throw XCTLRuntimeError.invalidListFrame
                         }
                         }
                         lastListFrame.breakListEvaluate = true
                         lastListFrame.breakListEvaluate = true
+//                        lastListFrame.breakToParagraph = true
                         lastListFrame.listResultValue = frame.listResultValue
                         lastListFrame.listResultValue = frame.listResultValue
                     }
                     }
                 }
                 }

+ 51 - 0
XCTreeLang/Statements/XCTLBreakStatement.swift

@@ -0,0 +1,51 @@
+//
+//  XCTLBreakStatement.swift
+//  XCTreeLang
+//
+//  Created by 邢铖 on 2023/6/1.
+//
+
+import Foundation
+
+internal class XCTLBreakStatement: XCTLStatement {
+    
+    var type: XCTLStatementType { .typeBreak }
+    
+    var holdingObject: XCTLRuntimeVariable { .void }
+    
+    var parent: XCTLStatement?
+    
+    func matchSelfStatement(lex: XCTLLexer) throws -> XCTLStatement? {
+        if try lex.next().type == .typeBreak {
+            return XCTLBreakStatement()
+        }
+        return nil
+    }
+    
+    func parseStatement(fromLexerToSelf lex: XCTLLexer, fromParent: XCTLStatement?) throws {
+        self.parent = fromParent
+        var parentStmt = self.parent
+        var founded = false
+        while let stmt = parentStmt {
+            if stmt is XCTLForStatement {
+                founded = true
+            }
+            if stmt is XCTLParagraphStatement {
+                break
+            }
+            parentStmt = stmt.parent
+        }
+        if !founded {
+            throw XCTLCompileTimeError.unexpectParentStatementType(expect: "for", butGot: "...")
+        }
+        try _ = lex.next()
+    }
+    
+    func evaluate(inContext context: XCTLRuntimeAbstractContext) throws -> XCTLRuntimeVariable {
+        if let forFrame = context.findForFrame() {
+            forFrame.breakForEvaluate = true
+        }
+        return .void
+    }
+    
+}

+ 52 - 0
XCTreeLang/Statements/XCTLContinueStatement.swift

@@ -0,0 +1,52 @@
+//
+//  XCTLContinueStatement.swift
+//  XCTreeLang
+//
+//  Created by 邢铖 on 2023/6/1.
+//
+
+import Foundation
+
+internal class XCTLContinueStatement: XCTLStatement {
+    
+    var type: XCTLStatementType { .typeContinue }
+    
+    var holdingObject: XCTLRuntimeVariable { .void }
+    
+    var parent: XCTLStatement?
+    
+    func matchSelfStatement(lex: XCTLLexer) throws -> XCTLStatement? {
+        if try lex.next().type == .typeContinue {
+            return XCTLContinueStatement()
+        }
+        return nil
+    }
+    
+    func parseStatement(fromLexerToSelf lex: XCTLLexer, fromParent: XCTLStatement?) throws {
+        self.parent = fromParent
+        var parentStmt = self.parent
+        var founded = false
+        while let stmt = parentStmt {
+            if stmt is XCTLForStatement {
+                founded = true
+            }
+            if stmt is XCTLParagraphStatement {
+                break
+            }
+            parentStmt = stmt.parent
+        }
+        if !founded {
+            throw XCTLCompileTimeError.unexpectParentStatementType(expect: "for", butGot: "...")
+        }
+        try _ = lex.next()
+    }
+    
+    func evaluate(inContext context: XCTLRuntimeAbstractContext) throws -> XCTLRuntimeVariable {
+        if let listFrame = context.findListFrame() {
+            listFrame.breakListEvaluate = true
+            listFrame.breakToParagraph = false
+        }
+        return .void
+    }
+    
+}

+ 83 - 0
XCTreeLang/Statements/XCTLForStatement.swift

@@ -0,0 +1,83 @@
+//
+//  XCTLForStatement.swift
+//  XCTreeLang
+//
+//  Created by 邢铖 on 2023/6/1.
+//
+
+import Foundation
+
+public class XCTLForStatement: XCTLStatement {
+    
+    var type: XCTLStatementType { .typeFor }
+    
+    var holdingObject: XCTLRuntimeVariable { .void }
+    
+    var parent: XCTLStatement?
+    
+    var iteratorName: String = ""
+    
+    var enumeratorVariableStatement: XCTLStatement!
+    
+    var listStatement = XCTLListStatement()
+    
+    func matchSelfStatement(lex: XCTLLexer) throws -> XCTLStatement? {
+        if try lex.next().type == .typeFor {
+            return XCTLForStatement()
+        }
+        return nil
+    }
+    
+    func parseStatement(fromLexerToSelf lex: XCTLLexer, fromParent: XCTLStatement?) throws {
+        self.parent = fromParent
+        try lex.next()
+        
+        let iteratorNameToken = try lex.next()
+        if iteratorNameToken.type != .typeIdentifier {
+            throw XCTLCompileTimeError.unexpectTokenInStatement(expect: XCTLTokenType.typeIdentifier.rawValue, butGot: iteratorNameToken.rawValue)
+        }
+        self.iteratorName = iteratorNameToken.rawValue
+        
+        let inToken = try lex.next()
+        if inToken.type != .typeIn {
+            throw XCTLCompileTimeError.unexpectTokenInStatement(expect: XCTLTokenType.typeIn.rawValue, butGot: inToken.rawValue)
+        }
+        
+        self.enumeratorVariableStatement = try self.parseNextStatement(forLexer: lex, prototypes: XCTLExpressionPrototypes)
+        
+        try self.listStatement.parseStatement(fromLexerToSelf: lex, fromParent: self)
+    }
+    
+    func evaluate(inContext context: XCTLRuntimeAbstractContext) throws -> XCTLRuntimeVariable {
+        let enumeratorVariable = try self.enumeratorVariableStatement.evaluate(inContext: context)
+        if enumeratorVariable.type != .typeObject {
+            throw XCTLRuntimeError.unexpectedVariableType(expect: XCTLRuntimeVariableType.typeObject.rawValue, butGot: enumeratorVariable.type.rawValue)
+        }
+        guard let enumerator = enumeratorVariable.objectValue as? XCTLEnumerator else {
+            throw XCTLRuntimeError.variableNotImplementProtocol(protocolName: "XCTLEnumerator")
+        }
+        
+        let context = context.makeSubContext()
+        let listFrame = context.findListFrame()
+        let forFrame = XCTLForStatementFrame()
+        context.recordForFrame(forFrame)
+        while true {
+            let value = enumerator.moveNext()
+            if value.type == .typeVoid {
+                break
+            }
+            context.setValueIgnoreParent(value, forName: self.iteratorName)
+            _ = try self.listStatement.evaluate(inContext: context)
+            if forFrame.breakForEvaluate {
+                break
+            }
+            if let listFrame = listFrame,
+               listFrame.breakListEvaluate {
+                break
+            }
+        }
+        
+        return .void
+    }
+    
+}

+ 16 - 9
XCTreeLang/Statements/XCTLStatement.swift

@@ -29,10 +29,6 @@ internal protocol XCTLStatement: AnyObject {
 
 
 internal protocol XCTLListStatementProtocol: AnyObject {
 internal protocol XCTLListStatementProtocol: AnyObject {
     
     
-//    var breakListEvaluate: Bool { get set }
-//
-//    var listResultValue: XCTLRuntimeVariable { get set }
-//
     var conditionParent: XCTLConditionParentStatement? { get }
     var conditionParent: XCTLConditionParentStatement? { get }
     
     
     var paragraphHold: Bool { get set }
     var paragraphHold: Bool { get set }
@@ -41,10 +37,6 @@ internal protocol XCTLListStatementProtocol: AnyObject {
 
 
 internal protocol XCTLConditionParentStatement: AnyObject {
 internal protocol XCTLConditionParentStatement: AnyObject {
     
     
-//    var doElse: Bool { get set }
-//    
-//    var doNext: Bool { get set }
-    
 }
 }
 
 
 internal protocol XCTLLateExecuteStatement: AnyObject {
 internal protocol XCTLLateExecuteStatement: AnyObject {
@@ -93,6 +85,18 @@ internal class XCTLListStatementFrame {
     }
     }
 }
 }
 
 
+internal class XCTLForStatementFrame {
+    var breakForEvaluate: Bool
+    
+    internal init() {
+        self.breakForEvaluate = false
+    }
+    
+    internal init(breakForEvaluate: Bool) {
+        self.breakForEvaluate = breakForEvaluate
+    }
+}
+
 internal var XCTLStatementPrototypes: [XCTLStatement] = [
 internal var XCTLStatementPrototypes: [XCTLStatement] = [
     XCTLImportStatement(),
     XCTLImportStatement(),
     XCTLExportStatement(),
     XCTLExportStatement(),
@@ -109,7 +113,10 @@ internal var XCTLStatementPrototypes: [XCTLStatement] = [
     XCTLElseStatement(),
     XCTLElseStatement(),
     XCTLParagraphStatement(),
     XCTLParagraphStatement(),
     XCTLSetStatement(),
     XCTLSetStatement(),
-    XCTLReturnStatement()
+    XCTLReturnStatement(),
+    XCTLForStatement(),
+    XCTLBreakStatement(),
+    XCTLContinueStatement()
 ]
 ]
 
 
 internal var XCTLExpressionPrototypes: [XCTLStatement] = [
 internal var XCTLExpressionPrototypes: [XCTLStatement] = [

+ 4 - 0
XCTreeLang/Statements/XCTLStatementType.swift

@@ -41,4 +41,8 @@ internal enum XCTLStatementType: String {
     case typeSet
     case typeSet
     case typeReturn
     case typeReturn
     
     
+    case typeFor
+    case typeBreak
+    case typeContinue
+    
 }
 }

+ 0 - 214
XCTreeLang/Utils/Invocation.swift

@@ -1,214 +0,0 @@
-//
-//  Dynamic
-//  Created by Mhd Hejazi on 4/15/20.
-//  Copyright © 2020 Samabox. All rights reserved.
-//
-
-import Foundation
-
-class Invocation: NSObject {
-
-    private let target: NSObject
-    private let selector: Selector
-
-    var invocation: NSObject?
-
-    var numberOfArguments: Int = 0
-    var returnLength: Int = 0
-    var returnType: UnsafePointer<CChar>?
-    var returnTypeString: String? {
-        guard let returnType = returnType else { return nil }
-        return String(cString: returnType)
-    }
-    var returnsObject: Bool {
-        /// `@` is the type encoding for an object
-        returnTypeString == "@"
-    }
-    var returnsAny: Bool {
-        /// `v` is the type encoding for Void
-        returnTypeString != "v"
-    }
-    lazy var returnedObject: AnyObject? = {
-        returnedObjectValue()
-    }()
-    private(set) var isInvoked: Bool = false
-
-    init(target: NSObject, selector: Selector) throws {
-        self.target = target
-        self.selector = selector
-        super.init()
-
-        try initialize()
-    }
-
-    private func initialize() throws {
-        /// `NSMethodSignature *methodSignature = [target methodSignatureForSelector: selector]`
-        let methodSignature: NSObject
-        do {
-            let selector = NSSelectorFromString("methodSignatureForSelector:")
-            let signature = (@convention(c)(NSObject, Selector, Selector) -> Any).self
-            let method = unsafeBitCast(target.method(for: selector), to: signature)
-            guard let result = method(target, selector, self.selector) as? NSObject else {
-                let error = InvocationError.unrecognizedSelector(type(of: target), self.selector)
-                throw error
-            }
-            methodSignature = result
-        }
-
-        /// `numberOfArguments = methodSignature.numberOfArguments`
-        self.numberOfArguments = methodSignature.value(forKeyPath: "numberOfArguments") as? Int ?? 0
-
-        /// `methodReturnLength = methodSignature.methodReturnLength`
-        self.returnLength = methodSignature.value(forKeyPath: "methodReturnLength") as? Int ?? 0
-
-        /// `methodReturnType = methodSignature.methodReturnType`
-        let methodReturnType: UnsafePointer<CChar>
-        do {
-            let selector = NSSelectorFromString("methodReturnType")
-            let signature = (@convention(c)(NSObject, Selector) -> UnsafePointer<CChar>).self
-            let method = unsafeBitCast(methodSignature.method(for: selector), to: signature)
-            methodReturnType = method(methodSignature, selector)
-        }
-        self.returnType = methodReturnType
-
-        /// `NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: methodSignature]`
-        let invocation: NSObject
-        do {
-            let NSInvocation = NSClassFromString("NSInvocation") as AnyObject
-            let selector = NSSelectorFromString("invocationWithMethodSignature:")
-            let signature = (@convention(c)(AnyObject, Selector, AnyObject) -> AnyObject).self
-            let method = unsafeBitCast(NSInvocation.method(for: selector), to: signature)
-            guard let result = method(NSInvocation, selector, methodSignature) as? NSObject else {
-                let error = InvocationError.unrecognizedSelector(type(of: target), self.selector)
-                throw error
-            }
-            invocation = result
-        }
-        self.invocation = invocation
-
-        /// `invocation.selector = selector`
-        do {
-            let selector = NSSelectorFromString("setSelector:")
-            let signature = (@convention(c)(NSObject, Selector, Selector) -> Void).self
-            let method = unsafeBitCast(invocation.method(for: selector), to: signature)
-            method(invocation, selector, self.selector)
-        }
-
-        /// `[invocation retainArguments]`
-        do {
-            let selector = NSSelectorFromString("retainArguments")
-            let signature = (@convention(c)(NSObject, Selector) -> Void).self
-            let method = unsafeBitCast(invocation.method(for: selector), to: signature)
-            method(invocation, selector)
-        }
-    }
-
-    func setArgument(_ argument: Any?, at index: NSInteger) {
-        guard let invocation = invocation else { return }
-
-        /// `[invocation setArgument:&argument atIndex:i + 2]`
-        let selector = NSSelectorFromString("setArgument:atIndex:")
-        let signature = (@convention(c)(NSObject, Selector, UnsafeRawPointer, Int) -> Void).self
-        let method = unsafeBitCast(invocation.method(for: selector), to: signature)
-
-        if let valueArgument = argument as? NSValue {
-            /// Get the type byte size
-            let typeSize = UnsafeMutablePointer<Int>.allocate(capacity: 1)
-            defer { typeSize.deallocate() }
-            NSGetSizeAndAlignment(valueArgument.objCType, typeSize, nil)
-
-            /// Get the actual value
-            let buffer = UnsafeMutablePointer<Int8>.allocate(capacity: typeSize.pointee)
-            defer { buffer.deallocate() }
-            valueArgument.getValue(buffer)
-
-            method(invocation, selector, buffer, index)
-        } else {
-            withUnsafePointer(to: argument) { pointer in
-                method(invocation, selector, pointer, index)
-            }
-        }
-    }
-
-    func invoke() {
-        guard let invocation = invocation, !isInvoked else { return }
-
-        isInvoked = true
-
-        /// `[invocation invokeWithTarget: target]`
-        do {
-            let selector = NSSelectorFromString("invokeWithTarget:")
-            let signature = (@convention(c)(NSObject, Selector, AnyObject) -> Void).self
-            let method = unsafeBitCast(invocation.method(for: selector), to: signature)
-            method(invocation, selector, target)
-        }
-    }
-
-    func getReturnValue<T>(result: inout T) {
-        guard let invocation = invocation else { return }
-
-        /// `[invocation getReturnValue: returnValue]`
-        do {
-            let selector = NSSelectorFromString("getReturnValue:")
-            let signature = (@convention(c)(NSObject, Selector, UnsafeMutableRawPointer) -> Void).self
-            let method = unsafeBitCast(invocation.method(for: selector), to: signature)
-            withUnsafeMutablePointer(to: &result) { pointer in
-                method(invocation, selector, pointer)
-            }
-        }
-    }
-
-    private func returnedObjectValue() -> AnyObject? {
-        guard returnsObject, returnLength > 0 else {
-            return nil
-        }
-
-        var result: AnyObject?
-
-        getReturnValue(result: &result)
-
-        guard let object = result else {
-            return nil
-        }
-
-        /// Take the ownership of the initialized objects to ensure they're deallocated properly.
-        if isRetainingMethod() {
-            return Unmanaged.passRetained(object).takeRetainedValue()
-        }
-
-        /// `NSInvocation.getReturnValue()` doesn't give us the ownership of the returned object, but the compiler
-        /// tries to release this object anyway. So, we are retaining it to balance with the compiler's release.
-        return Unmanaged.passRetained(object).takeUnretainedValue()
-    }
-
-    private func isRetainingMethod() -> Bool {
-        /// Refer to: https://bit.ly/308okXm
-        let selector = NSStringFromSelector(self.selector)
-        return selector == "alloc" ||
-            selector.hasPrefix("new") ||
-            selector.hasPrefix("copy") ||
-            selector.hasPrefix("mutableCopy")
-    }
-}
-
-public enum InvocationError: CustomNSError {
-    case unrecognizedSelector(_ classType: AnyClass, _ selector: Selector)
-
-    public static var errorDomain: String { String(describing: Invocation.self) }
-
-    public var errorCode: Int {
-        switch self {
-        case .unrecognizedSelector:
-            return 404
-        }
-    }
-
-    public var errorUserInfo: [String: Any] {
-        var message: String
-        switch self {
-        case .unrecognizedSelector(let classType, let selector):
-            message = "'\(String(describing: classType))' doesn't recognize selector '\(selector)'"
-        }
-        return [NSLocalizedDescriptionKey: message]
-    }
-}

+ 2 - 0
XCTreeLang/XCTLRuntimeError.swift

@@ -24,5 +24,7 @@ public enum XCTLRuntimeError: Error {
     case invalidConditionFrame
     case invalidConditionFrame
     case invalidListFrame
     case invalidListFrame
     
     
+    case variableNotImplementProtocol(protocolName: String)
+    
 }
 }