|
|
@ -13,12 +13,12 @@
|
|
|
|
(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) ...
|
|
|
|
(run PROGRAM-LINE ...))))
|
|
|
|
(run PROGRAM-LINE ...))))
|
|
|
|
|
|
|
|
|
|
|
|
; #%app and #%datum have to be present to make #%top work
|
|
|
|
; #%app and #%datum have to be present to make #%top work
|
|
|
|
(define-macro (basic-top . ID)
|
|
|
|
(define-macro (basic-top . ID)
|
|
|
@ -63,30 +63,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
(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)]
|
|
|
|
[(statement PROC-NAME . ARGS)
|
|
|
|
[(statement PROC-NAME . ARGS)
|
|
|
|
(with-pattern
|
|
|
|
(with-pattern
|
|
|
|
([PROC-ID (prefix-id "basic:" #'PROC-NAME)])
|
|
|
|
([PROC-ID (prefix-id "basic:" #'PROC-NAME)])
|
|
|
|
#'(PROC-ID . ARGS))])
|
|
|
|
#'(PROC-ID . ARGS))])
|
|
|
|
|
|
|
|
|
|
|
|
(define-macro basic:if
|
|
|
|
(define-macro basic:if
|
|
|
|
[(_ COND-EXPR TRUE-EXPR FALSE-EXPR)
|
|
|
|
[(_ COND-EXPR TRUE-EXPR FALSE-EXPR)
|
|
|
@ -114,8 +106,8 @@
|
|
|
|
#'(cond->int (equal? SUM COMP-EXPR))] ; special case because `=` is overloaded in basic
|
|
|
|
#'(cond->int (equal? SUM COMP-EXPR))] ; special case because `=` is overloaded in basic
|
|
|
|
[(_ SUM OP-STR COMP-EXPR)
|
|
|
|
[(_ SUM OP-STR COMP-EXPR)
|
|
|
|
(with-pattern
|
|
|
|
(with-pattern
|
|
|
|
([OP (replace-context #'here (prefix-id #'OP-STR))])
|
|
|
|
([OP (replace-context #'here (prefix-id #'OP-STR))])
|
|
|
|
#'(cond->int (OP SUM COMP-EXPR)))])
|
|
|
|
#'(cond->int (OP SUM COMP-EXPR)))])
|
|
|
|
|
|
|
|
|
|
|
|
(define <> (compose1 not equal?))
|
|
|
|
(define <> (compose1 not equal?))
|
|
|
|
|
|
|
|
|
|
|
@ -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))
|
|
|
|