So, I THINK, I understand how continuations mostly work in Scheme, but it's hard for me to figure out how to use it instead of recursion.
We are provided with working code for make-matcher (only basic pattern matching), which already does everything we want. You give it a sample, and it creates a layout for you that you can use to search for fragments for this template. The connector accepts an acceptor that gives it results, and if the result is not accepted, it recursively descends to the next part of the fragment and continues to move.
Now we need to basically modify it to use extensions instead of acceptors. It returns a suffix (left over material from a template that has not been matched) and continued, so something like
(let ((suffix (car match-result)) (backtrack (cdr match-result)))
It would give us a suffix and a backtrack function, which we could call a continuation.
So, for reference, the source 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 use the or-matcher example for an example. At the moment, if he finds a match, he gives the result to the acceptor, and if the acceptor does not like the result, he continues, looking for the next possible answer. If I wanted to use the continuation, I would have to force it to exit after it finds the result and use call / cc to save the current state of the program. I'm just ... not quite sure WHERE I have to put an escape and call / cc. I think I need to add a base register, as I donβt have an acceptor that tells me that my answer is correct or incorrect, but ...
I think that if someone just gives me some indications of the main changes that I can make, I can probably figure it out. I am at a time when I understand the individual parts of WHAT, but I canβt see exactly the big picture of how to implement it.