make gosub a continuation

pull/2/head
Matthew Butterick 9 years ago
parent 574bb06fb7
commit 93db2015af

@ -13,8 +13,8 @@
(remove-duplicates (map syntax->datum (filter (λ(s) (syntax-property s 'id)) (syntax-flatten stx))) eq?))) (remove-duplicates (map syntax->datum (filter (λ(s) (syntax-property s 'id)) (syntax-flatten stx))) eq?)))
(define-macro (basic-module-begin (basic-program PROGRAM-LINE ...)) (define-macro (basic-module-begin (basic-program PROGRAM-LINE ...))
(with-pattern (with-pattern ([(UNIQUE-ID ...)
([(UNIQUE-ID ...) (map (compose1 syntax-local-introduce (λ(id) (datum->syntax #f id))) (map (compose1 syntax-local-introduce (λ(id) (datum->syntax #f id)))
(gather-unique-ids #'(PROGRAM-LINE ...)))]) (gather-unique-ids #'(PROGRAM-LINE ...)))])
#'(#%module-begin #'(#%module-begin
(define UNIQUE-ID 0) ... (define UNIQUE-ID 0) ...
@ -63,23 +63,15 @@
(define return-stack empty) (define return-stack empty)
(define (do-gosub this-line where) (define (basic:gosub where)
(if (or (empty? return-stack) (let/cc return-k
(not (= this-line (car return-stack)))) (set! return-stack (cons return-k return-stack))
(begin (basic:goto where)))
(set! return-stack (cons this-line return-stack))
(basic:goto where))
;; if (= number (car return-stack))
;; then we reached this line by `return`, which means the end of a gosub
(set! return-stack (cdr return-stack))))
(struct $line (number thunk) #:transparent) (struct $line (number thunk) #:transparent)
(define-macro line (define-macro (line NUMBER . STATEMENTS)
[(_ NUMBER (statement "gosub" WHERE))
#'($line NUMBER (λ () (do-gosub NUMBER WHERE)))]
[(_ NUMBER . STATEMENTS)
#'($line NUMBER (λ () (with-handlers ([end-line-signal? (λ _ #f)]) #'($line NUMBER (λ () (with-handlers ([end-line-signal? (λ _ #f)])
. STATEMENTS)))]) . STATEMENTS))))
(define-macro statement (define-macro statement
[(statement ID "=" EXPR) #'(set! ID EXPR)] [(statement ID "=" EXPR) #'(set! ID EXPR)]
@ -157,7 +149,10 @@
(define (basic:goto where) where) (define (basic:goto where) where)
(define (basic:return) (car return-stack)) (define (basic:return)
(define return-k (car return-stack))
(set! return-stack (cdr return-stack))
(return-k #f))
(define (basic:stop) (basic:end)) (define (basic:stop) (basic:end))
(define (basic:end) (raise-end-program-signal)) (define (basic:end) (raise-end-program-signal))

@ -1,9 +1,9 @@
#lang br/demo/basic #lang br/demo/basic
10 GOSUB 50 10 GOSUB 50
15 PRINT "BOOM" 15 PRINT "2 of 3"
17 GOSUB 30 17 GOSUB 30
20 END 20 END
30 PRINT "YAY" 30 PRINT "3 of 3"
40 RETURN 40 RETURN
50 PRINT "50" 50 PRINT "1 of 3"
55 RETURN 55 RETURN
Loading…
Cancel
Save