So I THINK I understand how continuations basically work in Scheme, but I'm having trouble figuring out how to use it instead of recursion.
We are given working code for make-matcher (just basic pattern matching) that already does everything we want it to. You give it a pattern and it creates a matcher for you that you can use to search through fragments for that pattern. The matcher takes an acceptor that it gives it's results to, and if the result isn't accepted, it recursively descends into the next part of the fragment and keeps going.
Now, what we have to do is basically is modify it to use continuations instead of acceptors. It returns the suffix (left over stuff from the pattern that wasn't matched) and a continuation, so something like
(let ((suffix (car match-result))
(backtrack (cdr match-result)))
Would give us the suffix and a function backtrack we could call to keep going.
So for reference, the original code
(define match-junk
(lambda (k frag accept)
(or (accept frag)
(and (< 0 k)
(pair? frag)
(match-junk (- k 1) (cdr frag) accept)))))
(define match-*
(lambda (matcher frag accept)
(or (accept frag)
(matcher frag
(lambda (frag1)
(and (not (eq? frag frag1))
(match-* matcher frag1 accept)))))))
(define make-matcher
(lambda (pat)
(cond
((symbol? pat)
(lambda (frag accept)
(and (pair? frag)
(eq? pat (car frag))
(accept (cdr frag)))))
((eq? 'or (car pat))
(let make-or-matcher ((pats (cdr pat)))
(if (null? pats)
(lambda (frag accept) #f)
(let ((head-matcher (make-matcher (car pats)))
(tail-matcher (make-or-matcher (cdr pats))))
(lambda (frag accept)
(or (head-matcher frag accept)
(tail-matcher frag accept)))))))
((eq? 'list (car pat))
(let make-list-matcher ((pats (cdr pat)))
(if (null? pats)
(lambda (frag accept) (accept frag))
(let ((head-matcher (make-matcher (car pats)))
(tail-matcher (make-list-matcher (cdr pats))))
(lambda (frag accept)
(head-matcher frag
(lambda (frag1)
(tail-matcher frag1 accept))))))))
((eq? 'junk (car pat))
(let ((k (cadr pat)))
(lambda (frag accept)
(match-junk k frag accept))))
((eq? '* (car pat))
(let ((matcher (make-matcher (cadr pat))))
(lambda (frag accept)
(match-* matcher frag accept)))))))
So let's use the or-matcher for an example. At the moment if it finds a match, it gives the result to the acceptor and if the acceptor doesn't like the result, it continues on, looking for the next possible answer. If I wanted to use continuation, I would have to force it to exit after it finds a result and use call/cc to store the current state of the program. I'm just...not exactly sure WHERE I should put the escape and call/cc. I think I need to add a base case now since I don't have an acceptor telling me if my answer is true or false but...
I think if someone just gives me some pointers about the main changes to make, I can probably figure it out. I'm at that point where I understand the individual parts of WHAT but can't exactly see the big picture of how to implement it.