packages feed

cpsa-2.2.12: src/cpsaops.scm

#!/usr/bin/guile \
-e main -s
!#
;;; For an R6RS script, add an import statement.

;; This program simply extracts the operation form in a skeleton
;; and prints it.
(define (consume form)
  (let ((op (skel-assq 'operation form)))
    (cond (op (write op) (newline)))))

;;; Is form a defskeleton that can be used with assq?

(define (skel? form)
  (and (pair? form)
       (eq? 'defskeleton (car form))
       (pair? (cdr form))
       (alist? (cddr form))))

(define (alist? form)			; Is form a list of pairs?
  (or (null? form)
      (and (pair? form)
	   (pair? (car form))
	   (alist? (cdr form)))))

;;; Extract pieces from the top-level form

(define (skel-assq key form)
  (and (skel? form)
       (assq key (cddr form))))

(define (skel-label form)
  (and (skel? form)
       (let ((form (skel-assq 'label form)))
	 (and form
	      (pair? (cdr form))
	      (null? (cddr form))
	      (number? (cadr form))
	      (cadr form)))))

;;; The main driver loop and command-line processing

;;; The main loop calls consume on each S-expression read from the
;;; current input.

(define (filter)
  (do ((form (read) (read)))
      ((eof-object? form))
    (consume form)))

;;; A file description is #f for the standard port, or a file name
;;; that is a non-empty string that does not start with hyphen.

(define (file-description? file)
   (or (not file)
       (and (> (string-length file) 0)
	    (not (char=? #\- (string-ref file 0))))))

;;; After command-line processing, this routine opens files as needed.

(define (go input output)
  (cond ((not (file-description? input))
	 (display-error "bad input file name"))
	((not (file-description? output))
	 (display-error "bad output file name"))
	(input
	 (with-input-from-file input
	   (lambda ()
	     (if output
		 (with-output-to-file output filter)
		 (filter)))))
	(output
	 (with-output-to-file output filter))
	(else
	 (filter))))

;;; Parse command-line arguments and pass the result to the go function.

(define (main args)
  (let loop ((args (cdr args)) (output #f))
    (cond ((null? args) 		; No input file specified
	   (go #f output))
	  ((string=? (car args) "-h")
	   (display-help))		; Print help message
	  ((string=? (car args) "-o")
	   (if (null? (cdr args))
	       (display-error "bad args")
	       (loop (cddr args) (cadr args)))) ; Found an output file
	  ((null? (cdr args))		; An input file was specified
	   (go (car args) output))
	  (else
	   (display-error "bad args")))))

(define (display-help)
  (display-error "cpsaops [-h] [-o FILE] [FILE]"))

(define (display-error obj)
  (display obj (current-error-port))
  (newline (current-error-port)))

;;; For an R6RS script, add the following:
;;; (main (command-line))