Advertisement
Guest User

Untitled

a guest
Apr 27th, 2015
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.48 KB | None | 0 0
  1. // We will show how long jumps can be used within Swift
  2.  
  3. // Create jump and set it's position
  4. let start = Jump()
  5. setjmp(start.line) // Sets start's line to the current line
  6.  
  7. println("HI") // -> "Hi" -> "Hi" -> "Hi" -> ... (prints forever)
  8.  
  9. longjmp(start.line, 0) // Jumps back to start's line, e.g. setjmp(start.line)
  10.  
  11. // We have created an infinite loop using jumps!
  12. // Now let's do something more useful: We will create a while loop!
  13.  
  14. func myWhile(test: () -> Bool, loop:() -> ()){
  15. let start = Jump()
  16. setjmp(start.line)
  17.  
  18. if (test()){
  19. loop()
  20. longjmp(start.line, 0)
  21. }
  22. }
  23.  
  24. // Now we will use our loop!
  25.  
  26. var x = 0
  27. myWhile({ x < 3 }){
  28. println("Hello world") // -> "Hello world"
  29. x++ // "Hello world"
  30. } // "Hello world"
  31.  
  32. // Let's look at a more advanced example
  33. // It turns our that setjmp actually returns whatever value is passed into longjmp
  34. // (unless the value 0 is passed in in which case setjmp returns 1)
  35. // (and setjmp returns 0 the first time it is called)
  36. // Note that setjmp and longjmp use Int32, so cast accordingly
  37.  
  38. func doNTimes(n: Int, loop:() -> ()){
  39. let start = Jump()
  40. let count = Int(setjmp(start.line))
  41.  
  42. if (count < n){
  43. loop()
  44. longjmp(start.line, count + 1)
  45. }
  46. }
  47.  
  48. doNTimes(3){
  49. println("Whoa") // -> "Whoa"
  50. } // "Whoa"
  51. // "Whoa"
  52.  
  53. // One more thing: Let's modify myWhile to support continue and break calls!
  54.  
  55. func myWhile(test: () -> Bool, loop:(myContinue: () -> (), myBreak: () -> ()) -> ()) {
  56. let start = Jump()
  57. let stop = Int(setjmp(start.line))
  58.  
  59. if (stop != -1 && test()){
  60. loop({ longjmp(start.line, 0) }, { longjmp(start.line, -1) })
  61. longjmp(start.line, 0)
  62. }
  63. }
  64.  
  65. // Tahdah!!
  66.  
  67. var x = 0
  68. myWhile({ true }) { myContinue, myBreak in
  69. x++
  70.  
  71. println("Considering \(x)")
  72. if x % 2 == 0 { myContinue() } // skip even numbers
  73.  
  74. println("Using \(x)")
  75.  
  76. if x > 9 { myBreak() } // print numbers less than or equal to 11
  77. }
  78.  
  79. // Now for the actual implementation
  80. // Turns out that I didn't really do much to make this possible
  81. // C already has this feature built in, so naturally Swift does too
  82. // I just wrapped up the malloc and free calls so you don't have to worry
  83.  
  84. class Jump {
  85. typealias JumpType = UnsafeMutablePointer<Int32>
  86. private let jumpSize = UInt(sizeof(jmp_buf))
  87. let line: JumpType
  88.  
  89. init() {
  90. line = JumpType(malloc(jumpSize))
  91. }
  92. deinit {
  93. free(line)
  94. }
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement