live/interaction-state.ss
#lang scheme/base

;; Compiler state management for incremental development.  This
;; extends comp/code.ss which is just for static module state.

(require
 "../rpn.ss"
 "../scat.ss"
 "../tools.ss"
 "../target.ss"
 "../asm.ss"
 "../code.ss" 
 "tethered.ss"
 "commands.ss"
 "../port/ihex.ss"
 scheme/control)

(provide
 (all-defined-out))


;; Marks will only affect the code pointers, not the content of the
;; current namespace. It's a crude hacked-up mechanism.  Use with
;; care.

;; FIXME: make interpretation depend on the value of the pointers:
;; i.e. don't execute code that's beyond the current code mark.

(define *marks* '())
(define (mark) (push! *marks* (code-pointers)))

(define (empty [bits 5] ;; 2^5 words in a block
               [erase-from-block void])
  (define (get x) (cadr (assq x (code-pointers))))
  (unless (null? *marks*)
    (code-pointers-set! (pop! *marks*)))
  (let ((code (bit-ceil (get 'code) bits))
        (data (get 'data)))
    (code-pointers-set! `((code ,code)
                         (data ,data)))
    (printf "FIXME: erasing: ")
    (erase-from-block (>>> code bits))))


;; INCREMENTAL UPLOAD
(define (commit [bin (code->binary)])
  (unless (null? bin)
    (upload-bytes bin)
    (code-clear!)))


;; Scheme -> Scat + Target commands
(define-syntax-rule (0cmd: command ...)
  (begin
    (snarf as-void (scat) (() (command ...)))
    (prefix-parser-types (target) (0cmd command ...))))

(0cmd: commit code-print mark empty)

(prefix-parsers
 (target)
 ((ul w) (empty mark load w commit)))