├── .DS_Store ├── .gitignore ├── .travis.yml ├── Demo ├── .DS_Store ├── OCEvalDemo │ ├── .DS_Store │ ├── OCEvalDemo.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcuserdata │ │ │ │ └── sgcy.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── OCEvalDemo.xcscheme │ │ └── xcuserdata │ │ │ └── sgcy.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ ├── OCEvalDemo.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── sgcy.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ ├── OCEvalDemo │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── ViewController.h │ │ ├── ViewController.m │ │ └── main.m │ ├── OCEvalDemoTests │ │ ├── Info.plist │ │ ├── OCBlockTest.m │ │ ├── OCCfuntionTest.m │ │ ├── OCControlTest.m │ │ ├── OCLexerTest.m │ │ ├── OCLiteralTest.m │ │ └── OCParserTest.m │ ├── Podfile │ ├── Podfile.lock │ └── Pods │ │ ├── Local Podspecs │ │ └── OCEval.podspec.json │ │ ├── Manifest.lock │ │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ └── xcuserdata │ │ │ └── sgcy.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── OCEval.xcscheme │ │ │ ├── Pods-OCEvalDemo.xcscheme │ │ │ ├── Pods-OCEvalDemoTests.xcscheme │ │ │ └── xcschememanagement.plist │ │ └── Target Support Files │ │ ├── OCEval │ │ ├── OCEval-Info.plist │ │ ├── OCEval-dummy.m │ │ ├── OCEval-prefix.pch │ │ ├── OCEval-umbrella.h │ │ ├── OCEval.modulemap │ │ └── OCEval.xcconfig │ │ ├── Pods-OCEvalDemo │ │ ├── Info.plist │ │ ├── Pods-OCEvalDemo-Info.plist │ │ ├── Pods-OCEvalDemo-acknowledgements.markdown │ │ ├── Pods-OCEvalDemo-acknowledgements.plist │ │ ├── Pods-OCEvalDemo-dummy.m │ │ ├── Pods-OCEvalDemo-frameworks.sh │ │ ├── Pods-OCEvalDemo-resources.sh │ │ ├── Pods-OCEvalDemo-umbrella.h │ │ ├── Pods-OCEvalDemo.debug.xcconfig │ │ ├── Pods-OCEvalDemo.modulemap │ │ └── Pods-OCEvalDemo.release.xcconfig │ │ └── Pods-OCEvalDemoTests │ │ ├── Info.plist │ │ ├── Pods-OCEvalDemoTests-Info.plist │ │ ├── Pods-OCEvalDemoTests-acknowledgements.markdown │ │ ├── Pods-OCEvalDemoTests-acknowledgements.plist │ │ ├── Pods-OCEvalDemoTests-dummy.m │ │ ├── Pods-OCEvalDemoTests-frameworks.sh │ │ ├── Pods-OCEvalDemoTests-resources.sh │ │ ├── Pods-OCEvalDemoTests-umbrella.h │ │ ├── Pods-OCEvalDemoTests.debug.xcconfig │ │ ├── Pods-OCEvalDemoTests.modulemap │ │ └── Pods-OCEvalDemoTests.release.xcconfig └── OCEvalMacDemo │ ├── OCEvalMacDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── sgcy.xcuserdatad │ │ └── xcschemes │ │ ├── OCEvalMacDemo.xcscheme │ │ ├── OCEvalMacTest.xcscheme │ │ └── xcschememanagement.plist │ ├── OCEvalMacDemo.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── sgcy.xcuserdatad │ │ ├── WorkspaceSettings.xcsettings │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ ├── OCEvalMacDemo │ └── main.m │ ├── OCEvalMacTest │ ├── Info.plist │ └── OCEvalMacTest.m │ ├── Podfile │ ├── Podfile.lock │ └── Pods │ ├── Local Podspecs │ └── OCEval.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── sgcy.xcuserdatad │ │ └── xcschemes │ │ ├── OCEval.xcscheme │ │ ├── Pods-OCEvalMacDemo.xcscheme │ │ ├── Pods-OCEvalMacTest.xcscheme │ │ └── xcschememanagement.plist │ └── Target Support Files │ ├── OCEval │ ├── Info.plist │ ├── OCEval-Info.plist │ ├── OCEval-dummy.m │ ├── OCEval-prefix.pch │ ├── OCEval-umbrella.h │ ├── OCEval.modulemap │ └── OCEval.xcconfig │ ├── Pods-OCEvalMacDemo │ ├── Info.plist │ ├── Pods-OCEvalMacDemo-Info.plist │ ├── Pods-OCEvalMacDemo-acknowledgements.markdown │ ├── Pods-OCEvalMacDemo-acknowledgements.plist │ ├── Pods-OCEvalMacDemo-dummy.m │ ├── Pods-OCEvalMacDemo-frameworks.sh │ ├── Pods-OCEvalMacDemo-resources.sh │ ├── Pods-OCEvalMacDemo-umbrella.h │ ├── Pods-OCEvalMacDemo.debug.xcconfig │ ├── Pods-OCEvalMacDemo.modulemap │ └── Pods-OCEvalMacDemo.release.xcconfig │ └── Pods-OCEvalMacTest │ ├── Info.plist │ ├── Pods-OCEvalMacTest-Info.plist │ ├── Pods-OCEvalMacTest-acknowledgements.markdown │ ├── Pods-OCEvalMacTest-acknowledgements.plist │ ├── Pods-OCEvalMacTest-dummy.m │ ├── Pods-OCEvalMacTest-frameworks.sh │ ├── Pods-OCEvalMacTest-resources.sh │ ├── Pods-OCEvalMacTest-umbrella.h │ ├── Pods-OCEvalMacTest.debug.xcconfig │ ├── Pods-OCEvalMacTest.modulemap │ └── Pods-OCEvalMacTest.release.xcconfig ├── OCEval.podspec ├── OCEval ├── .DS_Store ├── OCEval.h ├── OCEval.m ├── helper │ ├── .DS_Store │ ├── Aspects.h │ ├── Aspects.m │ ├── FuntionSearch.c │ ├── FuntionSearch.h │ ├── NSValue+struct.h │ ├── NSValue+struct.m │ ├── OCBlockWrapper.h │ ├── OCBlockWrapper.m │ ├── OCCFuntionWrapper.h │ ├── OCCFuntionWrapper.m │ ├── OCCfuntionHelper.h │ ├── OCCfuntionHelper.m │ └── libffi │ │ ├── ffi.h │ │ ├── ffi_arm.h │ │ ├── ffi_arm64.h │ │ ├── ffi_i386.h │ │ ├── ffi_x86_64.h │ │ ├── ffitarget.h │ │ ├── ffitarget_arm.h │ │ ├── ffitarget_arm64.h │ │ ├── ffitarget_i386.h │ │ ├── ffitarget_x86_64.h │ │ └── libffi.a ├── lexer │ ├── OCLexer.h │ ├── OCLexer.m │ ├── OCReader.h │ ├── OCReader.m │ ├── OCToken.h │ ├── OCToken.m │ ├── OCTokenReader.h │ └── OCTokenReader.m └── parser │ ├── .DS_Store │ ├── OCBlockNode.h │ ├── OCBlockNode.m │ ├── OCControlNode.h │ ├── OCControlNode.m │ ├── OCExtension.h │ ├── OCExtension.m │ ├── OCFastCalculateNode.h │ ├── OCFastCalculateNode.m │ ├── OCIterateNode.h │ ├── OCIterateNode.m │ ├── OCLineNode.h │ ├── OCLineNode.m │ ├── OCLiteralNode.h │ ├── OCLiteralNode.m │ ├── OCMethodNode+invoke.h │ ├── OCMethodNode+invoke.m │ ├── OCMethodNode.h │ ├── OCMethodNode.m │ ├── OCMethodSignature.h │ ├── OCMethodSignature.m │ ├── OCNode.h │ ├── OCNode.m │ ├── OCPropertyNode.h │ ├── OCPropertyNode.m │ ├── OCReturnNode.h │ ├── OCReturnNode.m │ ├── OCScopeNode.h │ └── OCScopeNode.m ├── README-CN.md └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilidan/OCEval/19acf3a3cf36cc0f28b455e8d2ee202a5b67157a/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.xcuserstate 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | xcode_workspace: ./Demo/OCEvalDemo/OCEvalDemo.xcworkspace # path to your xcodeproj folder 3 | xcode_scheme: OCEvalDemo 4 | xcode_destination: platform=iOS Simulator,OS=11.3,name=iPhone X 5 | -------------------------------------------------------------------------------- /Demo/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilidan/OCEval/19acf3a3cf36cc0f28b455e8d2ee202a5b67157a/Demo/.DS_Store -------------------------------------------------------------------------------- /Demo/OCEvalDemo/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilidan/OCEval/19acf3a3cf36cc0f28b455e8d2ee202a5b67157a/Demo/OCEvalDemo/.DS_Store -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo.xcodeproj/project.xcworkspace/xcuserdata/sgcy.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilidan/OCEval/19acf3a3cf36cc0f28b455e8d2ee202a5b67157a/Demo/OCEvalDemo/OCEvalDemo.xcodeproj/project.xcworkspace/xcuserdata/sgcy.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo.xcodeproj/xcshareddata/xcschemes/OCEvalDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | OCEvalDemo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 3 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo.xcworkspace/xcuserdata/sgcy.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilidan/OCEval/19acf3a3cf36cc0f28b455e8d2ee202a5b67157a/Demo/OCEvalDemo/OCEvalDemo.xcworkspace/xcuserdata/sgcy.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo.xcworkspace/xcuserdata/sgcy.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // OCEvalDemo 4 | // 5 | // Created by sgcy on 2018/11/21. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // OCEvalDemo 4 | // 5 | // Created by sgcy on 2018/11/21. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "OCEval.h" 11 | #import 12 | #import "ViewController.h" 13 | 14 | @interface AppDelegate () 15 | 16 | @end 17 | 18 | @implementation AppDelegate 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 21 | 22 | [OCEval eval:@" \ 23 | [OCCfuntionHelper defineCFunction:@\"NSSelectorFromString\" types:@\"SEL,NSString *\"];\ 24 | [OCCfuntionHelper defineCFunction:@\"class_getMethodImplementation\" types:@\"IMP,Class,SEL\"];\ 25 | [OCCfuntionHelper defineCFunction:@\"class_addMethod\" types:@\"BOOL,Class,SEL,IMP,char *\"];\ 26 | SEL viewDidLoad = NSSelectorFromString(@\"viewDidLoad\");\ 27 | IMP imp = class_getMethodImplementation([ViewController class], viewDidLoad);\ 28 | SEL selector = NSSelectorFromString(@\"tableView:numberOfRowsInSection:\");\ 29 | BOOL didAdd1 = class_addMethod([ViewController class], selector,imp ,@\"i@:@i\");\ 30 | SEL selector2 = NSSelectorFromString(@\"tableView:cellForRowAtIndexPath:\");\ 31 | BOOL didAdd2 = class_addMethod([ViewController class], selector2,imp,@\"@@:@@\");"]; 32 | 33 | 34 | //call method 35 | NSString *viewDidload = @"{\ 36 | [OCCfuntionHelper defineCFunction:@\"objc_setAssociatedObject\" types:@\"void,id,void *,id,unsigned int\"];\ 37 | [OCCfuntionHelper defineCFunction:@\"objc_getAssociatedObject\" types:@\"id,id,void *\"];\ 38 | [originalInvocation invoke];\ 39 | UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:0];\ 40 | [self.view addSubview:tableView];\ 41 | tableView.delegate = self;\ 42 | tableView.dataSource = self;\ 43 | tableView.tableFooterView = [UIView new];\ 44 | tableView.tableHeaderView = [UIView new];\ 45 | NSURL *url = [NSURL URLWithString:@\"https://jobs.github.com/positions.json?page=1&search=iOS\"];\ 46 | NSURLRequest *request = [NSURLRequest requestWithURL:url];\ 47 | [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {\ 48 | if(data){\ 49 | NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];\ 50 | objc_setAssociatedObject(self, @\"data\", array, 1);\ 51 | [tableView reloadData];\ 52 | }\ 53 | }];}\ 54 | "; 55 | 56 | [OCEval hookClass:@"ViewController" 57 | selector:@"viewDidLoad" 58 | argNames:@[] 59 | isClass:NO 60 | implementation:viewDidload]; 61 | 62 | 63 | NSString *numberOfRowsInSection = @"{NSArray *array = objc_getAssociatedObject(self, @\"data\");\ 64 | if (array != nil) {\ 65 | return array.count;\ 66 | }else{\ 67 | return 0;\ 68 | }\ 69 | }"; 70 | 71 | [OCEval hookClass:@"ViewController" 72 | selector:@"tableView:numberOfRowsInSection:" 73 | argNames:@[@"tableView",@"section"] 74 | isClass:NO 75 | implementation:numberOfRowsInSection]; 76 | 77 | NSString *cellForRowAtIndexPath = @"{\ 78 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@\"aCell\"];\ 79 | if (cell == nil) {\ 80 | cell = [[UITableViewCell alloc] initWithStyle:3 reuseIdentifier:@\"aCell\"];\ 81 | }\ 82 | NSArray *array = objc_getAssociatedObject(self, @\"data\");\ 83 | NSDictionary *model = array[indexPath.row];\ 84 | NSString *title = model[@\"title\"];\ 85 | if (title.length > 30) {\ 86 | title = [title substringWithRange:NSMakeRange(0, 30)];\ 87 | }\ 88 | cell.textLabel.text = title;\ 89 | cell.detailTextLabel.text = [NSString stringWithFormat:@\"%@,%@,%@\",model[@\"company\"],model[@\"location\"],model[@\"created_at\"]];\ 90 | return cell;\ 91 | "; 92 | 93 | // NSString *title = @""; 94 | 95 | [OCEval hookClass:@"ViewController" 96 | selector:@"tableView:cellForRowAtIndexPath:" 97 | argNames:@[@"tableView",@"indexPath"] 98 | isClass:NO 99 | implementation:cellForRowAtIndexPath]; 100 | 101 | return YES; 102 | 103 | 104 | } 105 | 106 | 107 | - (void)applicationWillResignActive:(UIApplication *)application { 108 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 109 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 110 | } 111 | 112 | 113 | - (void)applicationDidEnterBackground:(UIApplication *)application { 114 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 115 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 116 | } 117 | 118 | 119 | - (void)applicationWillEnterForeground:(UIApplication *)application { 120 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 121 | } 122 | 123 | 124 | - (void)applicationDidBecomeActive:(UIApplication *)application { 125 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 126 | } 127 | 128 | 129 | - (void)applicationWillTerminate:(UIApplication *)application { 130 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 131 | } 132 | 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // OCEvalDemo 4 | // 5 | // Created by sgcy on 2018/11/21. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // OCEvalDemo 4 | // 5 | // Created by sgcy on 2018/11/21. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import 11 | #import "OCEval.h" 12 | 13 | @interface ViewController () 14 | 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // OCEvalDemo 4 | // 5 | // Created by sgcy on 2018/11/21. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemoTests/OCBlockTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCBlockTest.m 3 | // OCParserTest 4 | // 5 | // Created by sgcy on 2018/11/19. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCEval.h" 11 | 12 | @interface OCBlockTest : XCTestCase 13 | 14 | @end 15 | 16 | @implementation OCBlockTest 17 | 18 | - (void)testBlock { 19 | NSString *inputStr = @"{NSArray *content = @[@6,@7,@8,@9,@1,@2,@3,@4];\ 20 | NSComparisonResult (^comparison)(id obj1, id obj2) = ^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {\ 21 | return [obj1 doubleValue] > [obj2 doubleValue];\ 22 | };\ 23 | content = [content sortedArrayUsingComparator:comparison];\ 24 | return content;\ 25 | }"; 26 | NSArray *result = [OCEval eval:inputStr]; 27 | NSAssert([result[6] intValue] == 8, nil); 28 | } 29 | 30 | 31 | - (void)testBlock2{ 32 | NSString *inputStr = @"{NSArray *content = @[@6,@7,@8,@9,@1,@2,@3,@4];\ 33 | __block NSInteger result = 0;\ 34 | [content enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {\ 35 | result = result + 1;\ 36 | }];\ 37 | return result;\ 38 | }"; 39 | NSNumber *result = [OCEval eval:inputStr]; 40 | NSAssert(result.doubleValue == 8, nil); 41 | } 42 | 43 | - (void)testBlock3{ 44 | NSString *inputStr = @"{__block NSInteger result = 0;\ 45 | void(^blk)(NSInteger toAdd) = ^(NSInteger toAdd){\ 46 | result = result + toAdd;\ 47 | };\ 48 | blk(3);\ 49 | return result;\ 50 | }"; 51 | NSNumber *result = [OCEval eval:inputStr]; 52 | NSAssert(result.doubleValue == 3, nil); 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemoTests/OCControlTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCControlTest.m 3 | // OCParserTest 4 | // 5 | // Created by sgcy on 2018/11/17. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCEval.h" 11 | 12 | 13 | @interface OCControlTest : XCTestCase 14 | 15 | @end 16 | 17 | @implementation OCControlTest 18 | 19 | 20 | - (void)testIf{ 21 | NSString *inputStr = @"{ NSString *str = [NSString string];\ 22 | if (str.length == 0) {\ 23 | return str;\ 24 | }}"; 25 | NSString *result = [OCEval eval:inputStr]; 26 | NSAssert([result isEqualToString:@""], nil); 27 | } 28 | 29 | - (void)testIf2{ 30 | NSString *inputStr = @"{ NSString *str = [NSString string];\ 31 | if (str) {\ 32 | return str;\ 33 | }}"; 34 | NSString *result = [OCEval eval:inputStr]; 35 | NSAssert([result isEqualToString:@""], nil); 36 | } 37 | 38 | //- (void)testIf3{ 39 | // NSString *inputStr = @"{ NSString *str = [NSString string];\ 40 | // if (!str) {\ 41 | // return str;\ 42 | // }}"; 43 | // NSString *result = [OCEval eval:inputStr]; 44 | // NSAssert(result == nil, nil); 45 | //} 46 | 47 | 48 | - (void)testIfElse{ 49 | NSString *inputStr = @"{ NSString *str = [NSString string];\ 50 | if (str.length == 2) {\ 51 | return nil;\ 52 | }else if(str.length == 0){\ 53 | return str;\ 54 | }}"; 55 | NSString *result = [OCEval eval:inputStr]; 56 | NSAssert([result isEqualToString:@""], nil); 57 | } 58 | 59 | 60 | - (void)testElseIf{ 61 | NSString *inputStr = @"{ NSString *str = [NSString string];\ 62 | if (str.length == 2) {\ 63 | return nil;\ 64 | }else if(str.length == 0){\ 65 | return str;\ 66 | }else{}}"; 67 | NSString *result = [OCEval eval:inputStr]; 68 | NSAssert([result isEqualToString:@""], nil); 69 | } 70 | 71 | - (void)testDoWhile{ 72 | NSString *inputStr = @"{ int i = 4;\ 73 | do {\ 74 | i = i + 1;\ 75 | } while (i < 10);\ 76 | return i;}"; 77 | NSNumber *result = [OCEval eval:inputStr]; 78 | NSAssert(result.integerValue == 10, nil); 79 | } 80 | 81 | - (void)testWhileDo{ 82 | NSString *inputStr = @"{ int i = -4;\ 83 | while (i < 10) do {\ 84 | i = i + 1;\ 85 | }\ 86 | return i;}"; 87 | NSNumber *result = [OCEval eval:inputStr]; 88 | NSAssert(result.integerValue == 10, nil); 89 | } 90 | 91 | - (void)testForIn{ 92 | 93 | NSString *inputStr = @"{ NSArray *nums = @[@(1),@(2),@(3)];\ 94 | NSInteger value = 0;\ 95 | for (NSNumber *num in nums) {\ 96 | value = value + num;\ 97 | }\ 98 | return value;}"; 99 | NSNumber *result = [OCEval eval:inputStr]; 100 | NSAssert(result.integerValue == 6, nil); 101 | } 102 | 103 | - (void)testFor{ 104 | NSString *inputStr = @"{ NSArray *nums = @[@(1),@(2),@(3)];\ 105 | int j = -4;\ 106 | for (int i = 0; i< nums.count; i = i + 1) {\ 107 | j = j + i;\ 108 | }\ 109 | return j;}"; 110 | NSNumber *result = [OCEval eval:inputStr]; 111 | NSAssert(result.integerValue == -1, nil); 112 | } 113 | 114 | 115 | 116 | - (void)testFor2{ 117 | NSString *inputStr = @"{ NSArray *nums = @[@(1),@(2),@(3)];\ 118 | int j = -4;\ 119 | for (int i = 0; i< nums.count; i++) {\ 120 | j += 1;\ 121 | }\ 122 | return j;}"; 123 | NSNumber *result = [OCEval eval:inputStr]; 124 | NSAssert(result.integerValue == -1, nil); 125 | } 126 | 127 | - (void)testFor3{ 128 | NSString *inputStr = @"{ \ 129 | int j = -4;\ 130 | for (int i = 0; i< 6; i++) {\ 131 | j += i;\ 132 | }\ 133 | return j;}"; 134 | NSNumber *result = [OCEval eval:inputStr]; 135 | NSAssert(result.integerValue == 11, nil); 136 | } 137 | 138 | 139 | 140 | - (void)testFor4{ 141 | NSString *inputStr = @"{ NSArray *nums = @[@(1),@(2),@(3)];\ 142 | int j = -4;\ 143 | for (int i = 0; i< nums.count; i++) {\ 144 | j = j + i;\ 145 | }\ 146 | return j;}"; 147 | NSNumber *result = [OCEval eval:inputStr]; 148 | NSAssert(result.integerValue == -1, nil); 149 | } 150 | 151 | 152 | 153 | - (void)testFor5{ 154 | NSString *inputStr = @"{ \ 155 | int j = -4;\ 156 | for (int i = 5; i > 0; i--) {\ 157 | j -= i;\ 158 | }\ 159 | return j;}"; 160 | NSNumber *result = [OCEval eval:inputStr]; 161 | NSAssert(result.integerValue == -19, nil); 162 | //TODO i++,i+=1 163 | } 164 | 165 | 166 | 167 | @end 168 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemoTests/OCLexerTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCParserTest.m 3 | // OCParserTest 4 | // 5 | // Created by sgcy on 2018/11/14. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCLexer.h" 11 | #import "OCToken.h" 12 | 13 | @interface OCLexerTest : XCTestCase 14 | 15 | @end 16 | 17 | @implementation OCLexerTest 18 | 19 | - (void)testSymbol1 { 20 | NSString *inputStr = @":@(YES)"; 21 | OCLexer *lexer = [OCLexer lexerWithString:inputStr]; 22 | XCTAssert([lexer allTokens].count == 5); 23 | } 24 | 25 | - (void)testSymbol2 { 26 | NSString *inputStr = @"1 += 2"; 27 | OCLexer *lexer = [OCLexer lexerWithString:inputStr]; 28 | XCTAssert([lexer allTokens].count == 5); 29 | } 30 | 31 | - (void)testWhiteSpace { 32 | NSString *inputStr = @"1 += 2"; 33 | OCLexer *lexer = [OCLexer lexerWithString:inputStr]; 34 | XCTAssert([lexer allTokens:NO].count == 3); 35 | } 36 | 37 | - (void)testQuotedString { 38 | NSString *inputStr = @"\"aaa\""; 39 | OCLexer *lexer = [OCLexer lexerWithString:inputStr]; 40 | OCToken *token = [lexer allTokens:NO][0]; 41 | XCTAssert([token.value isEqualToString:@"aaa"]); 42 | } 43 | 44 | 45 | - (void)testSingleLineComment{ 46 | // NSString *inputStr = @" \\\\[[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:skey];\ 47 | // 1 += 2"; 48 | // OCLexer *lexer = [OCLexer lexerWithString:inputStr]; 49 | // XCTAssert([lexer allTokens:NO].count == 3); 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemoTests/OCLiteralTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCLiteralTest.m 3 | // OCParserTest 4 | // 5 | // Created by sgcy on 2018/11/17. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCEval.h" 11 | 12 | @interface OCLiteralTest : XCTestCase 13 | 14 | @end 15 | 16 | @implementation OCLiteralTest 17 | 18 | - (void)testNSString { 19 | NSString *inputStr = @"{ NSString *str = @\"a\";\ 20 | NSString *str2 = [str stringByAppendingString:@\"b\"];\ 21 | return str2;\ 22 | }"; 23 | NSString *result = [OCEval eval:inputStr]; 24 | NSAssert([result isEqualToString:@"ab"], nil); 25 | } 26 | 27 | - (void)testNSNumber{ 28 | NSString *inputStr = @"{ NSString *str = @\"a\";\ 29 | NSString *str2 = [str stringByAppendingFormat:@\"%@,%@\",@\"2\",@(4 + 5*2)];\ 30 | return str2;\ 31 | }"; 32 | NSString *result = [OCEval eval:inputStr]; 33 | NSAssert([result isEqualToString:@"a2,14"], nil); 34 | //TODO format:%d 35 | } 36 | 37 | - (void)testNSArray{ 38 | NSString *inputStr = @"{NSArray *array = @[@\"a\",[NSNull null],@\"c\",[NSString string],@(5)];\ 39 | NSMutableArray *mutaArray = [array mutableCopy];\ 40 | mutaArray[5] = @\"d\";\ 41 | return mutaArray[5];\ 42 | }"; 43 | NSString *result = [OCEval eval:inputStr]; 44 | NSAssert([result isEqualToString:@"d"], nil); 45 | } 46 | 47 | - (void)testNSDictionary{ 48 | NSString *inputStr = @"{NSDictionary *dic = @{@\"aaa\":@(1),@\"6666\":[NSArray array]};\ 49 | NSDictionary *dic2 = [NSDictionary dictionaryWithObjectsAndKeys:@1,@\"go2\",@\"go3\",@\"go4\", nil];\ 50 | NSMutableDictionary *mutaDic = [dic mutableCopy];\ 51 | mutaDic[@\"w\"] = @\"xyz\";\ 52 | return mutaDic[@\"w\"];\ 53 | }"; 54 | NSString *result = [OCEval eval:inputStr]; 55 | NSAssert([result isEqualToString:@"xyz"], nil); 56 | } 57 | 58 | - (void)testJson{ 59 | NSString *inputStr = @"{NSDictionary *dic = @{@\"aaa\":@(1),@\"6666\":@{@\"bbb\":@\"cccc\"}};\ 60 | return dic[@\"6666\"][\"bbb\"];\ 61 | }"; 62 | NSString *result = [OCEval eval:inputStr]; 63 | NSAssert([result isEqualToString:@"cccc"], nil); 64 | } 65 | 66 | 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/OCEvalDemoTests/OCParserTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCParserTest.m 3 | // OCParserTest 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCMethodNode.h" 11 | #import "OCReturnNode.h" 12 | #import "OCScopeNode.h" 13 | #import "OCControlNode.h" 14 | #import "OCLexer.h" 15 | #import "OCEval.h" 16 | 17 | @interface OCParserTest : XCTestCase 18 | 19 | @end 20 | 21 | @implementation OCParserTest 22 | 23 | - (void)testReturnNode { 24 | NSString *inputStr = @"(follow);"; 25 | OCLexer *lexer = [OCLexer lexerWithString:inputStr]; 26 | OCReturnNode *rootNode = [[OCReturnNode alloc] initWithReader:[[OCTokenReader alloc] initWithTokens:[lexer allTokens:NO]]]; 27 | NSLog(@"%@",rootNode); 28 | } 29 | 30 | - (void)testReturnNodeExpression { 31 | NSString *inputStr = @"return 5-(1+2*4);"; 32 | NSNumber *result = [OCEval eval:inputStr]; 33 | NSAssert([result integerValue] == -4, nil); 34 | } 35 | 36 | - (void)testReturnNodePredicate { 37 | NSString *inputStr = @"return alpha + 3 <= 4 && 6 + 3 < 10;"; 38 | NSNumber *result = [OCEval eval:inputStr context:[@{@"alpha":@(0)} mutableCopy]]; 39 | NSAssert([result boolValue] == YES, nil); 40 | } 41 | 42 | - (void)testReturnNodeMethod { 43 | NSString *inputStr = @"return alpha + 3 <= 4 && [NSString string] != nil;"; 44 | NSNumber *result = [OCEval eval:inputStr context:[@{@"alpha":@(0)} mutableCopy]]; 45 | NSAssert([result boolValue] == YES, nil); 46 | } 47 | 48 | - (void)testScopeVariable{ 49 | // you can modify a variable's value. but you can't use the variable outside the scope. 50 | NSString *inputStr = @"{ NSString *str = [NSString string];\ 51 | if (str.length == 0) {\ 52 | str = nil;\ 53 | NSString *strr = [NSString string];\ 54 | }\ 55 | return str;\ 56 | }"; 57 | NSString *result = [OCEval eval:inputStr]; 58 | NSAssert(result == nil, nil); 59 | } 60 | 61 | - (void)testPointSetter{ 62 | NSString *inputStr = @"{ NSDateFormatter *formatter = [[NSDateFormatter alloc] init];\ 63 | formatter.dateFormat = @\"HH:MM:SS\";\ 64 | return [formatter stringFromDate:[NSDate date]];}"; 65 | NSString *result = [OCEval eval:inputStr]; 66 | NSAssert(result != nil, nil); 67 | } 68 | 69 | - (void)testPointGetter{ 70 | #if TARGET_OS_IPHONE 71 | NSString *inputStr = @"{ UIView *view = [[UIView alloc] init];\ 72 | CGRect frame = [view bounds];\ 73 | return frame;}"; 74 | NSValue *result = [OCEval eval:inputStr]; 75 | #else 76 | NSString *inputStr = @"{ NSView *view = [[NSView alloc] init];\ 77 | NSRect frame = [view bounds];\ 78 | return frame;}"; 79 | NSValue *result = [OCEval eval:inputStr]; 80 | #endif 81 | 82 | #if TARGET_OS_IPHONE 83 | NSAssert([result CGRectValue].origin.x == 0, nil); 84 | #else 85 | NSAssert([result rectValue].origin.x == 0, nil); 86 | #endif 87 | 88 | } 89 | 90 | 91 | - (void)testLine{ 92 | NSString *inputStr = @"{;;;;}"; 93 | NSString *result = [OCEval eval:inputStr]; 94 | } 95 | 96 | 97 | - (void)testPointerToPointer{ 98 | 99 | // NSData *data = [@"{[]{{{{}" dataUsingEncoding:4]; 100 | // NSError *error = [NSError errorWithDomain:@"error" code:0 userInfo:@{}]; 101 | // id result2 = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 102 | // 103 | NSString *input = @"\ 104 | NSData *data = [@\"{[]{{{{}\" dataUsingEncoding:4];\ 105 | NSError *error = [NSError errorWithDomain:@\"error\" code:0 userInfo:@{}];\ 106 | id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];\ 107 | return error;\ 108 | "; 109 | id result = [OCEval eval:input]; 110 | #if TARGET_OS_IPHONE 111 | NSAssert([NSStringFromClass([result class]) isEqualToString:@"NSError"], nil); 112 | #else 113 | NSAssert([[result className] isEqualToString:@"NSError"], nil); 114 | #endif 115 | 116 | } 117 | 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '8.0' 2 | use_frameworks! 3 | target 'OCEvalDemo' do 4 | pod 'OCEval', :path => '../../' 5 | end 6 | target 'OCEvalDemoTests' do 7 | pod 'OCEval', :path => '../../' 8 | end 9 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - OCEval (0.0.1) 3 | 4 | DEPENDENCIES: 5 | - OCEval (from `../../`) 6 | 7 | EXTERNAL SOURCES: 8 | OCEval: 9 | :path: "../../" 10 | 11 | SPEC CHECKSUMS: 12 | OCEval: 5ebf81afa2b3c08465a2f099eecda6ef896a977d 13 | 14 | PODFILE CHECKSUM: 1d7e92b8e402d5569ca602d861a126235a758ee5 15 | 16 | COCOAPODS: 1.6.0.beta.2 17 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Local Podspecs/OCEval.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OCEval", 3 | "version": "0.0.1", 4 | "summary": "OCEval", 5 | "description": "OCEval", 6 | "homepage": "https://github.com/lilidan/OCEval", 7 | "authors": { 8 | "sgcy": "sgcy1991@qq.com" 9 | }, 10 | "source": { 11 | "git": "https://github.com/lilidan/OCEval.git", 12 | "tag": "0.0.1" 13 | }, 14 | "source_files": [ 15 | "OCEval", 16 | "OCEval/**/*.{h,m,c}" 17 | ], 18 | "exclude_files": "OCEval/Exclude", 19 | "vendored_libraries": "OCEval/helper/libffi/libffi.a", 20 | "platforms": { 21 | "osx": null, 22 | "ios": null, 23 | "tvos": null, 24 | "watchos": null 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - OCEval (0.0.1) 3 | 4 | DEPENDENCIES: 5 | - OCEval (from `../../`) 6 | 7 | EXTERNAL SOURCES: 8 | OCEval: 9 | :path: "../../" 10 | 11 | SPEC CHECKSUMS: 12 | OCEval: 5ebf81afa2b3c08465a2f099eecda6ef896a977d 13 | 14 | PODFILE CHECKSUM: 1d7e92b8e402d5569ca602d861a126235a758ee5 15 | 16 | COCOAPODS: 1.6.0.beta.2 17 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Pods.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/OCEval.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Pods.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/Pods-OCEvalDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Pods.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/Pods-OCEvalDemoTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Pods.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | OCEval.xcscheme 8 | 9 | isShown 10 | 11 | orderHint 12 | 0 13 | 14 | Pods-OCEvalDemo.xcscheme 15 | 16 | isShown 17 | 18 | orderHint 19 | 1 20 | 21 | Pods-OCEvalDemoTests.xcscheme 22 | 23 | isShown 24 | 25 | orderHint 26 | 2 27 | 28 | 29 | SuppressBuildableAutocreation 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/OCEval/OCEval-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/OCEval/OCEval-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_OCEval : NSObject 3 | @end 4 | @implementation PodsDummy_OCEval 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/OCEval/OCEval-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/OCEval/OCEval-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "OCEval.h" 14 | #import "Aspects.h" 15 | #import "FuntionSearch.h" 16 | #import "ffi.h" 17 | #import "ffitarget.h" 18 | #import "ffitarget_arm.h" 19 | #import "ffitarget_arm64.h" 20 | #import "ffitarget_i386.h" 21 | #import "ffitarget_x86_64.h" 22 | #import "ffi_arm.h" 23 | #import "ffi_arm64.h" 24 | #import "ffi_i386.h" 25 | #import "ffi_x86_64.h" 26 | #import "NSValue+struct.h" 27 | #import "OCBlockWrapper.h" 28 | #import "OCCfuntionHelper.h" 29 | #import "OCCFuntionWrapper.h" 30 | #import "OCLexer.h" 31 | #import "OCReader.h" 32 | #import "OCToken.h" 33 | #import "OCTokenReader.h" 34 | #import "OCBlockNode.h" 35 | #import "OCControlNode.h" 36 | #import "OCExtension.h" 37 | #import "OCFastCalculateNode.h" 38 | #import "OCIterateNode.h" 39 | #import "OCLineNode.h" 40 | #import "OCLiteralNode.h" 41 | #import "OCMethodNode+invoke.h" 42 | #import "OCMethodNode.h" 43 | #import "OCMethodSignature.h" 44 | #import "OCNode.h" 45 | #import "OCPropertyNode.h" 46 | #import "OCReturnNode.h" 47 | #import "OCScopeNode.h" 48 | 49 | FOUNDATION_EXPORT double OCEvalVersionNumber; 50 | FOUNDATION_EXPORT const unsigned char OCEvalVersionString[]; 51 | 52 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/OCEval/OCEval.modulemap: -------------------------------------------------------------------------------- 1 | framework module OCEval { 2 | umbrella header "OCEval-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/OCEval/OCEval.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/OCEval 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../../OCEval/helper/libffi" 4 | OTHER_LDFLAGS = $(inherited) -l"ffi" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemo/Pods-OCEvalDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemo/Pods-OCEvalDemo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemo/Pods-OCEvalDemo-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemo/Pods-OCEvalDemo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_OCEvalDemo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_OCEvalDemo 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemo/Pods-OCEvalDemo-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_OCEvalDemoVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_OCEvalDemoVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemo/Pods-OCEvalDemo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval/OCEval.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../../OCEval/helper/libffi" 6 | OTHER_LDFLAGS = $(inherited) -ObjC -l"ffi" -framework "OCEval" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemo/Pods-OCEvalDemo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_OCEvalDemo { 2 | umbrella header "Pods-OCEvalDemo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemo/Pods-OCEvalDemo.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval/OCEval.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../../OCEval/helper/libffi" 6 | OTHER_LDFLAGS = $(inherited) -ObjC -l"ffi" -framework "OCEval" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemoTests/Pods-OCEvalDemoTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemoTests/Pods-OCEvalDemoTests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemoTests/Pods-OCEvalDemoTests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemoTests/Pods-OCEvalDemoTests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_OCEvalDemoTests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_OCEvalDemoTests 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemoTests/Pods-OCEvalDemoTests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_OCEvalDemoTestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_OCEvalDemoTestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemoTests/Pods-OCEvalDemoTests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval/OCEval.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../../OCEval/helper/libffi" 6 | OTHER_LDFLAGS = $(inherited) -ObjC -l"ffi" -framework "OCEval" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemoTests/Pods-OCEvalDemoTests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_OCEvalDemoTests { 2 | umbrella header "Pods-OCEvalDemoTests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/OCEvalDemo/Pods/Target Support Files/Pods-OCEvalDemoTests/Pods-OCEvalDemoTests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval/OCEval.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../../OCEval/helper/libffi" 6 | OTHER_LDFLAGS = $(inherited) -ObjC -l"ffi" -framework "OCEval" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/OCEvalMacDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/OCEvalMacTest.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 39 | 40 | 41 | 42 | 48 | 49 | 51 | 52 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | OCEvalMacDemo.xcscheme 8 | 9 | orderHint 10 | 4 11 | 12 | OCEvalMacTest.xcscheme 13 | 14 | isShown 15 | 16 | orderHint 17 | 0 18 | 19 | 20 | SuppressBuildableAutocreation 21 | 22 | D688324B21A969F200FA72C3 23 | 24 | primary 25 | 26 | 27 | D688325921A96A0B00FA72C3 28 | 29 | primary 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo.xcworkspace/xcuserdata/sgcy.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseAppPreferences 7 | CustomBuildLocationType 8 | RelativeToDerivedData 9 | DerivedDataLocationStyle 10 | Default 11 | EnabledFullIndexStoreVisibility 12 | 13 | IssueFilterStyle 14 | ShowActiveSchemeOnly 15 | LiveSourceIssuesEnabled 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo.xcworkspace/xcuserdata/sgcy.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // OCEvalMacDemo 4 | // 5 | // Created by sgcy on 2018/11/24. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCEval.h" 11 | 12 | int main(int argc, const char * argv[]) { 13 | @autoreleasepool { 14 | // insert code here... 15 | NSLog(@"Hello, World!"); 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacTest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/OCEvalMacTest/OCEvalMacTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCEvalMacTest.m 3 | // OCEvalMacTest 4 | // 5 | // Created by sgcy on 2018/11/24. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCEval.h" 11 | #import 12 | 13 | 14 | @interface OCEvalMacTest : XCTestCase 15 | 16 | @end 17 | 18 | @implementation OCEvalMacTest 19 | 20 | 21 | - (void)testPerformance { 22 | // This is an example of a performance test case. 23 | NSDate *date = [NSDate date]; 24 | int j = 0; 25 | 26 | 27 | CGFloat a = 0; 28 | CGFloat b = 0; 29 | CGFloat c = 0; 30 | 31 | for (int i = 0; i < 10000; i++) { 32 | 33 | // NSDate *date = [NSDate date]; 34 | // 35 | // NSMutableString *mutaStr = [[NSMutableString alloc] init]; 36 | // [mutaStr appendFormat:@"1"]; 37 | // [mutaStr appendFormat:@"+"]; 38 | // [mutaStr appendFormat:@"%d",1]; 39 | // 40 | // NSMutableString *mutaStr2 = [[NSMutableString alloc] init]; 41 | // [mutaStr2 appendFormat:@"1"]; 42 | // [mutaStr2 appendFormat:@"=="]; 43 | // [mutaStr2 appendFormat:@"%d",1]; 44 | // 45 | // a += [[NSDate date] timeIntervalSinceDate:date]; 46 | // date = [NSDate date]; 47 | // 48 | // NSExpression *exp = [NSExpression expressionWithFormat:[mutaStr copy]]; 49 | // NSNumber *number = [exp expressionValueWithObject:nil context:nil]; 50 | // 51 | // b += [[NSDate date] timeIntervalSinceDate:date]; 52 | // date = [NSDate date]; 53 | // 54 | // NSPredicate *pre = [NSPredicate predicateWithFormat:[mutaStr2 copy]]; 55 | // [pre evaluateWithObject:nil]; 56 | // c += [[NSDate date] timeIntervalSinceDate:date]; 57 | 58 | // j++; 59 | } 60 | NSLog(@"=====%f",[[NSDate date] timeIntervalSinceDate:date]); 61 | 62 | 63 | NSString *inputStr = @"{\ 64 | [OCCfuntionHelper defineCFunction:@\"NSLog\" types:@\"void, NSString *,float\"];\ 65 | NSDate *date = [NSDate date];\ 66 | int j = 0;\ 67 | for (int i = 0; i < 10000; i++) {\ 68 | }\ 69 | return [[NSDate date] timeIntervalSinceDate:date];\ 70 | }"; 71 | NSNumber *value = [OCEval eval:inputStr]; 72 | NSLog(@"======%f",value.doubleValue); 73 | 74 | JSContext *ctx = [[JSContext alloc] init]; 75 | ctx.exceptionHandler = ^(JSContext *con, JSValue *exception) { 76 | NSLog(@"%@", exception); 77 | con.exception = exception; 78 | }; 79 | 80 | 81 | 82 | [ctx evaluateScript:@"function go() {var j = 0;\ 83 | for (var i=0;i<10000;i++)\ 84 | {\ 85 | j = j+1; \ 86 | }\ 87 | return j;\ 88 | }"]; 89 | date = [NSDate date]; 90 | JSValue *n = [ctx[@"go"] callWithArguments:@[]]; 91 | NSLog(@"xxxxxxx%f xxxxxx%d",[[NSDate date] timeIntervalSinceDate:date],[n toInt32]); 92 | } 93 | 94 | 95 | - (void)testPerformance2 { 96 | // This is an example of a performance test case. 97 | 98 | 99 | NSString *inputStr = @"{\ 100 | NSDate *date = [NSDate date];\ 101 | [NSString stringWithFormat:@\"aaaa%@\",@\"a\"];\ 102 | return [[NSDate date] timeIntervalSinceDate:date];\ 103 | }"; 104 | NSNumber *value = [OCEval eval:inputStr]; 105 | NSLog(@"======%f",value.doubleValue); 106 | 107 | 108 | JSContext *ctx = [[JSContext alloc] init]; 109 | ctx.exceptionHandler = ^(JSContext *con, JSValue *exception) { 110 | NSLog(@"%@", exception); 111 | con.exception = exception; 112 | }; 113 | 114 | // ctx[@"go"] = ^() { 115 | // [NSString stringWithFormat:@"aaaa%@",@"a"]; 116 | // }; 117 | 118 | [ctx evaluateScript:@"function go() { var date = \"a\" + \"b\"}"]; 119 | NSDate * date = [NSDate date]; 120 | [ctx evaluateScript:@"\ 121 | for (var i=0;i<100;i++)\ 122 | {\ 123 | go(); \ 124 | }"]; 125 | NSLog(@"xxxxxxx%f",[[NSDate date] timeIntervalSinceDate:date]); 126 | 127 | 128 | date = [NSDate date]; 129 | for (int i = 0; i < 100; i++) { 130 | [NSString stringWithFormat:@"aaaa%@",@"a"]; 131 | } 132 | NSLog(@"------%f",[[NSDate date] timeIntervalSinceDate:date]); 133 | 134 | } 135 | 136 | @end 137 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.9' 2 | use_frameworks! 3 | target 'OCEvalMacDemo' do 4 | pod 'OCEval', :path => '../../' 5 | end 6 | target 'OCEvalMacTest' do 7 | pod 'OCEval', :path => '../../' 8 | end 9 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - OCEval (0.0.1) 3 | 4 | DEPENDENCIES: 5 | - OCEval (from `../../`) 6 | 7 | EXTERNAL SOURCES: 8 | OCEval: 9 | :path: "../../" 10 | 11 | SPEC CHECKSUMS: 12 | OCEval: 5ebf81afa2b3c08465a2f099eecda6ef896a977d 13 | 14 | PODFILE CHECKSUM: d689c27b223927f1bace3e3c1f24e6c3618bb051 15 | 16 | COCOAPODS: 1.6.0.beta.2 17 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Local Podspecs/OCEval.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OCEval", 3 | "version": "0.0.1", 4 | "summary": "OCEval", 5 | "description": "OCEval", 6 | "homepage": "https://github.com/lilidan/OCEval", 7 | "authors": { 8 | "sgcy": "sgcy1991@qq.com" 9 | }, 10 | "source": { 11 | "git": "https://github.com/lilidan/OCEval.git", 12 | "tag": "0.0.1" 13 | }, 14 | "source_files": [ 15 | "OCEval", 16 | "OCEval/**/*.{h,m,c}" 17 | ], 18 | "exclude_files": "OCEval/Exclude", 19 | "vendored_libraries": "OCEval/helper/libffi/libffi.a", 20 | "platforms": { 21 | "osx": null, 22 | "ios": null, 23 | "tvos": null, 24 | "watchos": null 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - OCEval (0.0.1) 3 | 4 | DEPENDENCIES: 5 | - OCEval (from `../../`) 6 | 7 | EXTERNAL SOURCES: 8 | OCEval: 9 | :path: "../../" 10 | 11 | SPEC CHECKSUMS: 12 | OCEval: 5ebf81afa2b3c08465a2f099eecda6ef896a977d 13 | 14 | PODFILE CHECKSUM: d689c27b223927f1bace3e3c1f24e6c3618bb051 15 | 16 | COCOAPODS: 1.6.0.beta.2 17 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Pods.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/OCEval.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Pods.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/Pods-OCEvalMacDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Pods.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/Pods-OCEvalMacTest.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Pods.xcodeproj/xcuserdata/sgcy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | OCEval.xcscheme 8 | 9 | isShown 10 | 11 | 12 | Pods-OCEvalMacDemo.xcscheme 13 | 14 | isShown 15 | 16 | 17 | Pods-OCEvalMacTest.xcscheme 18 | 19 | isShown 20 | 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/OCEval/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/OCEval/OCEval-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/OCEval/OCEval-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_OCEval : NSObject 3 | @end 4 | @implementation PodsDummy_OCEval 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/OCEval/OCEval-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/OCEval/OCEval-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "OCEval.h" 14 | #import "Aspects.h" 15 | #import "FuntionSearch.h" 16 | #import "ffi.h" 17 | #import "ffitarget.h" 18 | #import "ffitarget_arm.h" 19 | #import "ffitarget_arm64.h" 20 | #import "ffitarget_i386.h" 21 | #import "ffitarget_x86_64.h" 22 | #import "ffi_arm.h" 23 | #import "ffi_arm64.h" 24 | #import "ffi_i386.h" 25 | #import "ffi_x86_64.h" 26 | #import "OCBlockWrapper.h" 27 | #import "OCCfuntionHelper.h" 28 | #import "OCCFuntionWrapper.h" 29 | #import "OCLexer.h" 30 | #import "OCReader.h" 31 | #import "OCToken.h" 32 | #import "OCTokenReader.h" 33 | #import "OCBlockNode.h" 34 | #import "OCControlNode.h" 35 | #import "OCExtension.h" 36 | #import "OCFastCalculateNode.h" 37 | #import "OCIterateNode.h" 38 | #import "OCLineNode.h" 39 | #import "OCLiteralNode.h" 40 | #import "OCMethodNode+invoke.h" 41 | #import "OCMethodNode.h" 42 | #import "OCMethodSignature.h" 43 | #import "OCNode.h" 44 | #import "OCPropertyNode.h" 45 | #import "OCReturnNode.h" 46 | #import "OCScopeNode.h" 47 | 48 | FOUNDATION_EXPORT double OCEvalVersionNumber; 49 | FOUNDATION_EXPORT const unsigned char OCEvalVersionString[]; 50 | 51 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/OCEval/OCEval.modulemap: -------------------------------------------------------------------------------- 1 | framework module OCEval { 2 | umbrella header "OCEval-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/OCEval/OCEval.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/OCEval 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../../OCEval/helper/libffi" 5 | OTHER_LDFLAGS = $(inherited) -l"ffi" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../.. 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacDemo/Pods-OCEvalMacDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacDemo/Pods-OCEvalMacDemo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacDemo/Pods-OCEvalMacDemo-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacDemo/Pods-OCEvalMacDemo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_OCEvalMacDemo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_OCEvalMacDemo 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacDemo/Pods-OCEvalMacDemo-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_OCEvalMacDemoVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_OCEvalMacDemoVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacDemo/Pods-OCEvalMacDemo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval/OCEval.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' 6 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../../OCEval/helper/libffi" 7 | OTHER_LDFLAGS = $(inherited) -ObjC -l"ffi" -framework "OCEval" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacDemo/Pods-OCEvalMacDemo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_OCEvalMacDemo { 2 | umbrella header "Pods-OCEvalMacDemo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacDemo/Pods-OCEvalMacDemo.release.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval/OCEval.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' 6 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../../OCEval/helper/libffi" 7 | OTHER_LDFLAGS = $(inherited) -ObjC -l"ffi" -framework "OCEval" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacTest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacTest/Pods-OCEvalMacTest-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacTest/Pods-OCEvalMacTest-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacTest/Pods-OCEvalMacTest-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacTest/Pods-OCEvalMacTest-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_OCEvalMacTest : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_OCEvalMacTest 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacTest/Pods-OCEvalMacTest-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_OCEvalMacTestVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_OCEvalMacTestVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacTest/Pods-OCEvalMacTest.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval/OCEval.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks' 6 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../../OCEval/helper/libffi" 7 | OTHER_LDFLAGS = $(inherited) -ObjC -l"ffi" -framework "OCEval" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacTest/Pods-OCEvalMacTest.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_OCEvalMacTest { 2 | umbrella header "Pods-OCEvalMacTest-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/OCEvalMacDemo/Pods/Target Support Files/Pods-OCEvalMacTest/Pods-OCEvalMacTest.release.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/OCEval/OCEval.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks' 6 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../../OCEval/helper/libffi" 7 | OTHER_LDFLAGS = $(inherited) -ObjC -l"ffi" -framework "OCEval" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /OCEval.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint Buggy.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "OCEval" 19 | s.version = "0.1.2" 20 | s.summary = "OCEval" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | s.description = "OCEval" 28 | 29 | s.homepage = "https://github.com/lilidan/OCEval" 30 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 31 | 32 | 33 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 34 | # 35 | # Licensing your code is important. See http://choosealicense.com for more info. 36 | # CocoaPods will detect a license file if there is a named LICENSE* 37 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 38 | # 39 | 40 | # s.license = = { :type => "MIT", :file => "LICENSE" } 41 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 42 | 43 | 44 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 45 | # 46 | # Specify the authors of the library, with email addresses. Email addresses 47 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 48 | # accepts just a name if you'd rather not provide an email address. 49 | # 50 | # Specify a social_media_url where others can refer to, for example a twitter 51 | # profile URL. 52 | # 53 | 54 | s.author = { "sgcy" => "sgcy1991@qq.com" } 55 | # Or just: s.author = "sgcy" 56 | # s.authors = { "sgcy" => "sgcy1991@qq.com" } 57 | # s.social_media_url = "http://twitter.com/sgcy" 58 | 59 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 60 | # 61 | # If this Pod runs only on iOS or OS X, then specify the platform and 62 | # the deployment target. You can optionally include the target after the platform. 63 | # 64 | 65 | # s.platform = :ios 66 | # s.platform = :ios, "8.0" 67 | 68 | # When using multiple platforms 69 | # s.ios.deployment_target = "5.0" 70 | # s.osx.deployment_target = "10.7" 71 | # s.watchos.deployment_target = "2.0" 72 | # s.tvos.deployment_target = "9.0" 73 | 74 | 75 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 76 | # 77 | # Specify the location from where the source should be retrieved. 78 | # Supports git, hg, bzr, svn and HTTP. 79 | # 80 | 81 | s.source = { :git => "https://github.com/lilidan/OCEval.git", :tag => "#{s.version}" } 82 | 83 | 84 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 85 | # 86 | # CocoaPods is smart about how it includes source code. For source files 87 | # giving a folder will include any swift, h, m, mm, c & cpp files. 88 | # For header files it will include any header in the folder. 89 | # Not including the public_header_files will make all headers public. 90 | # 91 | 92 | s.source_files = "OCEval", "OCEval/**/*.{h,m,c}" 93 | s.exclude_files = "OCEval/Exclude" 94 | s.vendored_libraries = 'OCEval/helper/libffi/libffi.a' 95 | # s.public_header_files = "Classes/**/*.h" 96 | 97 | 98 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 99 | # 100 | # A list of resources included with the Pod. These are copied into the 101 | # target bundle with a build phase script. Anything else will be cleaned. 102 | # You can preserve files from being cleaned, please don't preserve 103 | # non-essential files like tests, examples and documentation. 104 | # 105 | 106 | # s.resource = "icon.png" 107 | # s.resources = "Resources/*.png" 108 | 109 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 110 | 111 | 112 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 113 | # 114 | # Link your library with frameworks, or libraries. Libraries do not include 115 | # the lib prefix of their name. 116 | # 117 | 118 | # s.framework = "SomeFramework" 119 | # s.frameworks = "SomeFramework", "AnotherFramework" 120 | 121 | # s.library = "iconv" 122 | # s.libraries = "iconv", "xml2" 123 | 124 | 125 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 126 | # 127 | # If your library depends on compiler flags you can set them in the xcconfig hash 128 | # where they will only apply to your library. If you depend on other Podspecs 129 | # you can include multiple dependencies to ensure it works. 130 | 131 | # s.requires_arc = true 132 | 133 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 134 | 135 | 136 | end 137 | -------------------------------------------------------------------------------- /OCEval/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilidan/OCEval/19acf3a3cf36cc0f28b455e8d2ee202a5b67157a/OCEval/.DS_Store -------------------------------------------------------------------------------- /OCEval/OCEval.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCEval.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/21. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface OCEval : NSObject 12 | 13 | + (id)eval:(NSString *)str; 14 | 15 | + (id)eval:(NSString *)str context:(NSMutableDictionary *)context; 16 | 17 | + (void)hookClass:(NSString *)clsName 18 | selector:(NSString *)selName 19 | argNames:(NSArray<__kindof NSString *> *)argNames //original parameters variable name 20 | isClass:(BOOL)isClass //hook class method or instance method 21 | implementation:(NSString *)imp; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /OCEval/OCEval.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCEval.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/21. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCEval.h" 10 | #import "OCLexer.h" 11 | #import "OCToken.h" 12 | #import "OCScopeNode.h" 13 | #import "OCTokenReader.h" 14 | #import "OCMethodNode+invoke.h" 15 | 16 | #import "Aspects.h" 17 | #import 18 | 19 | @implementation OCEval 20 | 21 | + (id)eval:(NSString *)str 22 | { 23 | return [self eval:str context:[@{} mutableCopy]]; 24 | } 25 | 26 | + (id)eval:(NSString *)str context:(NSMutableDictionary *)context 27 | { 28 | if (![[str substringToIndex:1] isEqualToString:@"{"]) { 29 | str = [NSString stringWithFormat:@"{%@}",str]; 30 | } 31 | OCLexer *lexer = [OCLexer lexerWithString:str]; 32 | OCRootNode *rootNode = [[OCRootNode alloc] initWithReader:[[OCTokenReader alloc] initWithTokens:[lexer allTokens:NO]]]; 33 | return [rootNode excuteWithCtx:context];; 34 | } 35 | 36 | + (void)hookClass:(NSString *)clsName 37 | selector:(NSString *)selName 38 | argNames:(NSArray<__kindof NSString *> *)argNames 39 | isClass:(BOOL)isClass 40 | implementation:(NSString *)imp 41 | { 42 | Class class = NSClassFromString(clsName); 43 | SEL selector = NSSelectorFromString(selName); 44 | 45 | if (isClass) { 46 | class = objc_getMetaClass([NSStringFromClass(class) UTF8String]); 47 | } 48 | 49 | OCLexer *lexer = [OCLexer lexerWithString:imp]; 50 | OCRootNode *rootNode = [[OCRootNode alloc] initWithReader:[[OCTokenReader alloc] initWithTokens:[lexer allTokens:NO]]]; 51 | 52 | NSError *error; 53 | [class aspect_hookSelector:selector withOptions:AspectPositionInstead usingBlock:^(id aspectInfo) { 54 | NSMutableDictionary *context = [[NSMutableDictionary alloc] init]; 55 | [context setObject:aspectInfo.instance forKey:@"self"]; 56 | [context setObject:aspectInfo.originalInvocation forKey:@"originalInvocation"]; 57 | NSAssert(aspectInfo.arguments.count == argNames.count, @"Error: Method params count must be same."); 58 | [aspectInfo.arguments enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 59 | NSString *name = argNames[idx]; 60 | [context setObject:obj forKey:name]; 61 | }]; 62 | 63 | id result = [rootNode excuteWithCtx:context]; 64 | 65 | const char *argumentType = aspectInfo.originalInvocation.methodSignature.methodReturnType; 66 | 67 | switch (argumentType[0] == 'r' ? argumentType[1] : argumentType[0]) { 68 | 69 | #define OC_CALL_ARG_CASE(_typeString, _type, _selector) \ 70 | case _typeString: { \ 71 | _type value = [result _selector]; \ 72 | [aspectInfo.originalInvocation setReturnValue:&value];\ 73 | break; \ 74 | } 75 | OC_CALL_ARG_CASE('c', char, charValue) 76 | OC_CALL_ARG_CASE('C', unsigned char, unsignedCharValue) 77 | OC_CALL_ARG_CASE('s', short, shortValue) 78 | OC_CALL_ARG_CASE('S', unsigned short, unsignedShortValue) 79 | OC_CALL_ARG_CASE('i', int, intValue) 80 | OC_CALL_ARG_CASE('I', unsigned int, unsignedIntValue) 81 | OC_CALL_ARG_CASE('l', long, longValue) 82 | OC_CALL_ARG_CASE('L', unsigned long, unsignedLongValue) 83 | OC_CALL_ARG_CASE('q', long long, longLongValue) 84 | OC_CALL_ARG_CASE('Q', unsigned long long, unsignedLongLongValue) 85 | OC_CALL_ARG_CASE('f', float, floatValue) 86 | OC_CALL_ARG_CASE('d', double, doubleValue) 87 | OC_CALL_ARG_CASE('B', BOOL, boolValue) 88 | 89 | case ':': { 90 | SEL value = nil; 91 | if (result != [OCMethodNode nilObj]) { 92 | value = NSSelectorFromString(result); 93 | } 94 | [aspectInfo.originalInvocation setReturnValue:&value]; 95 | break; 96 | } 97 | case '{': { 98 | void *pointer = NULL; 99 | [result getValue:&pointer]; 100 | [aspectInfo.originalInvocation setReturnValue:&pointer]; 101 | break; 102 | } 103 | default: { 104 | if (result == [OCMethodNode nilObj] || 105 | ([result isKindOfClass:[NSNumber class]] && strcmp([result objCType], "c") == 0 && ![result boolValue])) { 106 | result = nil; 107 | [aspectInfo.originalInvocation setReturnValue:&result]; 108 | break; 109 | } 110 | if (result) { 111 | [aspectInfo.originalInvocation setReturnValue:&result]; 112 | } 113 | } 114 | } 115 | 116 | } error:&error]; 117 | } 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /OCEval/helper/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilidan/OCEval/19acf3a3cf36cc0f28b455e8d2ee202a5b67157a/OCEval/helper/.DS_Store -------------------------------------------------------------------------------- /OCEval/helper/Aspects.h: -------------------------------------------------------------------------------- 1 | // 2 | // Aspects.h 3 | // Aspects - A delightful, simple library for aspect oriented programming. 4 | // 5 | // Copyright (c) 2014 Peter Steinberger. Licensed under the MIT license. 6 | // 7 | 8 | #import 9 | 10 | typedef NS_OPTIONS(NSUInteger, AspectOptions) { 11 | AspectPositionAfter = 0, /// Called after the original implementation (default) 12 | AspectPositionInstead = 1, /// Will replace the original implementation. 13 | AspectPositionBefore = 2, /// Called before the original implementation. 14 | 15 | AspectOptionAutomaticRemoval = 1 << 3 /// Will remove the hook after the first execution. 16 | }; 17 | 18 | /// Opaque Aspect Token that allows to deregister the hook. 19 | @protocol AspectToken 20 | 21 | /// Deregisters an aspect. 22 | /// @return YES if deregistration is successful, otherwise NO. 23 | - (BOOL)remove; 24 | 25 | @end 26 | 27 | /// The AspectInfo protocol is the first parameter of our block syntax. 28 | @protocol AspectInfo 29 | 30 | /// The instance that is currently hooked. 31 | - (id)instance; 32 | 33 | /// The original invocation of the hooked method. 34 | - (NSInvocation *)originalInvocation; 35 | 36 | /// All method arguments, boxed. This is lazily evaluated. 37 | - (NSArray *)arguments; 38 | 39 | @end 40 | 41 | /** 42 | Aspects uses Objective-C message forwarding to hook into messages. This will create some overhead. Don't add aspects to methods that are called a lot. Aspects is meant for view/controller code that is not called a 1000 times per second. 43 | 44 | Adding aspects returns an opaque token which can be used to deregister again. All calls are thread safe. 45 | */ 46 | @interface NSObject (Aspects) 47 | 48 | /// Adds a block of code before/instead/after the current `selector` for a specific class. 49 | /// 50 | /// @param block Aspects replicates the type signature of the method being hooked. 51 | /// The first parameter will be `id`, followed by all parameters of the method. 52 | /// These parameters are optional and will be filled to match the block signature. 53 | /// You can even use an empty block, or one that simple gets `id`. 54 | /// 55 | /// @note Hooking static methods is not supported. 56 | /// @return A token which allows to later deregister the aspect. 57 | + (id)aspect_hookSelector:(SEL)selector 58 | withOptions:(AspectOptions)options 59 | usingBlock:(id)block 60 | error:(NSError **)error; 61 | 62 | /// Adds a block of code before/instead/after the current `selector` for a specific instance. 63 | - (id)aspect_hookSelector:(SEL)selector 64 | withOptions:(AspectOptions)options 65 | usingBlock:(id)block 66 | error:(NSError **)error; 67 | 68 | @end 69 | 70 | 71 | typedef NS_ENUM(NSUInteger, AspectErrorCode) { 72 | AspectErrorSelectorBlacklisted, /// Selectors like release, retain, autorelease are blacklisted. 73 | AspectErrorDoesNotRespondToSelector, /// Selector could not be found. 74 | AspectErrorSelectorDeallocPosition, /// When hooking dealloc, only AspectPositionBefore is allowed. 75 | AspectErrorSelectorAlreadyHookedInClassHierarchy, /// Statically hooking the same method in subclasses is not allowed. 76 | AspectErrorFailedToAllocateClassPair, /// The runtime failed creating a class pair. 77 | AspectErrorMissingBlockSignature, /// The block misses compile time signature info and can't be called. 78 | AspectErrorIncompatibleBlockSignature, /// The block signature does not match the method or is too large. 79 | 80 | AspectErrorRemoveObjectAlreadyDeallocated = 100 /// (for removing) The object hooked is already deallocated. 81 | }; 82 | 83 | extern NSString *const AspectErrorDomain; 84 | -------------------------------------------------------------------------------- /OCEval/helper/FuntionSearch.h: -------------------------------------------------------------------------------- 1 | // 2 | // FuntionSearch.h 3 | // OCEvalDemo 4 | // 5 | // Created by sgcy on 2018/11/23. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #ifndef FuntionSearch_h 10 | #define FuntionSearch_h 11 | 12 | #include 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif //__cplusplus 18 | 19 | 20 | struct Function { 21 | const char *name; 22 | void **pointer; 23 | }; 24 | 25 | int find_function(struct Function functions[], size_t fcuntion_nel); 26 | 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif //__cplusplus 31 | #endif //fishhook_h 32 | -------------------------------------------------------------------------------- /OCEval/helper/NSValue+struct.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSValue+struct.h 3 | // OCEval 4 | // 5 | // Created by sgcy on 2018/11/27. 6 | // 7 | 8 | #if TARGET_OS_IPHONE 9 | @import UIKit; 10 | #else 11 | @import AppKit; 12 | #endif 13 | 14 | 15 | @interface NSValue(structt) 16 | 17 | //CGPoint,CGSize,CGRect 18 | - (id)setX:(CGFloat)x; 19 | - (CGFloat)x; 20 | - (id)setY:(CGFloat)y; 21 | - (CGFloat)y; 22 | 23 | - (id)setWidth:(CGFloat)width; 24 | - (CGFloat)width; 25 | - (id)setHeight:(CGFloat)height; 26 | - (CGFloat)height; 27 | 28 | - (id)setOrigin:(CGPoint)origin; 29 | - (id)setSize:(CGSize)size; 30 | - (CGPoint)origin; 31 | - (CGSize)size; 32 | 33 | //NSRange 34 | - (id)setLocation:(NSUInteger)location; 35 | - (NSUInteger)location; 36 | - (id)setLength:(NSUInteger)length; 37 | - (NSUInteger)length; 38 | 39 | //UIOffset 40 | - (id)setHorizontal:(CGFloat)horizontal; 41 | - (CGFloat)horizontal; 42 | - (id)setVertical:(CGFloat)vertical; 43 | - (CGFloat)vertical; 44 | 45 | 46 | //UIEdgeInsets 47 | 48 | - (id)setTop:(CGFloat)top; 49 | - (CGFloat)top; 50 | - (id)setLeading:(CGFloat)leading; 51 | - (CGFloat)leading; 52 | - (id)setBottom:(CGFloat)bottom; 53 | - (CGFloat)bottom; 54 | - (id)setTrailing:(CGFloat)trailing; 55 | - (CGFloat)trailing; 56 | 57 | //NSDirectionalEdgeInsets 58 | //CGVector 59 | //CGAffineTransform 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /OCEval/helper/NSValue+struct.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSValue+struct.m 3 | // OCEval 4 | // 5 | // Created by sgcy on 2018/11/27. 6 | // 7 | 8 | 9 | #import "NSValue+struct.h" 10 | 11 | 12 | #if TARGET_OS_IPHONE 13 | #define pointValue [self CGPointValue] 14 | #define valueWithPoint(point) [NSValue valueWithCGPoint:point] 15 | #define sizeValue [self CGSizeValue] 16 | #define valueWithSize(size) [NSValue valueWithCGSize:size] 17 | #define rectValue [self CGRectValue] 18 | #define valueWithRect(rect) [NSValue valueWithCGRect:rect] 19 | 20 | #else 21 | #define pointValue [self pointValue] 22 | #define valueWithPoint(point) [NSValue valueWithPoint:point] 23 | #define sizeValue [self sizeValue] 24 | #define valueWithSize(size) [NSValue valueWithSize:size] 25 | #define rectValue [self rectValue] 26 | #define valueWithRect(rect) [NSValue valueWithRect:rect] 27 | 28 | #endif 29 | 30 | #define rangeValue [self rangeValue] 31 | #define valueWithRange(range) [NSValue valueWithRange:range] 32 | #define offsetValue [self UIOffsetValue] 33 | #define valueWithOffset(offset) [NSValue valueWithUIOffset:offset] 34 | 35 | @implementation NSValue(structt) 36 | 37 | //CGPoint,CGSize,CGRect 38 | - (id)setX:(CGFloat)x 39 | { 40 | return valueWithPoint(CGPointMake(x, pointValue.y)); 41 | } 42 | 43 | - (CGFloat)x 44 | { 45 | return pointValue.x; 46 | } 47 | 48 | - (id)setY:(CGFloat)y 49 | { 50 | return valueWithPoint(CGPointMake(pointValue.x, y)); 51 | } 52 | 53 | - (CGFloat)y 54 | { 55 | return pointValue.y; 56 | } 57 | 58 | - (id)setWidth:(CGFloat)width 59 | { 60 | return valueWithSize(CGSizeMake(width, sizeValue.width)); 61 | } 62 | 63 | - (CGFloat)width 64 | { 65 | return sizeValue.width; 66 | } 67 | 68 | - (id)setHeight:(CGFloat)height 69 | { 70 | return valueWithSize(CGSizeMake(sizeValue.width, height)); 71 | } 72 | 73 | - (CGFloat)height 74 | { 75 | return sizeValue.height; 76 | } 77 | 78 | - (id)setOrigin:(CGPoint)origin 79 | { 80 | return valueWithRect(CGRectMake(origin.x, origin.y, rectValue.size.width, rectValue.size.height)); 81 | } 82 | 83 | - (id)setSize:(CGSize)size 84 | { 85 | return valueWithRect(CGRectMake(rectValue.origin.x, rectValue.origin.y, size.width, size.height)); 86 | } 87 | 88 | - (CGPoint)origin 89 | { 90 | return rectValue.origin; 91 | } 92 | 93 | - (CGSize)size 94 | { 95 | return rectValue.size; 96 | } 97 | 98 | //NSRange 99 | - (id)setLocation:(NSUInteger)location 100 | { 101 | return valueWithRange(NSMakeRange(location, rangeValue.length)); 102 | } 103 | 104 | - (NSUInteger)location 105 | { 106 | return rangeValue.location; 107 | } 108 | 109 | - (id)setLength:(NSUInteger)length 110 | { 111 | return valueWithRange(NSMakeRange(rangeValue.location, length)); 112 | } 113 | 114 | - (NSUInteger)length 115 | { 116 | return rangeValue.length; 117 | } 118 | 119 | //UIOffset 120 | - (id)setHorizontal:(CGFloat)horizontal 121 | { 122 | #if TARGET_OS_IPHONE 123 | return valueWithOffset(UIOffsetMake(horizontal,offsetValue.vertical)); 124 | #endif 125 | return nil; 126 | } 127 | - (CGFloat)horizontal 128 | { 129 | #if TARGET_OS_IPHONE 130 | return offsetValue.horizontal; 131 | #endif 132 | return 0; 133 | } 134 | 135 | - (id)setVertical:(CGFloat)vertical 136 | { 137 | #if TARGET_OS_IPHONE 138 | return valueWithOffset(UIOffsetMake(offsetValue.horizontal,vertical)); 139 | #endif 140 | return nil; 141 | } 142 | - (CGFloat)vertical 143 | { 144 | #if TARGET_OS_IPHONE 145 | return offsetValue.vertical; 146 | #endif 147 | return 0; 148 | } 149 | 150 | 151 | ////UIEdgeInsets 152 | // 153 | //- (id)setTop:(CGFloat)top; 154 | //- (CGFloat)top; 155 | //- (id)setLeading:(CGFloat)leading; 156 | //- (CGFloat)leading; 157 | //- (id)setBottom:(CGFloat)bottom; 158 | //- (CGFloat)bottom; 159 | //- (id)setTrailing:(CGFloat)trailing; 160 | //- (CGFloat)trailing; 161 | 162 | 163 | @end 164 | -------------------------------------------------------------------------------- /OCEval/helper/OCBlockWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // JPBlockWrapper.h 3 | // JSPatch 4 | // 5 | // Created by bang on 1/19/17. 6 | // Copyright © 2017 bang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class OCBlockNode; 12 | 13 | @interface OCBlockWrapper : NSObject 14 | 15 | + (instancetype)blockWrapperWithNode:(OCBlockNode *)node; 16 | 17 | - (void *)blockPtrWithCtx:(NSDictionary *)ctx; 18 | 19 | + (id)excuteBlock:(id)block withParams:(NSArray *)params; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /OCEval/helper/OCCFuntionWrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCCFuntionWrapper.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/21. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #if TARGET_OS_IPHONE 10 | @import UIKit; 11 | #else 12 | @import AppKit; 13 | #endif 14 | 15 | @interface OCCFuntionWrapper : NSObject 16 | 17 | + (id)callCFunction:(NSString *)funcName arguments:(NSArray *)arguments; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /OCEval/helper/OCCFuntionWrapper.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCCFuntionWrapper.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/21. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | 10 | #import "OCCFuntionWrapper.h" 11 | #import "OCMethodNode+invoke.h" 12 | 13 | @implementation OCCFuntionWrapper 14 | 15 | + (id)callCFunction:(NSString *)funcName arguments:(NSArray *)arguments 16 | { 17 | funcName = [funcName stringByAppendingString:@":"]; 18 | return [OCMethodNode invokeWithCaller:self selectorName:funcName argments:@[arguments]]; 19 | } 20 | 21 | + (id)CGRectMake:(NSArray *)arguments 22 | { 23 | #if TARGET_OS_IPHONE 24 | return [NSValue valueWithCGRect:CGRectMake([arguments[0] doubleValue], [arguments[1] doubleValue], [arguments[2] doubleValue], [arguments[3] doubleValue])]; 25 | #else 26 | return [NSValue valueWithRect:CGRectMake([arguments[0] doubleValue], [arguments[1] doubleValue], [arguments[2] doubleValue], [arguments[3] doubleValue])]; 27 | #endif 28 | } 29 | 30 | + (id)CGRectZero:(NSArray *)arguments 31 | { 32 | #if TARGET_OS_IPHONE 33 | return [NSValue valueWithCGRect:CGRectZero]; 34 | #else 35 | return [NSValue valueWithRect:CGRectZero]; 36 | #endif 37 | } 38 | 39 | + (id)CGPointMake:(NSArray *)arguments 40 | { 41 | #if TARGET_OS_IPHONE 42 | return [NSValue valueWithCGPoint:CGPointMake([arguments[0] doubleValue], [arguments[1] doubleValue])]; 43 | #else 44 | return [NSValue valueWithPoint:CGPointMake([arguments[0] doubleValue], [arguments[1] doubleValue])]; 45 | #endif 46 | } 47 | 48 | + (id)CGPointZero:(NSArray *)arguments 49 | { 50 | #if TARGET_OS_IPHONE 51 | return [NSValue valueWithCGPoint:CGPointZero]; 52 | #else 53 | return [NSValue valueWithPoint:CGPointZero]; 54 | #endif 55 | } 56 | 57 | + (id)CGSizeMake:(NSArray *)arguments 58 | { 59 | #if TARGET_OS_IPHONE 60 | return [NSValue valueWithCGSize:CGSizeMake([arguments[0] doubleValue], [arguments[1] doubleValue])]; 61 | #else 62 | return [NSValue valueWithSize:CGSizeMake([arguments[0] doubleValue], [arguments[1] doubleValue])]; 63 | #endif 64 | } 65 | 66 | + (id)CGSizeZero:(NSArray *)arguments 67 | { 68 | #if TARGET_OS_IPHONE 69 | return [NSValue valueWithCGSize:CGSizeZero]; 70 | #else 71 | return [NSValue valueWithSize:CGSizeZero]; 72 | #endif 73 | } 74 | 75 | + (id)NSMakeRange:(NSArray *)arguments 76 | { 77 | return [NSValue valueWithRange:NSMakeRange([arguments[0] integerValue], [arguments[1] integerValue])]; 78 | } 79 | 80 | @end 81 | 82 | -------------------------------------------------------------------------------- /OCEval/helper/OCCfuntionHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCCfuntionHelper.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/20. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface OCCfuntionHelper : NSObject 14 | 15 | + (void)defineCFunction:(NSString *)funcName types:(NSString *)types; 16 | + (id)callCFunction:(NSString *)funcName arguments:(NSArray *)arguments; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /OCEval/helper/libffi/ffi.h: -------------------------------------------------------------------------------- 1 | #ifdef __arm64__ 2 | 3 | #include "ffi_arm64.h" 4 | 5 | 6 | #endif 7 | #ifdef __i386__ 8 | 9 | #include "ffi_i386.h" 10 | 11 | 12 | #endif 13 | #ifdef __arm__ 14 | 15 | #include "ffi_arm.h" 16 | 17 | 18 | #endif 19 | #ifdef __x86_64__ 20 | 21 | #include "ffi_x86_64.h" 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /OCEval/helper/libffi/ffitarget.h: -------------------------------------------------------------------------------- 1 | #ifdef __arm64__ 2 | 3 | #include "ffitarget_arm64.h" 4 | 5 | 6 | #endif 7 | #ifdef __i386__ 8 | 9 | #include "ffitarget_i386.h" 10 | 11 | 12 | #endif 13 | #ifdef __arm__ 14 | 15 | #include "ffitarget_arm.h" 16 | 17 | 18 | #endif 19 | #ifdef __x86_64__ 20 | 21 | #include "ffitarget_x86_64.h" 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /OCEval/helper/libffi/ffitarget_arm.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 2010 CodeSourcery 4 | Copyright (c) 1996-2003 Red Hat, Inc. 5 | 6 | Target configuration macros for ARM. 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining 9 | a copy of this software and associated documentation files (the 10 | ``Software''), to deal in the Software without restriction, including 11 | without limitation the rights to use, copy, modify, merge, publish, 12 | distribute, sublicense, and/or sell copies of the Software, and to 13 | permit persons to whom the Software is furnished to do so, subject to 14 | the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included 17 | in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | 28 | ----------------------------------------------------------------------- */ 29 | 30 | #ifndef LIBFFI_TARGET_H 31 | #define LIBFFI_TARGET_H 32 | 33 | #ifndef LIBFFI_H 34 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 35 | #endif 36 | 37 | #ifndef LIBFFI_ASM 38 | typedef unsigned long ffi_arg; 39 | typedef signed long ffi_sarg; 40 | 41 | typedef enum ffi_abi { 42 | FFI_FIRST_ABI = 0, 43 | FFI_SYSV, 44 | FFI_VFP, 45 | FFI_LAST_ABI, 46 | #ifdef __ARM_PCS_VFP 47 | FFI_DEFAULT_ABI = FFI_VFP, 48 | #else 49 | FFI_DEFAULT_ABI = FFI_SYSV, 50 | #endif 51 | } ffi_abi; 52 | #endif 53 | 54 | #define FFI_EXTRA_CIF_FIELDS \ 55 | int vfp_used; \ 56 | unsigned short vfp_reg_free, vfp_nargs; \ 57 | signed char vfp_args[16] \ 58 | 59 | #define FFI_TARGET_SPECIFIC_VARIADIC 60 | #define FFI_TARGET_HAS_COMPLEX_TYPE 61 | 62 | /* ---- Definitions for closures ----------------------------------------- */ 63 | 64 | #define FFI_CLOSURES 1 65 | #define FFI_GO_CLOSURES 1 66 | #define FFI_NATIVE_RAW_API 0 67 | 68 | #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE 69 | 70 | #ifdef __MACH__ 71 | #define FFI_TRAMPOLINE_SIZE 12 72 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET 8 73 | #else 74 | #error "No trampoline table implementation" 75 | #endif 76 | 77 | #else 78 | #define FFI_TRAMPOLINE_SIZE 12 79 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /OCEval/helper/libffi/ffitarget_arm64.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | ``Software''), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 21 | 22 | #ifndef LIBFFI_TARGET_H 23 | #define LIBFFI_TARGET_H 24 | 25 | #ifndef LIBFFI_H 26 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 27 | #endif 28 | 29 | #ifndef LIBFFI_ASM 30 | #ifdef __ILP32__ 31 | #define FFI_SIZEOF_ARG 8 32 | #define FFI_SIZEOF_JAVA_RAW 4 33 | typedef unsigned long long ffi_arg; 34 | typedef signed long long ffi_sarg; 35 | #else 36 | typedef unsigned long ffi_arg; 37 | typedef signed long ffi_sarg; 38 | #endif 39 | 40 | typedef enum ffi_abi 41 | { 42 | FFI_FIRST_ABI = 0, 43 | FFI_SYSV, 44 | FFI_LAST_ABI, 45 | FFI_DEFAULT_ABI = FFI_SYSV 46 | } ffi_abi; 47 | #endif 48 | 49 | /* ---- Definitions for closures ----------------------------------------- */ 50 | 51 | #define FFI_CLOSURES 1 52 | #define FFI_NATIVE_RAW_API 0 53 | 54 | #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE 55 | 56 | #ifdef __MACH__ 57 | #define FFI_TRAMPOLINE_SIZE 16 58 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16 59 | #else 60 | #error "No trampoline table implementation" 61 | #endif 62 | 63 | #else 64 | #define FFI_TRAMPOLINE_SIZE 24 65 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE 66 | #endif 67 | 68 | /* ---- Internal ---- */ 69 | 70 | #if defined (__APPLE__) 71 | #define FFI_TARGET_SPECIFIC_VARIADIC 72 | #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs 73 | #else 74 | /* iOS reserves x18 for the system. Disable Go closures until 75 | a new static chain is chosen. */ 76 | #define FFI_GO_CLOSURES 1 77 | #endif 78 | 79 | #define FFI_TARGET_HAS_COMPLEX_TYPE 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /OCEval/helper/libffi/ffitarget_i386.h: -------------------------------------------------------------------------------- 1 | #ifdef __i386__ 2 | 3 | /* -----------------------------------------------------------------*-C-*- 4 | ffitarget.h - Copyright (c) 2012, 2014 Anthony Green 5 | Copyright (c) 1996-2003, 2010 Red Hat, Inc. 6 | Copyright (C) 2008 Free Software Foundation, Inc. 7 | 8 | Target configuration macros for x86 and x86-64. 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining 11 | a copy of this software and associated documentation files (the 12 | ``Software''), to deal in the Software without restriction, including 13 | without limitation the rights to use, copy, modify, merge, publish, 14 | distribute, sublicense, and/or sell copies of the Software, and to 15 | permit persons to whom the Software is furnished to do so, subject to 16 | the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included 19 | in all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 22 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28 | DEALINGS IN THE SOFTWARE. 29 | 30 | ----------------------------------------------------------------------- */ 31 | 32 | #ifndef LIBFFI_TARGET_H 33 | #define LIBFFI_TARGET_H 34 | 35 | #ifndef LIBFFI_H 36 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 37 | #endif 38 | 39 | /* ---- System specific configurations ----------------------------------- */ 40 | 41 | /* For code common to all platforms on x86 and x86_64. */ 42 | #define X86_ANY 43 | 44 | #if defined (X86_64) && defined (__i386__) 45 | #undef X86_64 46 | #define X86 47 | #endif 48 | 49 | #ifdef X86_WIN64 50 | #define FFI_SIZEOF_ARG 8 51 | #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */ 52 | #endif 53 | 54 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 55 | #define FFI_TARGET_HAS_COMPLEX_TYPE 56 | 57 | /* ---- Generic type definitions ----------------------------------------- */ 58 | 59 | #ifndef LIBFFI_ASM 60 | #ifdef X86_WIN64 61 | #ifdef _MSC_VER 62 | typedef unsigned __int64 ffi_arg; 63 | typedef __int64 ffi_sarg; 64 | #else 65 | typedef unsigned long long ffi_arg; 66 | typedef long long ffi_sarg; 67 | #endif 68 | #else 69 | #if defined __x86_64__ && defined __ILP32__ 70 | #define FFI_SIZEOF_ARG 8 71 | #define FFI_SIZEOF_JAVA_RAW 4 72 | typedef unsigned long long ffi_arg; 73 | typedef long long ffi_sarg; 74 | #else 75 | typedef unsigned long ffi_arg; 76 | typedef signed long ffi_sarg; 77 | #endif 78 | #endif 79 | 80 | typedef enum ffi_abi { 81 | FFI_FIRST_ABI = 0, 82 | 83 | /* ---- Intel x86 Win32 ---------- */ 84 | #ifdef X86_WIN32 85 | FFI_SYSV, 86 | FFI_STDCALL, 87 | FFI_THISCALL, 88 | FFI_FASTCALL, 89 | FFI_MS_CDECL, 90 | FFI_PASCAL, 91 | FFI_REGISTER, 92 | FFI_LAST_ABI, 93 | #ifdef _MSC_VER 94 | FFI_DEFAULT_ABI = FFI_MS_CDECL 95 | #else 96 | FFI_DEFAULT_ABI = FFI_SYSV 97 | #endif 98 | 99 | #elif defined(X86_WIN64) 100 | FFI_WIN64, 101 | FFI_LAST_ABI, 102 | FFI_DEFAULT_ABI = FFI_WIN64 103 | 104 | #else 105 | /* ---- Intel x86 and AMD x86-64 - */ 106 | FFI_SYSV, 107 | FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ 108 | FFI_THISCALL, 109 | FFI_FASTCALL, 110 | FFI_STDCALL, 111 | FFI_PASCAL, 112 | FFI_REGISTER, 113 | FFI_LAST_ABI, 114 | #if defined(__i386__) || defined(__i386) 115 | FFI_DEFAULT_ABI = FFI_SYSV 116 | #else 117 | FFI_DEFAULT_ABI = FFI_UNIX64 118 | #endif 119 | #endif 120 | } ffi_abi; 121 | #endif 122 | 123 | /* ---- Definitions for closures ----------------------------------------- */ 124 | 125 | #define FFI_CLOSURES 1 126 | #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) 127 | #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2) 128 | #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3) 129 | #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4) 130 | 131 | #if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) 132 | #define FFI_TRAMPOLINE_SIZE 24 133 | #define FFI_NATIVE_RAW_API 0 134 | #else 135 | #ifdef X86_WIN32 136 | #define FFI_TRAMPOLINE_SIZE 52 137 | #else 138 | #ifdef X86_WIN64 139 | #define FFI_TRAMPOLINE_SIZE 29 140 | #define FFI_NATIVE_RAW_API 0 141 | #define FFI_NO_RAW_API 1 142 | #else 143 | #define FFI_TRAMPOLINE_SIZE 10 144 | #endif 145 | #endif 146 | #ifndef X86_WIN64 147 | #define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ 148 | #endif 149 | #endif 150 | 151 | #endif 152 | 153 | 154 | 155 | #endif -------------------------------------------------------------------------------- /OCEval/helper/libffi/ffitarget_x86_64.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012, 2014 Anthony Green 3 | Copyright (c) 1996-2003, 2010 Red Hat, Inc. 4 | Copyright (C) 2008 Free Software Foundation, Inc. 5 | 6 | Target configuration macros for x86 and x86-64. 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining 9 | a copy of this software and associated documentation files (the 10 | ``Software''), to deal in the Software without restriction, including 11 | without limitation the rights to use, copy, modify, merge, publish, 12 | distribute, sublicense, and/or sell copies of the Software, and to 13 | permit persons to whom the Software is furnished to do so, subject to 14 | the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included 17 | in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | 28 | ----------------------------------------------------------------------- */ 29 | 30 | #ifndef LIBFFI_TARGET_H 31 | #define LIBFFI_TARGET_H 32 | 33 | #ifndef LIBFFI_H 34 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 35 | #endif 36 | 37 | /* ---- System specific configurations ----------------------------------- */ 38 | 39 | /* For code common to all platforms on x86 and x86_64. */ 40 | #define X86_ANY 41 | 42 | #if defined (X86_64) && defined (__i386__) 43 | #undef X86_64 44 | #define X86 45 | #endif 46 | 47 | #ifdef X86_WIN64 48 | #define FFI_SIZEOF_ARG 8 49 | #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */ 50 | #endif 51 | 52 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 53 | #ifndef _MSC_VER 54 | #define FFI_TARGET_HAS_COMPLEX_TYPE 55 | #endif 56 | 57 | /* ---- Generic type definitions ----------------------------------------- */ 58 | 59 | #ifndef LIBFFI_ASM 60 | #ifdef X86_WIN64 61 | #ifdef _MSC_VER 62 | typedef unsigned __int64 ffi_arg; 63 | typedef __int64 ffi_sarg; 64 | #else 65 | typedef unsigned long long ffi_arg; 66 | typedef long long ffi_sarg; 67 | #endif 68 | #else 69 | #if defined __x86_64__ && defined __ILP32__ 70 | #define FFI_SIZEOF_ARG 8 71 | #define FFI_SIZEOF_JAVA_RAW 4 72 | typedef unsigned long long ffi_arg; 73 | typedef long long ffi_sarg; 74 | #else 75 | typedef unsigned long ffi_arg; 76 | typedef signed long ffi_sarg; 77 | #endif 78 | #endif 79 | 80 | typedef enum ffi_abi { 81 | #if defined(X86_WIN64) 82 | FFI_FIRST_ABI = 0, 83 | FFI_WIN64, 84 | FFI_LAST_ABI, 85 | FFI_DEFAULT_ABI = FFI_WIN64 86 | 87 | #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) 88 | FFI_FIRST_ABI = 1, 89 | FFI_UNIX64, 90 | FFI_WIN64, 91 | FFI_EFI64 = FFI_WIN64, 92 | FFI_LAST_ABI, 93 | FFI_DEFAULT_ABI = FFI_UNIX64 94 | 95 | #elif defined(X86_WIN32) 96 | FFI_FIRST_ABI = 0, 97 | FFI_SYSV = 1, 98 | FFI_STDCALL = 2, 99 | FFI_THISCALL = 3, 100 | FFI_FASTCALL = 4, 101 | FFI_MS_CDECL = 5, 102 | FFI_PASCAL = 6, 103 | FFI_REGISTER = 7, 104 | FFI_LAST_ABI, 105 | FFI_DEFAULT_ABI = FFI_MS_CDECL 106 | #else 107 | FFI_FIRST_ABI = 0, 108 | FFI_SYSV = 1, 109 | FFI_THISCALL = 3, 110 | FFI_FASTCALL = 4, 111 | FFI_STDCALL = 5, 112 | FFI_PASCAL = 6, 113 | FFI_REGISTER = 7, 114 | FFI_MS_CDECL = 8, 115 | FFI_LAST_ABI, 116 | FFI_DEFAULT_ABI = FFI_SYSV 117 | #endif 118 | } ffi_abi; 119 | #endif 120 | 121 | /* ---- Definitions for closures ----------------------------------------- */ 122 | 123 | #define FFI_CLOSURES 1 124 | #define FFI_GO_CLOSURES 1 125 | 126 | #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) 127 | #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2) 128 | #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3) 129 | #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4) 130 | 131 | #if defined (X86_64) || defined(X86_WIN64) \ 132 | || (defined (__x86_64__) && defined (X86_DARWIN)) 133 | # define FFI_TRAMPOLINE_SIZE 24 134 | # define FFI_NATIVE_RAW_API 0 135 | #else 136 | # define FFI_TRAMPOLINE_SIZE 12 137 | # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ 138 | #endif 139 | 140 | #endif 141 | 142 | -------------------------------------------------------------------------------- /OCEval/helper/libffi/libffi.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilidan/OCEval/19acf3a3cf36cc0f28b455e8d2ee202a5b67157a/OCEval/helper/libffi/libffi.a -------------------------------------------------------------------------------- /OCEval/lexer/OCLexer.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCLexer.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/14. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #if TARGET_OS_IPHONE 10 | @import UIKit; 11 | #else 12 | @import AppKit; 13 | #endif 14 | 15 | @class OCToken; 16 | @class OCLexer; 17 | 18 | @interface OCLexer : NSObject 19 | 20 | @property (nonatomic, copy) NSString *string; 21 | @property (nonatomic, readonly) NSUInteger lineNumber; 22 | 23 | + (OCLexer *)lexer; 24 | + (OCLexer *)lexerWithString:(NSString *)s; 25 | - (instancetype)initWithString:(NSString *)s; 26 | 27 | - (OCToken *)nextToken; 28 | 29 | - (NSArray *)allTokens; 30 | - (NSArray *)allTokens:(BOOL)withWhiteSpace; 31 | 32 | @end 33 | 34 | -------------------------------------------------------------------------------- /OCEval/lexer/OCReader.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCReader.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/14. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface OCReader : NSObject 12 | 13 | @property (nonatomic, copy) NSString *string; 14 | @property (nonatomic, readonly) NSUInteger offset; 15 | 16 | - (instancetype)initWithString:(NSString *)s; 17 | 18 | - (char)read; 19 | 20 | - (void)unread; 21 | - (void)unread:(NSUInteger)count; 22 | 23 | - (NSString *)debugDescription; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /OCEval/lexer/OCReader.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCReader.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/14. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCReader.h" 10 | 11 | @interface OCReader() 12 | 13 | @property (nonatomic) NSUInteger offset; 14 | @property (nonatomic) NSUInteger length; 15 | 16 | @end 17 | 18 | 19 | @implementation OCReader 20 | 21 | 22 | - (instancetype)initWithString:(NSString *)s { 23 | self = [super init]; 24 | if (self) { 25 | self.string = s; 26 | } 27 | return self; 28 | } 29 | 30 | - (NSString *)debugDescription { 31 | NSString *buff = [NSString stringWithFormat:@"%@^%@", [_string substringToIndex:_offset], [_string substringFromIndex:_offset]]; 32 | return [NSString stringWithFormat:@"<%@ %p `%@`>", [self class], self, buff]; 33 | } 34 | 35 | - (void)setString:(NSString *)s { 36 | NSAssert(s, @"s != nil"); 37 | 38 | if (_string != s) { 39 | _string = [s copy]; 40 | self.length = [_string length]; 41 | } 42 | // reset cursor 43 | self.offset = 0; 44 | } 45 | 46 | 47 | - (char)read { 48 | char result = EOF; 49 | 50 | if (_length && _offset < _length) { 51 | result = [_string characterAtIndex:self.offset]; 52 | } 53 | self.offset ++; 54 | return result; 55 | } 56 | 57 | 58 | - (void)unread { 59 | self.offset = (0 == _offset) ? 0 : _offset - 1; 60 | } 61 | 62 | 63 | - (void)unread:(NSUInteger)count { 64 | for (NSUInteger i = 0; i < count; i++) { 65 | [self unread]; 66 | } 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /OCEval/lexer/OCToken.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCToken.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/14. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, OCTokenType) { 12 | OCTokenTypeEOF = 0, 13 | OCTokenTypeNumber = 1, 14 | OCTokenTypeString = 2, 15 | OCTokenTypeSymbol = 3, 16 | OCTokenTypeWord = 4, 17 | OCTokenTypeWhitespace = 5, 18 | OCTokenTypeComment = 6 19 | }; 20 | 21 | #define SUB_TYPES @[@"if",@"else",@"do",@"while",@"for",@"in",@"continue",@"break",@"return",@"selector",@"self",@"super",@"nil",@"YES",@"NO",@"__weak",@"__strong",@"__block",@"_Nonnull",@"_Nullable",\ 22 | @"(",@")",@"[",@"]",@"{",@"}",@";",@"=",@".",@",",@":",@"+",@"-",@"*",@"/",@"&",@"|",@"!",@">",@">=",@"<",@"<=",@"==",@"!=",@"&&",@"||",@"@",@"^",@"++",@"--",@"+=",@"-="\ 23 | ] 24 | 25 | typedef NS_ENUM(NSUInteger, OCTokenSubType) { 26 | OCTokenSubTypeNone = 0, 27 | OCWordSubTypeIf, 28 | OCWordSubTypeElse, 29 | OCWordSubTypeDo, 30 | OCWordSubTypeWhile, 31 | OCWordSubTypeFor, 32 | OCWordSubTypeIn, 33 | OCWordSubTypeContinue, 34 | OCWordSubTypeBreak, 35 | OCWordSubTypeReturn, 36 | OCWordSubTypeSelector, 37 | OCWordSubTypeSelf, 38 | OCWordSubTypeSuper, 39 | OCWordSubTypeNil, 40 | OCWordSubTypeYES, 41 | OCWordSubTypeNO, 42 | OCWordSubTypeWeak, 43 | OCWordSubTypeStrong, 44 | OCWordSubTypeBlock, 45 | OCWordSubTypeNonnull, 46 | OCWordSubTypenullable, 47 | // 48 | OCSymbolSubTypeLeftParen, 49 | OCSymbolSubTypeRightParen, 50 | OCSymbolSubTypeLeftSquare, 51 | OCSymbolSubTypeRightSquare, 52 | OCSymbolSubTypeLeftBrace, 53 | OCSymbolSubTypeRightBrace, 54 | OCSymbolSubTypeSemi, 55 | OCSymbolSubTypeEqual, 56 | OCSymbolSubTypePoint, 57 | OCSymbolSubTypeComma, 58 | OCSymbolSubTypeColon, 59 | OCSymbolSubTypeAdd, 60 | OCSymbolSubTypeMinus, 61 | OCSymbolSubTypeStar, 62 | OCSymbolSubTypeSlash, 63 | OCSymbolSubTypeAmp, 64 | OCSymbolSubTypePipe, 65 | OCSymbolSubTypeExclaim, 66 | OCSymbolSubTypeGreaterThan, 67 | OCSymbolSubTypeGreaterThanOrEqual, 68 | OCSymbolSubTypeLessThan, 69 | OCSymbolSubTypeLessThanOrEqual, 70 | OCSymbolSubTypeEqualEqual, 71 | OCSymbolSubTypeExclaimEqual, 72 | OCSymbolSubTypeAmpAmp, 73 | OCSymbolSubTypePipepipe, 74 | OCSymbolSubTypeAt, 75 | OCSymbolSubTypeCaret, 76 | OCSymbolSubTypeAddAdd, 77 | OCSymbolSubTypeMinusMinus, 78 | OCSymbolSubTypeAddEqual, 79 | OCSymbolSubTypeMinusEqual, 80 | }; 81 | 82 | 83 | 84 | @interface OCToken : NSObject 85 | 86 | @property (nonatomic, readonly) OCTokenType tokenType; 87 | @property (nonatomic, assign) OCTokenSubType tokenSubType; 88 | 89 | @property (nonatomic, readonly) double doubleValue; 90 | @property (nonatomic, readonly, copy) NSString *stringValue; 91 | @property (nonatomic, readonly, copy) id value; 92 | 93 | @property (nonatomic, assign) NSUInteger offset; 94 | @property (nonatomic, assign) NSUInteger lineNumber; 95 | 96 | + (OCToken *)EOFToken; 97 | 98 | + (instancetype)tokenWithTokenType:(OCTokenType)t stringValue:(NSString *)s doubleValue:(double)n; 99 | - (instancetype)initWithTokenType:(OCTokenType)t stringValue:(NSString *)s doubleValue:(double)n; 100 | 101 | - (BOOL)isEqualIgnoringCase:(id)obj; 102 | 103 | - (NSString *)debugDescription; 104 | 105 | @end 106 | 107 | -------------------------------------------------------------------------------- /OCEval/lexer/OCToken.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCToken.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/14. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCToken.h" 10 | 11 | @interface OCTokenEOF : OCToken 12 | 13 | @property (nonatomic,strong) NSDictionary *subTypeDictionary; 14 | + (OCTokenEOF *)instance; 15 | 16 | @end 17 | 18 | @implementation OCTokenEOF 19 | 20 | static OCTokenEOF *EOFToken = nil; 21 | 22 | + (OCTokenEOF *)instance { 23 | @synchronized(self) { 24 | if (!EOFToken) { 25 | EOFToken = [[self alloc] initWithTokenType:OCTokenTypeEOF stringValue:@"«EOF»" doubleValue:0.0]; 26 | NSMutableDictionary *mutDic = [NSMutableDictionary dictionary]; 27 | [SUB_TYPES enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 28 | [mutDic setObject:@(idx + 1) forKey:obj]; 29 | }]; 30 | EOFToken.subTypeDictionary = [mutDic copy]; 31 | } 32 | } 33 | return EOFToken; 34 | } 35 | - (NSString *)description { 36 | return [self stringValue]; 37 | } 38 | - (NSString *)debugDescription { 39 | return [self description]; 40 | } 41 | 42 | @end 43 | 44 | @interface OCToken () 45 | 46 | - (BOOL)isEqual:(id)obj ignoringCase:(BOOL)ignoringCase; 47 | 48 | @property (nonatomic, readwrite) double doubleValue; 49 | @property (nonatomic, readwrite, copy) NSString *stringValue; 50 | @property (nonatomic, readwrite) OCTokenType tokenType; 51 | @property (nonatomic, readwrite, copy) id value; 52 | 53 | @end 54 | 55 | @implementation OCToken 56 | 57 | + (OCToken *)EOFToken { 58 | return [OCTokenEOF instance]; 59 | } 60 | 61 | 62 | + (instancetype)tokenWithTokenType:(OCTokenType)t stringValue:(NSString *)s doubleValue:(double)n { 63 | return [[self alloc] initWithTokenType:t stringValue:s doubleValue:n]; 64 | } 65 | 66 | 67 | // designated initializer 68 | - (instancetype)initWithTokenType:(OCTokenType)t stringValue:(NSString *)s doubleValue:(double)n { 69 | //NSParameterAssert(s); 70 | self = [super init]; 71 | if (self) { 72 | self.tokenType = t; 73 | self.stringValue = s; 74 | self.doubleValue = n; 75 | self.offset = NSNotFound; 76 | self.lineNumber = NSNotFound; 77 | if (t == OCTokenTypeWord || t == OCTokenTypeSymbol) { 78 | NSNumber *subType = [[OCTokenEOF instance].subTypeDictionary objectForKey:s]; 79 | if (subType) { 80 | self.tokenSubType = [subType integerValue]; 81 | } 82 | } 83 | } 84 | return self; 85 | } 86 | 87 | 88 | - (NSUInteger)hash { 89 | return [_stringValue hash]; 90 | } 91 | 92 | 93 | - (BOOL)isEqual:(id)obj { 94 | return [self isEqual:obj ignoringCase:NO]; 95 | } 96 | 97 | 98 | - (BOOL)isEqualIgnoringCase:(id)obj { 99 | return [self isEqual:obj ignoringCase:YES]; 100 | } 101 | 102 | 103 | - (BOOL)isEqual:(id)obj ignoringCase:(BOOL)ignoringCase { 104 | if (![obj isMemberOfClass:[OCToken class]]) { 105 | return NO; 106 | } 107 | 108 | OCToken *tok = (OCToken *)obj; 109 | if (_tokenType != tok->_tokenType) { 110 | return NO; 111 | } 112 | 113 | if (self.tokenType == OCTokenTypeNumber) { 114 | return _doubleValue == tok->_doubleValue; 115 | } else { 116 | if (ignoringCase) { 117 | return (NSOrderedSame == [_stringValue caseInsensitiveCompare:tok->_stringValue]); 118 | } else { 119 | return [_stringValue isEqualToString:tok->_stringValue]; 120 | } 121 | } 122 | } 123 | 124 | 125 | - (BOOL)isEOF { 126 | return NO; 127 | } 128 | 129 | 130 | - (id)value { 131 | if (!_value) { 132 | id v = nil; 133 | if (self.tokenType == OCTokenTypeNumber) { 134 | v = [NSNumber numberWithDouble:_doubleValue]; 135 | } else { 136 | v = _stringValue; 137 | } 138 | self.value = v; 139 | } 140 | return _value; 141 | } 142 | 143 | 144 | - (NSString *)debugDescription { 145 | NSString *typeString = [@(self.tokenType) stringValue]; 146 | return [NSString stringWithFormat:@"%@ %C%@%C", typeString, (unichar)0x00AB, self.value, (unichar)0x00BB]; 147 | } 148 | 149 | 150 | - (NSString *)description { 151 | NSArray *types = @[@"EOF",@"Number",@"String",@"Symbol",@"Word",@"WhiteSpace",@"Comment"]; 152 | return [NSString stringWithFormat:@"%@ - %@ - ", types[self.tokenType], self.value]; 153 | } 154 | 155 | 156 | @end 157 | -------------------------------------------------------------------------------- /OCEval/lexer/OCTokenReader.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCTokenReader.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class OCToken; 12 | 13 | @interface OCTokenReader : NSObject 14 | 15 | @property (nonatomic, copy) NSArray *tokens; 16 | @property (nonatomic, readonly) NSUInteger offset; 17 | 18 | - (instancetype)initWithTokens:(NSArray *)tokens; 19 | 20 | - (OCToken *)current; 21 | - (OCToken *)read; 22 | 23 | - (void)unread; 24 | - (void)unread:(NSUInteger)count; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /OCEval/lexer/OCTokenReader.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCTokenReader.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCTokenReader.h" 10 | #import "OCToken.h" 11 | 12 | @interface OCTokenReader() 13 | 14 | @property (nonatomic) NSUInteger offset; 15 | @property (nonatomic) NSUInteger length; 16 | 17 | @end 18 | 19 | 20 | @implementation OCTokenReader 21 | 22 | 23 | - (instancetype)initWithTokens:(NSArray *)tokens 24 | { 25 | if (self = [super init]) { 26 | self.tokens = tokens; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)setTokens:(NSArray *)tokens 32 | { 33 | _tokens = tokens; 34 | _length = tokens.count; 35 | _offset = 0; 36 | } 37 | 38 | - (OCToken *)read 39 | { 40 | OCToken *result = [OCToken EOFToken]; 41 | if (_length && _offset < _length) { 42 | result = [self.tokens objectAtIndex:self.offset]; 43 | } 44 | self.offset ++; 45 | // NSLog(@"READ:%@",result.value); 46 | return result; 47 | } 48 | 49 | - (OCToken *)current 50 | { 51 | OCToken *result = [OCToken EOFToken]; 52 | if (_length && _offset < _length) { 53 | result = [self.tokens objectAtIndex:self.offset]; 54 | } 55 | return result; 56 | } 57 | 58 | - (void)unread { 59 | self.offset = (0 == _offset) ? 0 : _offset - 1; 60 | } 61 | 62 | - (void)unread:(NSUInteger)count { 63 | for (NSUInteger i = 0; i < count; i++) { 64 | [self unread]; 65 | } 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /OCEval/parser/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilidan/OCEval/19acf3a3cf36cc0f28b455e8d2ee202a5b67157a/OCEval/parser/.DS_Store -------------------------------------------------------------------------------- /OCEval/parser/OCBlockNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCBlockNode.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/19. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCNode.h" 10 | 11 | @interface OCBlockNode : OCNode 12 | 13 | @property (nonatomic,strong) NSMutableArray *typeNames; 14 | @property (nonatomic,strong) NSMutableArray *paramNames; 15 | 16 | @end 17 | 18 | @interface OCBlockCallNode : OCNode 19 | 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /OCEval/parser/OCBlockNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCBlockNode.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/19. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCBlockNode.h" 10 | #import "OCToken.h" 11 | #import "OCScopeNode.h" 12 | #import "OCBlockWrapper.h" 13 | #import "OCReturnNode.h" 14 | #import "OCMethodNode+invoke.h" 15 | #import "OCCfuntionHelper.h" 16 | 17 | @interface OCBlockNode() 18 | 19 | @property (nonatomic,strong) OCBlockWrapper *wrapper; 20 | 21 | @end 22 | 23 | @implementation OCBlockNode 24 | 25 | 26 | - (instancetype)initWithReader:(OCTokenReader *)reader 27 | { 28 | if (self = [super initWithReader:reader]) { 29 | _typeNames = [[NSMutableArray alloc] init]; 30 | _paramNames = [[NSMutableArray alloc] init]; 31 | [reader read]; 32 | [self read]; 33 | } 34 | return self; 35 | } 36 | 37 | - (void)read 38 | { 39 | OCToken *current = [self.reader read]; 40 | if (current.tokenType == OCTokenTypeWord) { 41 | [self.typeNames addObject:current.value]; 42 | current = [self.reader read]; 43 | }else{ 44 | [self.typeNames addObject:@"void"]; 45 | } 46 | NSAssert(current.tokenSubType == OCSymbolSubTypeLeftParen, nil); 47 | [self readParam]; 48 | [self addChild:[[OCScopeNode alloc] initWithReader:self.reader]]; 49 | self.wrapper = [OCBlockWrapper blockWrapperWithNode:self]; //won't be a retain cycle. 50 | } 51 | 52 | - (void)readParam 53 | { 54 | OCToken *current = [self.reader read]; 55 | if (current.tokenSubType == OCSymbolSubTypeRightParen) { 56 | return; 57 | }else if (current.tokenSubType == OCSymbolSubTypeComma){ 58 | [self readParam]; 59 | }else{ 60 | [self.typeNames addObject:current.value]; 61 | current = [self.reader read]; 62 | while (current.tokenSubType == OCSymbolSubTypeStar || current.tokenSubType == OCWordSubTypeNonnull || current.tokenSubType == OCWordSubTypenullable) { 63 | current = [self.reader read]; 64 | } 65 | NSAssert(current.tokenType == OCTokenTypeWord, nil); 66 | [self.paramNames addObject:current.value]; 67 | [self readParam]; 68 | } 69 | } 70 | 71 | - (id)excuteWithCtx:(NSDictionary *)ctx 72 | { 73 | return [self.wrapper blockPtrWithCtx:ctx]; 74 | } 75 | 76 | @end 77 | 78 | @interface OCBlockCallNode() 79 | 80 | @property (nonatomic,strong) NSString *blockName; 81 | 82 | @end 83 | 84 | 85 | @implementation OCBlockCallNode 86 | 87 | - (instancetype)initWithReader:(OCTokenReader *)reader 88 | { 89 | self = [super initWithReader:reader]; 90 | self.blockName = [reader read].value; 91 | NSAssert([reader read].tokenSubType == OCSymbolSubTypeLeftParen, nil); 92 | while (!self.isFinished) { 93 | [self read]; 94 | } 95 | return self; 96 | } 97 | 98 | - (void)read 99 | { 100 | OCToken *token = [self.reader read]; 101 | if (token.tokenSubType == OCSymbolSubTypeRightParen) { 102 | self.finished = YES; 103 | return; 104 | }else if (token.tokenSubType == OCSymbolSubTypeComma){ 105 | return; 106 | } 107 | [self.reader unread]; 108 | [self addChild:[[OCReturnNode alloc] initWithReader:self.reader]]; 109 | } 110 | 111 | - (id)excuteWithCtx:(NSDictionary *)ctx 112 | { 113 | id block = [ctx valueForKey:self.blockName]; 114 | NSMutableArray *argumentsList = [[NSMutableArray alloc] init]; 115 | [self.children enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 116 | id result = [obj excuteWithCtx:ctx]; 117 | if (result == nil) { 118 | result = [OCMethodNode nilObj]; 119 | } 120 | [argumentsList addObject:result]; 121 | }]; 122 | if (block) { // call block 123 | return [OCBlockWrapper excuteBlock:block withParams:[argumentsList copy]]; 124 | }else{ // call C funtion 125 | return [OCCfuntionHelper callCFunction:self.blockName arguments:[argumentsList copy]]; 126 | } 127 | 128 | } 129 | 130 | @end 131 | -------------------------------------------------------------------------------- /OCEval/parser/OCControlNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCControlNode.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCNode.h" 10 | 11 | typedef NS_ENUM(NSUInteger, OCControlNodeType) { 12 | OCControlNodeTypeIfElse = 0, 13 | OCControlNodeTypeDoWhile = 1, 14 | OCControlNodeTypeForIn = 2, 15 | OCControlNodeTypeSwitchCase = 3, 16 | }; 17 | 18 | @interface OCControlNode : OCNode 19 | 20 | 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /OCEval/parser/OCControlNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCControlNode.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCControlNode.h" 10 | #import "OCToken.h" 11 | #import "OCReturnNode.h" 12 | #import "OCScopeNode.h" 13 | #import "OCIterateNode.h" 14 | 15 | @interface OCControlNode() 16 | 17 | @property (nonatomic,strong) NSMutableArray *logics; 18 | @property (nonatomic,strong) NSMutableArray *expressions; 19 | 20 | @end 21 | 22 | @implementation OCControlNode 23 | 24 | - (instancetype)initWithReader:(OCTokenReader *)reader 25 | { 26 | if (self = [super initWithReader:reader]) { 27 | _expressions = [[NSMutableArray alloc] init]; 28 | _logics = [[NSMutableArray alloc] init]; 29 | while (!self.isFinished) { 30 | [self read]; 31 | } 32 | } 33 | return self; 34 | } 35 | 36 | - (void)readIf 37 | { 38 | [self.logics addObject:@(OCWordSubTypeIf)]; 39 | OCReturnNode *returnNode = [[OCReturnNode alloc] initWithReader:self.reader]; 40 | [self.expressions addObject:returnNode]; 41 | [self addChild:[[OCScopeNode alloc] initWithReader:self.reader]]; 42 | } 43 | 44 | - (void)readElse 45 | { 46 | [self.logics addObject:@(OCWordSubTypeElse)]; 47 | [self.expressions addObject:[NSNull null]]; 48 | [self addChild:[[OCScopeNode alloc] initWithReader:self.reader]]; 49 | } 50 | 51 | - (void)readFor 52 | { 53 | [self.logics addObject:@(OCWordSubTypeFor)]; 54 | [self.expressions addObject:[OCIterateNode nodeWithReader:self.reader]]; 55 | [self addChild:[[OCScopeNode alloc] initWithReader:self.reader]]; 56 | } 57 | 58 | 59 | - (void)read 60 | { 61 | OCToken *token = [self.reader read]; 62 | if (token.tokenSubType == OCWordSubTypeIf) { 63 | [self readIf]; 64 | }else if (token.tokenSubType == OCWordSubTypeElse){ 65 | OCToken *token2 = [self.reader read]; 66 | if (token2.tokenSubType == OCWordSubTypeIf) { 67 | [self readIf]; 68 | }else{ 69 | [self.reader unread]; 70 | [self readElse]; 71 | } 72 | }else if (token.tokenSubType == OCWordSubTypeFor){ 73 | [self readFor]; 74 | }else if (token.tokenSubType == OCWordSubTypeDo){ 75 | [self.logics addObject:@(OCWordSubTypeDo)]; 76 | [self addChild:[[OCScopeNode alloc] initWithReader:self.reader]]; 77 | OCToken *token2 = [self.reader read]; 78 | NSAssert(token2.tokenSubType == OCWordSubTypeWhile, nil); //do...while.. 79 | [self.expressions addObject:[[OCReturnNode alloc] initWithReader:self.reader]]; 80 | }else if (token.tokenSubType == OCWordSubTypeWhile){ 81 | [self.logics addObject:@(OCWordSubTypeWhile)]; 82 | [self.expressions addObject:[[OCReturnNode alloc] initWithReader:self.reader]]; 83 | OCToken *token2 = [self.reader current]; 84 | if (token2.tokenSubType == OCWordSubTypeDo) { 85 | [self.reader read]; 86 | } 87 | [self addChild:[[OCScopeNode alloc] initWithReader:self.reader]]; 88 | }else{ 89 | [self.reader unread]; 90 | self.finished = YES; 91 | } 92 | } 93 | 94 | - (id)excuteWithCtx:(NSDictionary *)ctx 95 | { 96 | // NSAssert(self.children.count == self.logics.count == self.expressions.count,nil); 97 | for (int i = 0; i < self.logics.count; i++) { 98 | OCReturnNode *expression = self.expressions[i]; 99 | OCNode *node = self.children[i]; 100 | NSInteger logicType = [self.logics[i] integerValue]; 101 | if (logicType == OCWordSubTypeIf) { 102 | id exp = [expression excuteWithCtx:ctx]; 103 | if ([exp isKindOfClass:[NSNumber class]]) { 104 | if ([exp boolValue]) { 105 | EXCUTE(node,ctx); 106 | } 107 | }else{ 108 | if (exp != nil) { 109 | EXCUTE(node,ctx); 110 | } 111 | } 112 | }else if (logicType == OCWordSubTypeElse){ 113 | EXCUTE(node,ctx); 114 | }else if (logicType == OCWordSubTypeDo){ 115 | do { 116 | EXCUTE(node,ctx); 117 | } while ([[expression excuteWithCtx:ctx] boolValue]); 118 | }else if (logicType == OCWordSubTypeWhile || logicType == OCWordSubTypeFor){ 119 | while ([[expression excuteWithCtx:ctx] boolValue]) { 120 | EXCUTE(node,ctx); 121 | } 122 | } 123 | } 124 | return nil; 125 | } 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /OCEval/parser/OCExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCExtension.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/21. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #if TARGET_OS_IPHONE 10 | @import UIKit; 11 | #else 12 | @import AppKit; 13 | #endif 14 | 15 | @interface OCExtension : NSObject 16 | 17 | + (int)sizeOfStructTypes:(NSString *)structTypes; 18 | + (void)getStructDataWidthDict:(void *)structData dict:(NSDictionary *)dict structDefine:(NSDictionary *)structDefine; 19 | + (NSDictionary *)getDictOfStruct:(void *)structData structDefine:(NSDictionary *)structDefine; 20 | 21 | + (NSMutableDictionary *)registeredStruct; 22 | 23 | + (NSString *)extractStructName:(NSString *)typeEncodeString; 24 | + (void)defineStruct:(NSDictionary *)defineDict; 25 | 26 | @end 27 | 28 | -------------------------------------------------------------------------------- /OCEval/parser/OCFastCalculateNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCFastCalculateNode.h 3 | // OCEval 4 | // 5 | // Created by sgcy on 2018/11/26. 6 | // 7 | 8 | #import "OCToken.h" 9 | #import "OCNode.h" 10 | 11 | @interface OCFastCalculateNode : OCNode 12 | 13 | @property (nonatomic,assign) OCTokenSubType subType; 14 | @property (nonatomic,strong) NSString *assigneeName; 15 | 16 | @end 17 | 18 | 19 | -------------------------------------------------------------------------------- /OCEval/parser/OCFastCalculateNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCFastCalculateNode.m 3 | // OCEval 4 | // 5 | // Created by sgcy on 2018/11/26. 6 | // 7 | 8 | #import "OCFastCalculateNode.h" 9 | #import "OCReturnNode.h" 10 | 11 | @implementation OCFastCalculateNode 12 | 13 | - (instancetype)initWithReader:(OCTokenReader *)reader 14 | { 15 | if (self = [super initWithReader:reader]) { 16 | [self read]; 17 | } 18 | return self; 19 | } 20 | 21 | 22 | - (void)read 23 | { 24 | OCToken *current = [self.reader read]; 25 | if (current.tokenType == OCTokenTypeWord) { 26 | self.assigneeName = current.value; 27 | OCToken *current = [self.reader read]; 28 | self.subType = current.tokenSubType; 29 | if (self.subType != OCSymbolSubTypeAddAdd && self.subType != OCSymbolSubTypeMinusMinus) { 30 | [self addChild:[[OCReturnNode alloc] initWithReader:self.reader]]; 31 | } 32 | }else if(current.tokenType == OCTokenTypeSymbol){ 33 | self.subType = current.tokenSubType; 34 | OCToken *current = [self.reader read]; 35 | self.assigneeName = current.value; 36 | } 37 | } 38 | 39 | - (id)excuteWithCtx:(NSDictionary *)ctx 40 | { 41 | NSNumber *base = [ctx valueForKey:self.assigneeName]; 42 | switch (self.subType) { 43 | case OCSymbolSubTypeAddAdd: 44 | [ctx setValue:@(base.integerValue + 1) forKey:self.assigneeName]; 45 | break; 46 | case OCSymbolSubTypeMinusMinus: 47 | [ctx setValue:@(base.integerValue - 1) forKey:self.assigneeName]; 48 | break; 49 | case OCSymbolSubTypeAddEqual: 50 | [ctx setValue:@(base.doubleValue + [[self.children[0] excuteWithCtx:ctx] doubleValue]) forKey:self.assigneeName]; 51 | break; 52 | case OCSymbolSubTypeMinusEqual: 53 | [ctx setValue:@(base.doubleValue - [[self.children[0] excuteWithCtx:ctx] doubleValue]) forKey:self.assigneeName]; 54 | break; 55 | default: 56 | break; 57 | } 58 | return nil; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /OCEval/parser/OCIterateNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCIterateNode.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/16. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCNode.h" 10 | 11 | 12 | @interface OCIterateNode : OCNode 13 | 14 | + (instancetype)nodeWithReader:(OCTokenReader *)reader; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /OCEval/parser/OCIterateNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCIterateNode.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/16. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCIterateNode.h" 10 | #import "OCToken.h" 11 | #import "OCNode.h" 12 | #import "OCReturnNode.h" 13 | #import "OCLineNode.h" 14 | 15 | @interface OCFastEnumIterateNode:OCIterateNode 16 | 17 | @property (nonatomic,strong) NSString *variableName; 18 | @property (nonatomic,assign) NSInteger index; 19 | @property (nonatomic,strong) NSArray *array; 20 | 21 | @end 22 | 23 | @implementation OCFastEnumIterateNode 24 | 25 | - (instancetype)initWithReader:(OCTokenReader *)reader 26 | { 27 | if (self = [super initWithReader:reader]) { 28 | self.variableName = [reader read].value; 29 | NSAssert([reader read].tokenSubType == OCWordSubTypeIn, nil); 30 | [self read]; 31 | NSAssert([reader read].tokenSubType == OCSymbolSubTypeRightParen, nil); 32 | } 33 | return self; 34 | } 35 | 36 | - (void)read 37 | { 38 | [self addChild:[[OCReturnNode alloc] initWithReader:self.reader]]; 39 | } 40 | 41 | - (id)excuteWithCtx:(NSDictionary *)ctx 42 | { 43 | if (!self.array) { 44 | self.array = [self.children[0] excuteWithCtx:ctx]; 45 | } 46 | BOOL valid = self.index < self.array.count; 47 | //task 1: set variable 48 | if (valid) { 49 | [ctx setValue:self.array[self.index] forKey:self.variableName]; 50 | } 51 | self.index ++; 52 | //task 2: return BOOL 53 | return @(valid); 54 | } 55 | 56 | @end 57 | 58 | @interface OCNormalEnumIterateNode:OCIterateNode 59 | 60 | @property (nonatomic,assign) BOOL hasInit; 61 | 62 | @end 63 | 64 | @implementation OCNormalEnumIterateNode 65 | 66 | - (instancetype)initWithReader:(OCTokenReader *)reader 67 | { 68 | if (self = [super initWithReader:reader]) { 69 | [self addChild:[[OCLineNode alloc] initWithReader:reader]]; 70 | [self addChild:[[OCReturnNode alloc] initWithReader:reader]]; 71 | NSAssert([reader read].tokenSubType == OCSymbolSubTypeSemi, nil); 72 | [self addChild:[[OCLineNode alloc] initWithReader:reader]]; 73 | } 74 | return self; 75 | } 76 | 77 | - (id)excuteWithCtx:(NSDictionary *)ctx 78 | { 79 | if (!self.hasInit) { 80 | [self.children[0] excuteWithCtx:ctx]; 81 | self.hasInit = YES; 82 | return [self.children[1] excuteWithCtx:ctx]; 83 | } 84 | [self.children[2] excuteWithCtx:ctx]; 85 | NSNumber *result = [self.children[1] excuteWithCtx:ctx]; 86 | return result; 87 | } 88 | 89 | @end 90 | 91 | 92 | @interface OCIterateNode() 93 | 94 | @end 95 | 96 | 97 | @implementation OCIterateNode 98 | 99 | + (instancetype)nodeWithReader:(OCTokenReader *)reader 100 | { 101 | NSAssert([reader read].tokenSubType == OCSymbolSubTypeLeftParen, nil); 102 | [reader read]; 103 | OCToken *current = [reader read]; 104 | if (current.tokenSubType == OCSymbolSubTypeStar){ 105 | current = [reader read]; 106 | } 107 | current = [reader read]; 108 | if (current.tokenSubType == OCWordSubTypeIn) { 109 | [reader unread:2]; 110 | return [[OCFastEnumIterateNode alloc] initWithReader:reader]; 111 | }else{ 112 | [reader unread:2]; 113 | return [[OCNormalEnumIterateNode alloc] initWithReader:reader]; 114 | } 115 | } 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /OCEval/parser/OCLineNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCLineNode.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCNode.h" 11 | 12 | typedef NS_ENUM(NSUInteger, OCLineNodeType) { 13 | OCLineNodeTypeCallMethod = 0, 14 | OCLineNodeTypeAssign, 15 | OCLineNodeTypeAssignPoint, 16 | OCLineNodeTypeReturn, 17 | OCLineNodeTypeAddAdd, 18 | OCLineNodeTypeMinusMinus 19 | }; 20 | 21 | @interface OCLineNode : OCNode 22 | 23 | @property (nonatomic,assign) OCLineNodeType type; 24 | @property (nonatomic,strong) NSString *assigneeName; 25 | @property (nonatomic,assign) BOOL isStatement; 26 | 27 | @end 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /OCEval/parser/OCLineNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCLineNode.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCLineNode.h" 10 | #import "OCToken.h" 11 | #import "OCMethodNode.h" 12 | #import "OCReturnNode.h" 13 | #import "OCPropertyNode.h" 14 | #import "OCBlockNode.h" 15 | #import "OCFastCalculateNode.h" 16 | 17 | @interface OCLineNode() 18 | 19 | 20 | 21 | @end 22 | 23 | 24 | @implementation OCLineNode 25 | 26 | - (instancetype)initWithReader:(OCTokenReader *)reader 27 | { 28 | if (self = [super initWithReader:reader]) { 29 | while (!self.isFinished) { 30 | [self read]; 31 | } 32 | } 33 | return self; 34 | } 35 | 36 | - (void)read 37 | { 38 | OCToken *token = [self.reader current]; 39 | 40 | //end by semi ; 41 | if (token.tokenSubType == OCSymbolSubTypeSemi || token == [OCToken EOFToken] || token.tokenSubType == OCSymbolSubTypeRightParen) { 42 | [self.reader read]; 43 | self.finished = YES; 44 | return; 45 | } 46 | 47 | if (token.tokenSubType == OCSymbolSubTypeLeftSquare) { 48 | self.type = OCLineNodeTypeCallMethod; 49 | [self addChild:[[OCMethodNode alloc] initWithReader:self.reader]]; 50 | }else if (token.tokenSubType == OCWordSubTypeReturn){ 51 | self.type = OCLineNodeTypeReturn; 52 | [self.reader read]; 53 | [self addChild:[[OCReturnNode alloc] initWithReader:self.reader]]; 54 | }else if (token.tokenSubType == OCSymbolSubTypeAddAdd || token.tokenSubType == OCSymbolSubTypeMinusMinus){ 55 | self.type = OCLineNodeTypeCallMethod; 56 | [self addChild:[[OCFastCalculateNode alloc] initWithReader:self.reader]]; 57 | }else{ 58 | OCToken *token1 = [self.reader read]; 59 | if (token1.tokenSubType <= OCWordSubTypeBlock && token1.tokenSubType >= OCWordSubTypeWeak) { 60 | token1 = [self.reader read]; 61 | } 62 | 63 | OCToken *token2 = [self.reader read]; 64 | 65 | if (token2.tokenSubType == OCSymbolSubTypePoint){ 66 | //method setter 67 | self.type = OCLineNodeTypeCallMethod; 68 | [self.reader unread:2]; 69 | [self addChild:[[OCPointSetterNode alloc] initWithReader:self.reader]]; 70 | } 71 | 72 | if (token2.tokenSubType == OCSymbolSubTypeStar) { 73 | token2 = [self.reader read]; 74 | } 75 | 76 | //local variable setter 77 | if (token2.tokenType == OCTokenTypeWord) { 78 | self.type = OCLineNodeTypeAssign; 79 | self.assigneeName = token2.value; 80 | self.isStatement = YES; 81 | NSAssert([self.reader read].tokenSubType == OCSymbolSubTypeEqual, nil); 82 | [self addChild:[[OCReturnNode alloc] initWithReader:self.reader]]; 83 | }else if (token2.tokenSubType == OCSymbolSubTypeEqual){ 84 | self.type = OCLineNodeTypeAssign; 85 | self.assigneeName = token1.value; 86 | [self addChild:[[OCReturnNode alloc] initWithReader:self.reader]]; 87 | }else if (token2.tokenSubType == OCSymbolSubTypeLeftSquare){ 88 | //subscript setter like array[1] = ... 89 | self.type = OCLineNodeTypeCallMethod; 90 | OCSubscriptMethodNode *methodNode = [[OCSubscriptMethodNode alloc] init]; 91 | methodNode.isSetter = YES; 92 | OCVariableNode *variableNode = [[OCVariableNode alloc] init]; 93 | variableNode.token = token1; 94 | methodNode.caller = variableNode; 95 | [methodNode addChild:[[OCReturnNode alloc] initWithReader:self.reader]]; 96 | NSAssert([self.reader read].tokenSubType == OCSymbolSubTypeRightSquare, nil); 97 | NSAssert([self.reader read].tokenSubType == OCSymbolSubTypeEqual, nil); 98 | [methodNode addChild:[[OCReturnNode alloc] initWithReader:self.reader]]; 99 | [self addChild:methodNode]; 100 | }else if (token2.tokenSubType == OCSymbolSubTypeLeftParen){ 101 | if ([self.reader read].tokenSubType == OCSymbolSubTypeCaret) { 102 | //define block 103 | self.assigneeName = [self.reader read].value; 104 | self.isStatement = YES; 105 | while ([self.reader read].tokenSubType != OCSymbolSubTypeEqual) {} 106 | self.type = OCLineNodeTypeAssign; 107 | [self addChild:[[OCReturnNode alloc] initWithReader:self.reader]]; 108 | }else{ 109 | //call block 110 | [self.reader unread:3]; 111 | self.type = OCLineNodeTypeCallMethod; 112 | [self addChild:[[OCBlockCallNode alloc] initWithReader:self.reader]]; 113 | } 114 | }else if (token2.tokenSubType >= OCSymbolSubTypeAddAdd || token2.tokenSubType <= OCSymbolSubTypeMinusEqual){ 115 | [self.reader unread:2]; 116 | self.type = OCLineNodeTypeCallMethod; 117 | [self addChild:[[OCFastCalculateNode alloc] initWithReader:self.reader]]; 118 | } 119 | } 120 | } 121 | 122 | - (id)excuteWithCtx:(NSDictionary *)ctx 123 | { 124 | if (self.children.count == 0) { 125 | return nil; 126 | } 127 | if (self.type == OCLineNodeTypeCallMethod) { 128 | [self.children[0] excuteWithCtx:ctx]; 129 | }else if (self.type == OCLineNodeTypeReturn){ 130 | return [self.children[0] excuteWithCtx:ctx]; 131 | }else if (self.type == OCLineNodeTypeAssign){ 132 | //set context. 133 | OCNode *node = self.children[0]; 134 | id value = [node excuteWithCtx:ctx]; 135 | [ctx setValue:value forKey:self.assigneeName]; 136 | } 137 | return nil; 138 | } 139 | 140 | @end 141 | -------------------------------------------------------------------------------- /OCEval/parser/OCLiteralNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCLiteralNode.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/17. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCNode.h" 11 | 12 | typedef NS_ENUM(NSUInteger, OCLiteralNodeType) { 13 | OCLiteralNodeTypeSimple = 0, 14 | OCLiteralNodeTypeExpression, 15 | OCLiteralNodeTypeCollection, 16 | OCLiteralNodeTypeSeletor // TODO 17 | }; 18 | 19 | 20 | @interface OCLiteralNode : OCNode 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /OCEval/parser/OCLiteralNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCLiteralNode.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/17. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCLiteralNode.h" 10 | #import "OCToken.h" 11 | #import "OCReturnNode.h" 12 | #import "OCMethodNode.h" 13 | 14 | @interface OCLiteralNode() 15 | 16 | @property (nonatomic,assign) OCLiteralNodeType type; 17 | 18 | @end 19 | 20 | 21 | @implementation OCLiteralNode 22 | 23 | - (instancetype)initWithReader:(OCTokenReader *)reader 24 | { 25 | if (self = [super initWithReader:reader]) { 26 | [self.reader read]; 27 | [self read]; 28 | } 29 | return self; 30 | } 31 | 32 | - (void)read 33 | { 34 | OCToken *token = [self.reader current]; 35 | if (token.tokenType == OCTokenTypeNumber || token.tokenType == OCTokenTypeString) { 36 | self.type = OCLiteralNodeTypeSimple; 37 | [self addChild:[[OCSimpleNode alloc] initWithReader:self.reader]]; 38 | }else if (token.tokenSubType == OCSymbolSubTypeLeftParen){ 39 | self.type = OCLiteralNodeTypeExpression; 40 | [self addChild:[[OCReturnNode alloc] initWithReader:self.reader]]; 41 | }else if (token.tokenSubType == OCSymbolSubTypeLeftSquare || token.tokenSubType == OCSymbolSubTypeLeftBrace){ 42 | self.type = OCLiteralNodeTypeCollection; 43 | [self addChild:[[OCLiteralMethodNode alloc] initWithReader:self.reader]]; 44 | }else if (token.tokenSubType == OCWordSubTypeSelector){ 45 | self.type = OCLiteralNodeTypeSeletor; 46 | } 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /OCEval/parser/OCMethodNode+invoke.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCMethodNode+invoke.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/18. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCMethodNode.h" 11 | 12 | @interface OCMethodNode(invoke) 13 | 14 | + (id)nilObj; 15 | + (id)invokeWithCaller:(id)caller selectorName:(NSString *)selectorName argments:(NSArray *)arguments; 16 | + (id)invokeWithInvocation:(NSInvocation *)invocation argments:(NSArray *)arguments; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /OCEval/parser/OCMethodNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCMethodNode.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCNode.h" 10 | 11 | @class OCReturnNode; 12 | 13 | @interface OCMethodNode : OCNode 14 | 15 | @property (nonatomic,strong) OCNode *caller; 16 | @property (nonatomic,strong) NSMutableString *selectorName; 17 | @property (nonatomic,assign) BOOL isSuper; 18 | 19 | @end 20 | 21 | @interface OCSubscriptMethodNode : OCMethodNode 22 | 23 | @property (nonatomic,assign) BOOL isSetter; 24 | 25 | @end 26 | 27 | @interface OCLiteralMethodNode : OCNode 28 | 29 | 30 | @end 31 | 32 | @interface OCPointSetterNode : OCNode 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /OCEval/parser/OCMethodSignature.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCMethodSignature.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/19. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ffi.h" 11 | 12 | @interface OCMethodSignature : NSObject 13 | 14 | @property (nonatomic, strong) NSString *types; 15 | @property (nonatomic, strong) NSArray *argumentTypes; 16 | @property (nonatomic, strong) NSString *returnType; 17 | 18 | - (instancetype)initWithBlockTypeNames:(NSArray *)typeNames; 19 | - (instancetype)initWithObjCTypes:(NSString *)objCTypes; 20 | 21 | + (ffi_type *)ffiTypeWithEncodingChar:(const char *)c; 22 | + (NSString *)typeEncodeWithTypeName:(NSString *)typeName; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /OCEval/parser/OCNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCNode.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OCTokenReader.h" 11 | 12 | #define EXCUTE(node,ctx) id result = [node excuteWithCtx:ctx];\ 13 | if (result) {\ 14 | return result;\ 15 | } 16 | 17 | @interface OCNode : NSObject 18 | 19 | @property (nonatomic,strong) OCTokenReader *reader; 20 | @property (nonatomic,assign,getter=isFinished) BOOL finished; 21 | 22 | - (instancetype)initWithReader:(OCTokenReader *)reader; 23 | 24 | - (void)read; 25 | 26 | - (void)addChild:(OCNode *)node; 27 | - (void)replaceLastChild:(OCNode *)node; 28 | 29 | - (NSArray *)children; 30 | 31 | - (id)excuteWithCtx:(NSDictionary *)ctx; 32 | 33 | @end 34 | 35 | @interface OCSimpleNode : OCNode 36 | 37 | @property (nonatomic,strong) OCToken *token; 38 | 39 | @end 40 | 41 | @interface OCSymbolNode : OCSimpleNode 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /OCEval/parser/OCNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCNode.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCNode.h" 10 | #import "OCToken.h" 11 | 12 | @interface OCNode() 13 | 14 | @property (nonatomic,strong) NSMutableArray *allChilds; 15 | 16 | @end 17 | 18 | @implementation OCNode 19 | 20 | - (instancetype)init 21 | { 22 | if (self = [super init]) { 23 | _allChilds = [[NSMutableArray alloc] init]; 24 | } 25 | return self; 26 | } 27 | 28 | - (instancetype)initWithReader:(OCTokenReader *)reader 29 | { 30 | if (self = [super init]) { 31 | _allChilds = [[NSMutableArray alloc] init]; 32 | _reader = reader; 33 | } 34 | return self; 35 | } 36 | 37 | - (void)read 38 | { 39 | 40 | } 41 | 42 | - (void)addChild:(OCNode *)node 43 | { 44 | [self.allChilds addObject:node]; 45 | } 46 | 47 | - (void)replaceLastChild:(OCNode *)node 48 | { 49 | self.allChilds[self.allChilds.count - 1] = node; 50 | } 51 | 52 | - (NSArray *)children 53 | { 54 | return [self.allChilds copy]; 55 | } 56 | 57 | - (id)excuteWithCtx:(NSDictionary *)ctx 58 | { 59 | for (OCNode *node in self.children) { 60 | EXCUTE(node,ctx); 61 | } 62 | return nil; 63 | } 64 | 65 | - (NSString *)description 66 | { 67 | if (![self.children count]) { 68 | return NSStringFromClass(self.class); 69 | } 70 | 71 | NSMutableString *ms = [NSMutableString string]; 72 | 73 | [ms appendFormat:@"(%@ ", NSStringFromClass(self.class)]; 74 | 75 | NSInteger i = 0; 76 | for (OCNode *child in self.children) { 77 | NSString *fmt = 0 == i++ ? @"%@" : @" %@"; 78 | [ms appendFormat:fmt, [child description]]; 79 | } 80 | 81 | [ms appendString:@")"]; 82 | return [ms copy]; 83 | } 84 | 85 | @end 86 | 87 | 88 | @implementation OCSimpleNode 89 | 90 | - (instancetype)initWithReader:(OCTokenReader *)reader 91 | { 92 | if (self = [super init]) { 93 | self.token = [reader read]; 94 | } 95 | return self; 96 | } 97 | 98 | - (id)excuteWithCtx:(NSDictionary *)ctx 99 | { 100 | return self.token.value; 101 | } 102 | 103 | - (NSString *)description 104 | { 105 | return [NSString stringWithFormat:@"Node:%@",self.token.value]; 106 | } 107 | 108 | @end 109 | 110 | 111 | @implementation OCSymbolNode 112 | 113 | @end 114 | -------------------------------------------------------------------------------- /OCEval/parser/OCPropertyNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCPropertyNode.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/16. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCNode.h" 10 | 11 | @interface OCVariableNode : OCSimpleNode 12 | 13 | @end 14 | 15 | @interface OCPropertyNode : OCVariableNode 16 | 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /OCEval/parser/OCPropertyNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCPropertyNode.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/16. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCPropertyNode.h" 10 | #import "OCTokenReader.h" 11 | #import "OCToken.h" 12 | #import "OCReturnNode.h" 13 | #import "OCMethodNode.h" 14 | #import "OCMethodNode+invoke.h" 15 | #import "OCCfuntionHelper.h" 16 | 17 | @interface OCVariableNode() 18 | 19 | 20 | @end 21 | 22 | 23 | @implementation OCVariableNode 24 | 25 | - (id)excuteWithCtx:(NSDictionary *)ctx 26 | { 27 | id variable = [ctx valueForKey:self.token.value]; 28 | if (variable) { 29 | return variable; 30 | } 31 | 32 | switch (self.token.tokenSubType) { 33 | case OCWordSubTypeNil: 34 | return nil; 35 | case OCWordSubTypeYES: 36 | return @(YES); 37 | case OCWordSubTypeNO: 38 | return @(NO); 39 | case OCWordSubTypeSuper: 40 | return [ctx valueForKey:@"self"]; 41 | default: 42 | break; 43 | } 44 | 45 | Class cls = NSClassFromString(self.token.value); 46 | if (cls) { 47 | return cls; 48 | } 49 | 50 | 51 | // abort(); 52 | return nil; 53 | } 54 | 55 | - (NSString *)description 56 | { 57 | return [NSString stringWithFormat:@"VariableNode Name:%@",self.token.value]; 58 | } 59 | 60 | 61 | @end 62 | 63 | @interface OCPropertyNode() 64 | 65 | @property (nonatomic,strong) NSMutableArray *propertyNames; 66 | @property (nonatomic,assign) BOOL shouldBeWord; //The next token should be word or point. 67 | 68 | @end 69 | 70 | @implementation OCPropertyNode 71 | 72 | - (instancetype)initWithReader:(OCTokenReader *)reader 73 | { 74 | if (self = [super initWithReader:reader]) { 75 | self.reader = reader; 76 | self.propertyNames = [[NSMutableArray alloc] init]; 77 | while (!self.isFinished) { 78 | [self readPropertys]; 79 | } 80 | } 81 | return self; 82 | } 83 | 84 | - (void)readPropertys 85 | { 86 | OCToken *token = [self.reader read]; 87 | if (token.tokenSubType == OCSymbolSubTypeEqual) { 88 | // end by equal,it must be a setter method 89 | self.finished = YES; 90 | [self.reader unread:2]; 91 | [self.propertyNames removeLastObject]; 92 | return; 93 | }else if (token.tokenType == OCTokenTypeWord && self.shouldBeWord){ 94 | [self.propertyNames addObject:token.value]; 95 | self.shouldBeWord = NO; 96 | }else if (token.tokenSubType == OCSymbolSubTypePoint && !self.shouldBeWord){ 97 | self.shouldBeWord = YES; 98 | }else{ 99 | [self.reader unread]; 100 | self.finished = YES; 101 | } 102 | } 103 | 104 | - (id)excuteWithCtx:(NSDictionary *)ctx 105 | { 106 | id obj = [ctx objectForKey:self.token.value]; 107 | for (NSString *propertyName in self.propertyNames) { 108 | obj = [OCMethodNode invokeWithCaller:obj selectorName:propertyName argments:@[]]; 109 | } 110 | return obj; 111 | } 112 | 113 | 114 | - (NSString *)description 115 | { 116 | return [NSString stringWithFormat:@"NodeName:%@.%@",self.token.value,self.propertyNames]; 117 | } 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /OCEval/parser/OCReturnNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCReturnNode.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCNode.h" 10 | 11 | typedef NS_OPTIONS(NSUInteger, OCReturnNodeType) { 12 | OCReturnNodeTypeSimple = 1 << 0, 13 | OCReturnNodeTypeExpression = 1 << 1, 14 | OCReturnNodeTypeNSPredicate = 1 << 2, 15 | OCReturnNodeTypeObjectNotNil = 1 << 3, 16 | }; 17 | 18 | @interface OCReturnNode : OCNode 19 | 20 | @property (nonatomic,assign) OCReturnNodeType type; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /OCEval/parser/OCScopeNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCScopeNode.h 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCNode.h" 10 | 11 | 12 | @interface OCScopeNode : OCNode 13 | 14 | @end 15 | 16 | @interface OCRootNode: OCScopeNode 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /OCEval/parser/OCScopeNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCScopeNode.m 3 | // OCParser 4 | // 5 | // Created by sgcy on 2018/11/15. 6 | // Copyright © 2018年 sgcy. All rights reserved. 7 | // 8 | 9 | #import "OCScopeNode.h" 10 | #import "OCToken.h" 11 | #import "OCControlNode.h" 12 | #import "OCLineNode.h" 13 | 14 | 15 | @implementation OCScopeNode 16 | 17 | - (instancetype)initWithReader:(OCTokenReader *)reader 18 | { 19 | if (self = [super initWithReader:reader]) { 20 | OCToken *token = [self.reader read]; 21 | NSAssert(token.tokenSubType == OCSymbolSubTypeLeftBrace, nil); 22 | while (!self.isFinished) { 23 | [self read]; 24 | } 25 | } 26 | return self; 27 | } 28 | 29 | - (void)read 30 | { 31 | OCToken *token = [self.reader current]; 32 | if (token.tokenSubType == OCSymbolSubTypeRightBrace || token == [OCToken EOFToken]) { 33 | self.finished = YES; 34 | [self.reader read]; 35 | return; 36 | }else if (token.tokenSubType >= OCWordSubTypeIf && token.tokenSubType <= OCWordSubTypeFor) { 37 | OCControlNode *controlNode = [[OCControlNode alloc] initWithReader:self.reader]; 38 | [self addChild:controlNode]; 39 | }else{ 40 | OCLineNode *lineNode = [[OCLineNode alloc] initWithReader:self.reader]; 41 | [self addChild:lineNode]; 42 | } 43 | } 44 | 45 | - (id)excuteWithCtx:(NSDictionary *)ctx 46 | { 47 | // NSMutableArray *toRemove = [[NSMutableArray alloc] init]; 48 | for (OCNode *node in self.children) { 49 | // if ([node isKindOfClass:[OCLineNode class]]) { 50 | // OCLineNode *lineNode = (OCLineNode *)node; 51 | // if (lineNode.isStatement == YES) { 52 | // [toRemove addObject:lineNode.assigneeName]; 53 | // } 54 | // } 55 | EXCUTE(node,ctx); 56 | } 57 | // block delays the object releasing 58 | // for (NSString *assigneeName in toRemove) { 59 | // [ctx setValue:nil forKey:assigneeName]; 60 | // } 61 | return nil; 62 | } 63 | 64 | 65 | @end 66 | 67 | 68 | @implementation OCRootNode 69 | 70 | - (id)excuteWithCtx:(NSDictionary *)ctx 71 | { 72 | return [super excuteWithCtx:ctx]; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /README-CN.md: -------------------------------------------------------------------------------- 1 | # OCEval 2 | 3 | [![Travis](https://travis-ci.org/lilidan/OCEval.svg?branch=master)](https://travis-ci.org/lilidan/OCEval) 4 | ![support](https://img.shields.io/badge/support-macOS%20%7C%20iOS-orange.svg) 5 | 6 | 一个Objective-C解释器, 能够像 `eval()` 一样动态执行OC代码. 7 | 8 | [English README](https://github.com/lilidan/OCEval/blob/master/README.md) 9 | 10 | 11 | ### Features 12 | 13 | - 动态执行OC代码 14 | - 支持 iOS & OS X. 15 | - 用 Objective-C 编写的. 16 | - 集成单元测试 17 | - 支持 block 和 C 函数调用. 18 | 19 | # Usage 20 | 21 | ### 动态执行OC代码 22 | 23 | ```Objective-C 24 | //Example 1 25 | NSString *inputStr = @"return 1 + 3 <= 4 && [NSString string] != nil;"; 26 | NSNumber *result = [OCEval eval:inputStr]; 27 | NSAssert([result boolValue] == YES, nil); 28 | ``` 29 | ```Objective-C 30 | //Example 2 31 | NSString *inputStr = @"{NSArray *content = @[@6,@7,@8,@9,@1,@2,@3,@4];\ 32 | NSComparisonResult (^comparison)(id obj1, id obj2) = ^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {\ 33 | return [obj1 doubleValue] > [obj2 doubleValue];\ 34 | };\ 35 | content = [content sortedArrayUsingComparator:comparison];\ 36 | return content;\ 37 | }"; 38 | NSArray *result = [OCEval eval:inputStr]; 39 | NSAssert([result[6] intValue] == 8, nil); 40 | ``` 41 | 42 | ### 替换现有的OC方法 43 | 44 | 通过Aspect的帮助可以替换现有的OC方法。(从而可以实现类似热修复) 45 | 46 | ```Objective-C 47 | 48 | //new implementation code,just call originalInvocation 49 | NSString *viewDidLoad2 = @"{\ 50 | [originalInvocation invoke];\ 51 | "; 52 | 53 | [OCEval hookClass:@"ViewController" 54 | selector:@"viewDidLoad" 55 | argNames:@[] 56 | isClass:NO 57 | implementation:viewDidLoad2]; 58 | ``` 59 | 60 | ### 甚至编写一个完全动态的App 61 | 62 | 理论上可以编写一个完全动态的Objective-C的App,然后通过网络下发。当然目前还需要做很多工作。 63 | 64 | # Installation 65 | 66 | ### Cocoapods 67 | 68 | ``` 69 | pod 'OCEval' 70 | ``` 71 | 72 | # TO-DO List 73 | 74 | ### 已经支持的语法 75 | 76 | 77 | * [x] if..else..,do..while.. 78 | * [x] for..in,for 79 | * [x] @() @[] @{} 80 | * [x] array[0] or dic[@""] 81 | * [x] block 的定义和调用 82 | * [x] call C external function 83 | * [x] i++,++i,i+=1 等 84 | * [x] C struct: 包括CGRect,CGPoint,CGSize,NSRange等常用结构体。 85 | * [x] if(a){}:支持直接判断a是否为nil的简写 86 | * [x] [super doSth]: 支持调用super 87 | 88 | 部分语法糖的支持尤其是C结构体的支持不太完善。 89 | 90 | ### 目前不支持的语法(持续改善中) 91 | 92 | * [ ] call C inline function 暂不支持C内联函数调用。 93 | * [ ] macro like #define xx or typedef: use original value instead. 暂不支持宏定义,用原本的值替代。 94 | * [ ] ((YES)&&(NO)) : use `(YES && NO)` instead 。 使用条件与/或的时候注意一下括号。 95 | * [ ] [stringformat:@"%d",aInt] : use `[stringformat:@"%@",[NSNumber numberWithInt:aInt]]` instead。 stringWithFormat暂不支持非id对象的类型。 96 | * [ ] ?: : use `if else` instead 。 暂不支持三元运算符。 97 | * [ ] _propertyName : use `self.propertyName` instead 。 暂不支持下划线获取property。 98 | * [ ] if (!a): use `if(a == nil)` instead 。暂不支持if(!a)的简写,需要用if(a == nil)来替代 99 | 100 | # Warning 101 | 102 | 仅作为研究学习使用,提交AppStore审核可能会被拒绝。 103 | 104 | # Dependency 105 | 106 | - libffi 107 | - Aspect 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OCEval 2 | 3 | [![Travis](https://travis-ci.org/lilidan/OCEval.svg?branch=master)](https://travis-ci.org/lilidan/OCEval) 4 | ![support](https://img.shields.io/badge/support-macOS%20%7C%20iOS-orange.svg) 5 | 6 | A tiny JIT Interpreter of Objective-C, dynamically run your code like `eval()`. 7 | 8 | [中文介绍](https://github.com/lilidan/OCEval/blob/master/README-CN.md) 9 | 10 | ## Features 11 | 12 | - Run Objective-C code dynamically. 13 | - Support iOS & OS X. 14 | - Written by Objective-C. 15 | - Driven By Unit Tests. 16 | - Support part of Low-level APIs like block and C funtion. 17 | 18 | # Usage 19 | 20 | ### Dynamically call Objective-C method 21 | ```Objective-C 22 | //Example 1 23 | NSString *inputStr = @"return 1 + 3 <= 4 && [NSString string] != nil;"; 24 | NSNumber *result = [OCEval eval:inputStr]; 25 | NSAssert([result boolValue] == YES, nil); 26 | ``` 27 | ```Objective-C 28 | //Example 2 29 | NSString *inputStr = @"{NSArray *content = @[@6,@7,@8,@9,@1,@2,@3,@4];\ 30 | NSComparisonResult (^comparison)(id obj1, id obj2) = ^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {\ 31 | return [obj1 doubleValue] > [obj2 doubleValue];\ 32 | };\ 33 | content = [content sortedArrayUsingComparator:comparison];\ 34 | return content;\ 35 | }"; 36 | NSArray *result = [OCEval eval:inputStr]; 37 | NSAssert([result[6] intValue] == 8, nil); 38 | ``` 39 | 40 | ### Replace method implementation dynamically 41 | 42 | ```Objective-C 43 | 44 | //new implementation code,just call originalInvocation 45 | NSString *viewDidLoad2 = @"{\ 46 | [originalInvocation invoke];\ 47 | "; 48 | 49 | [OCEval hookClass:@"ViewController" 50 | selector:@"viewDidLoad" 51 | argNames:@[] 52 | isClass:NO 53 | implementation:viewDidLoad2]; 54 | ``` 55 | 56 | ### Even make a dynamical app 57 | 58 | Theoretically we could make a whole application written by Objective-C and deliver it through the network. You could read the iOS demo for details. 59 | 60 | # Installation 61 | 62 | ### Cocoapods 63 | 64 | ``` 65 | pod 'OCEval' 66 | ``` 67 | 68 | # TO-DO List 69 | 70 | ### Already supported syntax 71 | 72 | * [x] if..else..,do..while.. 73 | * [x] for..in,for 74 | * [x] @() @[] @{} 75 | * [x] array[0] or dic[@""] 76 | * [x] block 77 | * [x] call C external function 78 | * [x] mac application 79 | * [x] i++,++i,i+=1 80 | * [x] if(a){} : means if(a == nil){} 81 | * [x] C struct: including CGRect,CGPoint,CGSize,NSRange etc. 82 | * [x] [super doSth] 83 | 84 | ### Not support yet 85 | 86 | * [ ] call C inline function 87 | * [ ] macro like #define xx or typedef: use original value instead. 88 | * [ ] ((YES)&&(NO)) : use `(YES && NO)` instead 89 | * [ ] [stringformat:@"%d",aInt] : use `[stringformat:@"%@",[NSNumber numberWithInt:aInt]]` instead 90 | * [ ] ?: : use `if else` instead 91 | * [ ] _propertyName : use `self.propertyName` instead 92 | * [ ] if (!a): use `if(a == nil)` instead 93 | 94 | # Warning 95 | 96 | An app submission to Appstore including this framework will likely be rejected. 97 | 98 | # Dependency 99 | 100 | - libffi 101 | - Aspect 102 | --------------------------------------------------------------------------------