pic18.ss
#lang scheme/base

;; Macro Forth for PIC18.

(require
 scheme/control
 "forth/forth-tx.ss"
 "tools.ss"
 (for-syntax scheme/base
             "tools.ss"))

(require/provide

 ;; BASE LANGUAGE
 "coma/macro.ss"    ;; base macro tools

 ;; LANGUAGE/COMPILER
 "coma/comma-unit.ss"       ;; comma^
 "coma/code-unit.ss"        ;; code^
 "control/control-unit.ss"  ;; control^
 "comp/compiler-unit.ss"    ;; jump^
 "pic18/pic18-unit.ss"      ;; PIC18-specific macros
 "pic18/pic18-control-unit.ss"    
 "comp/postprocess.ss"      ;; CFG postprocessing
 
 ;; FORTH PREFIX PARSING
 "coma/macro-forth.ss"      ;; rpn prefix parsing words bound to macro.ss
 "pic18/forth.ss"           ;; PIC18 specific

 ;; FORTH LEXING
 "forth/forth-lex.ss"

 ;; ASSEMBLER
 "asm.ss"
 "pic18/asm.ss"
 "pic18/sig.ss"

 ;; CODE REGISTRY
 "code.ss"
 
 )

(provide (all-defined-out))





;; MACRO LANGUAGE

;; The macro language is implemented in a collection of units.
(define/invoke
  (stack^
   stack-extra^
   memory-extra^
   ram^
   comma^
   code^
   jump^
   cjump^
   control^
   cfg^
   rstack^
   org^
   machine^
   instantiate^
   pic18-assembler^
   pic18-extra^
   pic18-postproc^)
  (pic18@ pic18-control@ comma@ code@ compiler@ control@))


;; COMPILER

;; Inline macro instantiation converts Forth words in postponed form
;; to a control flow graph containing assembly code.

;; Get the postprocessors from the macro namespace.
(define-syntax-rule (postproc name)
  (macro->postprocess (ns (macro) name)
                      ;; 'name  ;; DEBUG
                      ))

(define (pic18-compile->cfg inline-macros)
  (words->cfg!
   (compile-words   ;; functional compiler from instantiated module
    inline-macros)  ;; word definitions passed in by forth-begin-tx
   ;; postprocessor
   (compose
    (postproc opti-save)
    (postproc pseudo)
    )))


;; CODE REGISTRY

;; The parsing step will only produce macros and target labels.  Forth
;; words (as opposed to Forth macros) are collected by the parser in
;; postponed form later to be instantiated.

(define pic18-debug (make-parameter #f))
(define (compile!)
  (code-compile!
   (lambda (in)
     (let ((cfg (pic18-compile->cfg in)))
       (when (pic18-debug)
         (code-print cfg))
       cfg))
   assemble!))
   


;; PARSER

;; Link the parser to the compiler: create defining prefix macros in
;; terms of code wrapping functions and the postponed code registry.
;; In addition to 'forth-begin, this introduces some (macro) prefix
;; parsing words.
(define-forth-parser forth-begin (code-register-postponed!
                                  wrap-macro
                                  wrap-word
                                  wrap-variable))

;; Toplevel begin used for interactive development.
(define-syntax (pic18-begin stx)
  (syntax-case stx ()
    ((_ . code)
     #`(begin
         (forth-begin
          path #,(build-path (home) "pic18") ;; library path
          . code)
         (compile!)))))

;; Module level begin used in pic18/lang.ss
(define-syntax-rule (pic18-module-begin . words)
  (#%plain-module-begin
   (pic18-begin |{| provide forth-load/compile |}| . words)))

;; String read-eval interface.
(define-syntax-rule (forth-compile str)
  (forth-lex-string/cps pic18-begin str))
(define-syntax-rule (forth-load/compile str)
  (forth-begin load str))


;; FIXME: One of the last bits of dynamic residue to eliminate:
(require "comp/state.ss")


(define-dasm-collection dasm-collection)