Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // We will show how long jumps can be used within Swift
- // Create jump and set it's position
- let start = Jump()
- setjmp(start.line) // Sets start's line to the current line
- println("HI") // -> "Hi" -> "Hi" -> "Hi" -> ... (prints forever)
- longjmp(start.line, 0) // Jumps back to start's line, e.g. setjmp(start.line)
- // We have created an infinite loop using jumps!
- // Now let's do something more useful: We will create a while loop!
- func myWhile(test: () -> Bool, loop:() -> ()){
- let start = Jump()
- setjmp(start.line)
- if (test()){
- loop()
- longjmp(start.line, 0)
- }
- }
- // Now we will use our loop!
- var x = 0
- myWhile({ x < 3 }){
- println("Hello world") // -> "Hello world"
- x++ // "Hello world"
- } // "Hello world"
- // Let's look at a more advanced example
- // It turns our that setjmp actually returns whatever value is passed into longjmp
- // (unless the value 0 is passed in in which case setjmp returns 1)
- // (and setjmp returns 0 the first time it is called)
- // Note that setjmp and longjmp use Int32, so cast accordingly
- func doNTimes(n: Int, loop:() -> ()){
- let start = Jump()
- let count = Int(setjmp(start.line))
- if (count < n){
- loop()
- longjmp(start.line, count + 1)
- }
- }
- doNTimes(3){
- println("Whoa") // -> "Whoa"
- } // "Whoa"
- // "Whoa"
- // One more thing: Let's modify myWhile to support continue and break calls!
- func myWhile(test: () -> Bool, loop:(myContinue: () -> (), myBreak: () -> ()) -> ()) {
- let start = Jump()
- let stop = Int(setjmp(start.line))
- if (stop != -1 && test()){
- loop({ longjmp(start.line, 0) }, { longjmp(start.line, -1) })
- longjmp(start.line, 0)
- }
- }
- // Tahdah!!
- var x = 0
- myWhile({ true }) { myContinue, myBreak in
- x++
- println("Considering \(x)")
- if x % 2 == 0 { myContinue() } // skip even numbers
- println("Using \(x)")
- if x > 9 { myBreak() } // print numbers less than or equal to 11
- }
- // Now for the actual implementation
- // Turns out that I didn't really do much to make this possible
- // C already has this feature built in, so naturally Swift does too
- // I just wrapped up the malloc and free calls so you don't have to worry
- class Jump {
- typealias JumpType = UnsafeMutablePointer<Int32>
- private let jumpSize = UInt(sizeof(jmp_buf))
- let line: JumpType
- init() {
- line = JumpType(malloc(jumpSize))
- }
- deinit {
- free(line)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement