;; -*- Scheme -*-
;;
;; $Id: mawk05.scm,v 1.1 1998/03/16 07:58:43 foner Exp $

;;-----------

(require 'substring:search)

;;-----------

(define mawk:pattern-match::helper
  (lambda (line line-num state actions)
    (let ((next-action
	   (lambda (state)
	     (mawk:pattern-match::helper line line-num state (cdr actions))))
	  (next-line (lambda (state) state)))
      (if (null? actions)
	  state
	  ((car actions) line line-num next-action next-line state)))))


;;+doc
;; procedure: mawk:pattern-match
;; arguments: pattern/action ...
;;
;; Takes a list of PATTERN/ACTION pairs and creates a pattern matcher out
;; of them.
;;
;; (mawk:pattern-match
;;  (mawk:pattern/action
;;    (mawk:pattern:make (m #\#) (s* ws) (m "include") (s* ws) (m #\") (f #\"))
;;    mawk:action:display-line)
;;  (mawk:pattern/action
;;    (mawk:pattern:make (m #\#) (s* ws) (m "ifdef") (s* ws) (m #\") (f #\"))
;;     (lambda (line line-num next-line state)
;;       (lambda (define-name)
;;         ; do something with DEFINE-NAME
;;         ))))
;;
;; where m   = mawk:pattern:match
;;       s*  = mawk:pattern:skip*
;;       f   = mawk:pattern:find
;;       ws  = char-set:whitespace
;;-doc

(define mawk:pattern-match
  (lambda actions
    (lambda (line line-num state)
      (mawk:pattern-match::helper line line-num state actions))))


;;+doc
;; procedure: mawk:pattern/action
;; arguments: pattern action[line line-num next-line state]
;; signature: pattern x (string x int x (a -> a) x a -> a) -> a   XXX?
;;
;; Create a PATTERN/ACTION pair.  When applied to a line, this will
;; call ACTION if PATTERN matches the line.
;;
;; For example, the following will match lines starting with a specific
;; sort of "#include" directive and display those lines.
;;
;;  (mawk:pattern/action
;;    (mawk:pattern:make (m #\#) (s* ws) (m "include") (s* ws) (m #\") (f #\"))
;;    mawk:action:display-line)
;;
;; where m   = mawk:pattern:match
;;       s*  = mawk:pattern:skip*
;;       f   = mawk:pattern:find
;;       ws  = char-set:whitespace
;;-doc

(define mawk:pattern/action
  (lambda (pattern action)
    (lambda (line line-num next-action next-line state)
      (let* ((foo (action line line-num next-line state))
	     (xxx (lambda (_ . r) (apply foo r)))
	     (bar (lambda (_) (next-action state)))
	     (sl (string-length line)))
	(apply substring:search line 0 sl xxx bar pattern)))))


;;+doc
;; procedure: mawk:action:display-line
;; arguments: none
;; signature: () -> 
;;
;; An action that displays the current line
;;-doc

(define mawk:action:display-line
  (lambda (line line-num next-line state)
    (lambda ()
      (display line)
      (newline)
      state)))

;; eof
