#lang scheme/base

;; This module exports signatures used to interface all components in
;; the Staapl language.

;; Components in staapl are collections of macros or "op
;; transformers".  Macros are Scat functions of type:
;;   (stack-of op) -> (stack-of op)
;; The these macros are implemented as scheme functions and thus not
;; to be confused with scheme syntax transformers.  In general the
;; compilation stage is shifted one level in Staapl code: target code
;; is always data in the scheme sense.
;; The "op" objects represent the target machine's operations.  These
;; objects contain information that lives at macro compile time, they
;; are information embedded in the signature to allow separate
;; compilation of op transformers.

(require scheme/unit
(provide (all-defined-out))

(define-syntax-rule (define-macro-set name (w ...))
  (ns (macro) (define-signature name (w ...))))

(define-syntax-rule (define-scat-set name (w ...))
  (ns (scat) (define-signature name (w ...))))

(define-syntax-rule (define-op-set name (w ...))
    (ns (op) (define-signature op^ (w ...)))
    (ns (asm) (define-signature asm^ (w ...)))
    (ns (dasm) (define-signature dasm^ (w ...)))
    (define-signature name ((open op^) (open asm^) (open dasm^)))))


;; These are signatures containing static information about the
;; opcodes.  Currently this is only the formal argument list used in
;; arity checking and error reporting.

;; FIXME: because qw is used at the very core of the macro code
;; transformer, scat needs to be re-implemented as a unit before this
;; will work.  I'll try to brin the code to a point where some
;; modules are operational so the change to scat can be
;; gradually propagated upward.

;; (define-op-signature op-quote-decl^ op-quote-impl^ ;; code/data distinction
;;   (cw val)
;;   (qw val)) 

;; (define-op-signature op-jump-decl^ op-quote-impl^ ;; control flow
;;   (label l)
;;   (jw l)
;;   (jw/false l)
;;   (exit))


;; The label^ set defines branch target representation (sym), branch
;; target marking (label:) and branch instructions (cw jw jw/if exit).
;; These behave as RPN assembler macros.
(define-macro-set jump^   (sym label: >label cw jw exit reachable))
(define-macro-set cjump^  (jw/false))
(define-macro-set ram^    (allot))

;; Forth style control words on top of the jump representation.
(define-macro-set control^ (m-swap m> >m word>m if else then begin again
                            do while repeat until))

;; Target code placement.
(define-macro-set org^ (org org-push org-pop here))
;; Compiler internal interface.
(define-macro-set cfg^ (menter mleave mexit close-chain word-org word-org-push ";" "."))

;; Basic stack manip + ALU
(define-macro-set stack^       (dup swap drop + - * / not))
(define-macro-set comma-extra^ (dw> "string,"))
(define-macro-set comma^       (","))
(define-macro-set code^        (compose address i execute compile nop))
(define-macro-set rstack^      (for next >x x> swap>x x- +x))

;; Machine parameters used to parameterize the CFG compiler.
(define-macro-set machine^  (code-size))

;; PIC18 specific.  Move more of these to standard wordsets.
(define-macro-set stack-extra^ (and or xor pow >>> <<< 1+ 1- min max odd? toggle neg >> << 2/ over nip))
(define-macro-set memory-extra^ (1-! 1+! swap! ! @ high low high? low? +! or! and! xor!))

(define-signature instantiate^
  (;; Compiler invokation.
   ;; These functions apply appropriate wrappers before
   ;; the objects are defined in the namespace.