#lang scheme/base
(require
"../tools.ss"
"../target.ss"
"../scat.ss"
"../op.ss"
scheme/match)
(provide
(all-defined-out))
(define-struct pattern-srcloc (file line col))
(define format-pattern-srcloc
(match-lambda
((struct pattern-srcloc (file line col))
(format "~a:~a:~a:" file line col))))
(define (macro/append-reverse code rest)
(if (procedure? code) (cons code rest)
(append (reverse code) rest)))
(define (at-most lst n [trunc-tail '()])
(cond
((null? lst) '())
((zero? n) trunc-tail)
(else
(cons (car lst)
(at-most
(cdr lst)
(- n 1)
trunc-tail)))))
(define (pattern-failed name asm)
(error 'asm-pattern
"match failed for: ~a, asm:\n~a"
name
(apply string-append
(map (lambda (ins) (instruction->string ins "\n"))
(reverse (at-most asm 4 '(...)))))))
(define (with-match-error-handler name asm thunk)
(with-handlers
((exn:misc:match?
(lambda (ex)
(pattern-failed name asm))))
(thunk)))
(define (pattern-tx->macro name xform)
(define (k/asm asm-in)
(let ((asm
(with-match-error-handler
name asm-in
(lambda () (xform asm-in)))))
(cond
((null? asm) (values id '()))
((procedure? (car asm)) (uncons asm)) ((list? (car asm)) (values id asm)) (else
(error 'pattern-result-type-error
"~a" asm)))))
(state-lambda stack
(asm)
(let-values
(((k asm+) (k/asm asm)))
(k (update asm+)))))
(define (check-ops asm-find records)
(for-each*
(lambda (name . occurances)
(let ((asm (asm-find name)))
(map* (lambda (arity f l c p s)
(define (err msg)
(error msg "~a:~a:~a: ~a" f l c name) )
(unless asm
(err 'undefined-opcode))
(let ((n+1 (procedure-arity asm)))
(unless
(if (number? n+1)
(= arity (- n+1 1))
(>= arity (- (arity-at-least-value n+1) 1)))
(err 'asm-arity-error)
)))
occurances)))
records))