|
|
@ -1,8 +1,7 @@
|
|
|
|
#lang br
|
|
|
|
#lang br/quicklang
|
|
|
|
(require (for-syntax syntax/strip-context))
|
|
|
|
(require (for-syntax syntax/strip-context))
|
|
|
|
(provide #%top-interaction #%app #%datum
|
|
|
|
(provide #%top-interaction #%app #%datum
|
|
|
|
(rename-out [basic-module-begin #%module-begin])
|
|
|
|
(rename-out [basic-module-begin #%module-begin])
|
|
|
|
(rename-out [basic-top #%top])
|
|
|
|
|
|
|
|
(all-defined-out))
|
|
|
|
(all-defined-out))
|
|
|
|
|
|
|
|
|
|
|
|
; BASIC implementation details
|
|
|
|
; BASIC implementation details
|
|
|
@ -20,13 +19,9 @@
|
|
|
|
#'(#%module-begin
|
|
|
|
#'(#%module-begin
|
|
|
|
(define UNIQUE-ID 0) ...
|
|
|
|
(define UNIQUE-ID 0) ...
|
|
|
|
(provide UNIQUE-ID ...)
|
|
|
|
(provide UNIQUE-ID ...)
|
|
|
|
(run PROGRAM-LINE ... (line #f (statement "end"))))))
|
|
|
|
(run (sort (cons (line +inf.0 (statement "end"))
|
|
|
|
|
|
|
|
(list PROGRAM-LINE ...)) #:key $line-number <)))))
|
|
|
|
|
|
|
|
|
|
|
|
; #%app and #%datum have to be present to make #%top work
|
|
|
|
|
|
|
|
(define-macro (basic-top . ID)
|
|
|
|
|
|
|
|
#'(begin
|
|
|
|
|
|
|
|
(displayln (format "got unbound identifier: ~a" 'ID))
|
|
|
|
|
|
|
|
(procedure-rename (λ xs (cons 'ID xs)) (string->symbol (format "undefined:~a" 'ID)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(struct exn:line-not-found exn:fail ())
|
|
|
|
(struct exn:line-not-found exn:fail ())
|
|
|
|
(define (raise-line-not-found-error ln)
|
|
|
|
(define (raise-line-not-found-error ln)
|
|
|
@ -43,13 +38,13 @@
|
|
|
|
(define (raise-end-line-signal)
|
|
|
|
(define (raise-end-line-signal)
|
|
|
|
(raise (end-line-signal "" (current-continuation-marks))))
|
|
|
|
(raise (end-line-signal "" (current-continuation-marks))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (run . line-list)
|
|
|
|
(define (run line-list)
|
|
|
|
(define lines (list->vector line-list))
|
|
|
|
(define lines (list->vector line-list))
|
|
|
|
(define (find-index ln)
|
|
|
|
(define (find-index ln)
|
|
|
|
(or
|
|
|
|
(or
|
|
|
|
(for/or ([idx (in-range (vector-length lines))])
|
|
|
|
(for/or ([idx (in-range (vector-length lines))])
|
|
|
|
(and (= ($line-number (vector-ref lines idx)) ln)
|
|
|
|
(and (= ($line-number (vector-ref lines idx)) ln)
|
|
|
|
idx))
|
|
|
|
idx))
|
|
|
|
(raise-line-not-found-error ln)))
|
|
|
|
(raise-line-not-found-error ln)))
|
|
|
|
(void
|
|
|
|
(void
|
|
|
|
(with-handlers ([end-program-signal? void])
|
|
|
|
(with-handlers ([end-program-signal? void])
|
|
|
@ -61,15 +56,15 @@
|
|
|
|
(find-index maybe-line-number)
|
|
|
|
(find-index maybe-line-number)
|
|
|
|
(add1 program-counter)))))))
|
|
|
|
(add1 program-counter)))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define return-stack empty)
|
|
|
|
(define current-return-stack (make-parameter empty))
|
|
|
|
|
|
|
|
|
|
|
|
(define (basic:gosub where)
|
|
|
|
(define (basic:gosub where)
|
|
|
|
(let/cc return-k
|
|
|
|
(let/cc return-k
|
|
|
|
(set! return-stack (cons return-k return-stack))
|
|
|
|
(current-return-stack (cons return-k (current-return-stack)))
|
|
|
|
(basic:goto where)))
|
|
|
|
(basic:goto where)))
|
|
|
|
|
|
|
|
|
|
|
|
(define current-line (make-parameter #f))
|
|
|
|
(define current-line (make-parameter #f))
|
|
|
|
(struct $line (number thunk))
|
|
|
|
(struct $line (number thunk) #:transparent)
|
|
|
|
(define-macro (line NUMBER . STATEMENTS)
|
|
|
|
(define-macro (line NUMBER . STATEMENTS)
|
|
|
|
#'($line NUMBER (λ ()
|
|
|
|
#'($line NUMBER (λ ()
|
|
|
|
(current-line NUMBER)
|
|
|
|
(current-line NUMBER)
|
|
|
@ -89,9 +84,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
(define-macro-cases basic:let
|
|
|
|
(define-macro-cases basic:let
|
|
|
|
[(_ (id-expr ID) EXPR)
|
|
|
|
[(_ (id-expr ID) EXPR)
|
|
|
|
#'(begin
|
|
|
|
#'(set! ID EXPR)]
|
|
|
|
#;(displayln (format "setting ~a = ~a in ~a" 'ID EXPR (current-line)))
|
|
|
|
|
|
|
|
(set! ID EXPR))]
|
|
|
|
|
|
|
|
[(_ (id-expr ID DIM-IDX ...) EXPR)
|
|
|
|
[(_ (id-expr ID DIM-IDX ...) EXPR)
|
|
|
|
#'(array-set! ID DIM-IDX ... EXPR)])
|
|
|
|
#'(array-set! ID DIM-IDX ... EXPR)])
|
|
|
|
|
|
|
|
|
|
|
@ -151,11 +144,7 @@
|
|
|
|
[(_ BASE) #'BASE]
|
|
|
|
[(_ BASE) #'BASE]
|
|
|
|
[(_ BASE POWER) #'(expt BASE POWER)])
|
|
|
|
[(_ BASE POWER) #'(expt BASE POWER)])
|
|
|
|
|
|
|
|
|
|
|
|
(define-macro-cases number
|
|
|
|
(define-macro-cases maybe-negative-val
|
|
|
|
[(_ "-" NUM) #'(- NUM)]
|
|
|
|
|
|
|
|
[(_ NUM) #'NUM])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define-macro-cases id-val
|
|
|
|
|
|
|
|
[(_ "-" ID) #'(- ID)]
|
|
|
|
[(_ "-" ID) #'(- ID)]
|
|
|
|
[(_ ID) #'ID])
|
|
|
|
[(_ ID) #'ID])
|
|
|
|
|
|
|
|
|
|
|
@ -165,11 +154,11 @@
|
|
|
|
(define (println [x ""])
|
|
|
|
(define (println [x ""])
|
|
|
|
(define xstr (format "~a" x))
|
|
|
|
(define xstr (format "~a" x))
|
|
|
|
(displayln xstr)
|
|
|
|
(displayln xstr)
|
|
|
|
(set! current-print-position 0))
|
|
|
|
(current-print-position 0))
|
|
|
|
(define (print x)
|
|
|
|
(define (print x)
|
|
|
|
(define xstr (format "~a" x))
|
|
|
|
(define xstr (format "~a" x))
|
|
|
|
(display xstr)
|
|
|
|
(display xstr)
|
|
|
|
(set! current-print-position (+ current-print-position (string-length xstr))))
|
|
|
|
(current-print-position (+ (current-print-position) (string-length xstr))))
|
|
|
|
|
|
|
|
|
|
|
|
(match args
|
|
|
|
(match args
|
|
|
|
[#f (println)]
|
|
|
|
[#f (println)]
|
|
|
@ -186,8 +175,8 @@
|
|
|
|
[(list print-list-items ...)
|
|
|
|
[(list print-list-items ...)
|
|
|
|
(for-each println print-list-items)]))
|
|
|
|
(for-each println print-list-items)]))
|
|
|
|
|
|
|
|
|
|
|
|
(define current-print-position 0)
|
|
|
|
(define current-print-position (make-parameter 0))
|
|
|
|
(define (TAB num) (make-string (max 0 (INT (- num current-print-position))) #\space))
|
|
|
|
(define (TAB num) (make-string (max 0 (INT (- num (current-print-position)))) #\space))
|
|
|
|
(define (INT num) (inexact->exact (truncate num)))
|
|
|
|
(define (INT num) (inexact->exact (truncate num)))
|
|
|
|
(define (SIN num) (sin num))
|
|
|
|
(define (SIN num) (sin num))
|
|
|
|
(define (ABS num) (inexact->exact (abs num)))
|
|
|
|
(define (ABS num) (inexact->exact (abs num)))
|
|
|
@ -215,8 +204,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define (basic:return)
|
|
|
|
(define (basic:return)
|
|
|
|
(define return-k (car return-stack))
|
|
|
|
(define return-k (car (current-return-stack)))
|
|
|
|
(set! return-stack (cdr return-stack))
|
|
|
|
(current-return-stack (cdr (current-return-stack)))
|
|
|
|
(return-k #f))
|
|
|
|
(return-k #f))
|
|
|
|
|
|
|
|
|
|
|
|
(define (basic:stop) (basic:end))
|
|
|
|
(define (basic:stop) (basic:end))
|
|
|
@ -228,13 +217,13 @@
|
|
|
|
#'(begin
|
|
|
|
#'(begin
|
|
|
|
(set! ID (make-array (apply shape (append (list 0 (add1 EXPR)) ...)))) ...))
|
|
|
|
(set! ID (make-array (apply shape (append (list 0 (add1 EXPR)) ...)))) ...))
|
|
|
|
|
|
|
|
|
|
|
|
(define for-stack empty)
|
|
|
|
(define current-for-stack (make-parameter empty))
|
|
|
|
|
|
|
|
|
|
|
|
(define (push-for-stack thunk)
|
|
|
|
(define (push-for-stack thunk)
|
|
|
|
(set! for-stack (cons thunk for-stack)))
|
|
|
|
(current-for-stack (cons thunk (current-for-stack))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (pop-for-stack)
|
|
|
|
(define (pop-for-stack)
|
|
|
|
(set! for-stack (cdr for-stack)))
|
|
|
|
(current-for-stack (cdr (current-for-stack))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (in-closed-interval? x left right)
|
|
|
|
(define (in-closed-interval? x left right)
|
|
|
|
(define cmp (if (< left right) <= >=))
|
|
|
|
(define cmp (if (< left right) <= >=))
|
|
|
@ -258,10 +247,10 @@
|
|
|
|
#f))]) ; return value for first visit to line
|
|
|
|
#f))]) ; return value for first visit to line
|
|
|
|
|
|
|
|
|
|
|
|
(define (handle-next [which #f])
|
|
|
|
(define (handle-next [which #f])
|
|
|
|
(unless (pair? for-stack) (error 'next "for-stack is empty"))
|
|
|
|
(unless (pair? (current-for-stack)) (error 'next "for-stack is empty"))
|
|
|
|
(define for-thunk (cdr (if which
|
|
|
|
(define for-thunk (cdr (if which
|
|
|
|
(assq which for-stack)
|
|
|
|
(assq which (current-for-stack))
|
|
|
|
(car for-stack))))
|
|
|
|
(car (current-for-stack)))))
|
|
|
|
(for-thunk))
|
|
|
|
(for-thunk))
|
|
|
|
|
|
|
|
|
|
|
|
(define-macro (basic:next VAR ...)
|
|
|
|
(define-macro (basic:next VAR ...)
|
|
|
|