#lang scheme/base
(require
"../tools.ss"
"op.ss"
(for-syntax
"../tools.ss"
"../ns-tx.ss"
scheme/base
"static.ss")
scheme/provide-syntax
"../ns.ss")
(provide
(struct-out asm)
(struct-out dasm)
define-op
define-virtual-ops
define-lowlevel-op
define-lowlevel-ops
(op-combine-out dw here)
asm:
op
op:
op-apply
)
(define-struct asm (fn name))
(define-struct dasm (fn))
(define-syntax-rule (asm: name) (ns (op asm) name))
(define-syntax (op: stx)
(syntax-case stx ()
((_ rator . rands)
(begin
(op-check-syntax #'(rator . rands))
#`(list (asm: rator) . rands)))))
(define ((asm-predicate name) x)
(let* ((n (asm-name x))
(p (eq? name n)))
p))
(define-syntax (define-op stx)
(syntax-case stx ()
((_ name formals asm-body dasm-body)
(let ((op-name (ns-prefixed #'(op info) #'name)))
#`(begin
#,@(let ((local-static (syntax-local-value op-name (lambda () #f))))
(if local-static
(begin '())
(list #'(ns (op info) (define-syntax name (make-op-static 'formals))))))
(ns (op ?) (define name (asm-predicate 'name)))
(ns (op asm) (define name (make-asm asm-body 'name)))
(ns (op dasm) (define name (and
dasm-body
(make-dasm
(dasm-body
(ns (op asm) name)) )))))))))
(define-syntax-rule (define-lowlevel-op (name addr . formals) . body)
(define-op
name
formals
(let ((name (lambda (addr . formals) . body))) name)
#f))
(define-syntax-rule (define-lowlevel-ops (def ...) ...)
(begin (define-lowlevel-op def ...) ...))
(define-syntax-rule (define-virtual-ops (op . args) ...)
(begin
(begin
(define-lowlevel-op (op addr . args)
(error 'asm-pseudo-op "~s" 'op))) ...))
(define-lowlevel-op (here addr) `(,addr))
(define-lowlevel-op (dw addr w) `(,(int w)))
(define (op-apply ins start-address)
(apply (asm-fn (car ins)) start-address (cdr ins)))