;; load/save purrr configuration dictionaries (state file) ;; Each project has 3 state files. ;; init.ss initial file, does not include monitor dictionary ;; monitor.ss contains pristine boot monitor dictionary ;; prj.ss current working state ;; The idea is that you do one of the following: ;; * Start from scratch (init.ss) and compile your own monitor code, ;; which gives a monitor.ss dictionary and a monitor.hex binary file ;; to be uploaded with a PIC programmer. ;; * Start with a working monitor on the PIC chip and a corresponding ;; monitor.ss dictionary file. (module config mzscheme (require "dict.ss" "list-utils.ss" "hhash.ss" "io-utils.ss" (lib "pretty.ss") (lib "match.ss")) (provide load-project save-project) (define *project-defaults* '((forth) (dict) (mark) (asm) (point (dasm . 0)) (file (init-state "init.state") ;; empty state (monitor-state "monitor.state") ;; state with boot loader (state "current.state") ;; the day-to-day state file (monitor "monitor.f") ;; monitor source code (hex "monitor.hex") ;; intel .hex binary output ))) ;; Read a state file, checking consistency. This reads only the ;; first form, the rest is ignored. Uses hhash intermediate state. (define (read-state . port) (let ((dict (hhash->dict (hhash-accumulate! (dict->hhash *project-defaults*) (dict->hhash (match (apply read port) (('project . dict) dict) (other (error 'invalid-project-format "~a" other)))))))) ;; (pretty-print dict) dict)) (define (true ex) #t) (define (false ex) #f) (define (state dir filename) (let ((filename (string-append dir filename))) (with-handlers ((exn:fail:filesystem? false)) (let ((port (open-input-file filename))) (printf "loading ~a\n" filename) (read-state port))))) ;; Read new project state, checking prj, monitor, init files. (define (load-project dir component) (define (file tag) (format "/~a.state" tag)) (or (match component ('current ;; defaults to one of the following: (or (state dir (file 'current)) (state dir (file 'monitor)) (state dir (file 'init)))) (tag (state dir (file tag)))) (error 'cannot-load-project-component "in: ~a, component: ~a, cd: ~a" dir component (current-directory)))) (define (save-project state filename) (with-output-to-file/safe filename (lambda () (pretty-print (cons 'project state))))) )