(in-package :parse-html) (defvar if*-keyword-list '("then" "thenret" "else" "elseif")) (defmacro if* (&rest args) (do ((xx (reverse args) (cdr xx)) (state :init) (elseseen nil) (totalcol nil) (lookat nil nil) (col nil)) ((null xx) (cond ((eq state :compl) `(cond ,@totalcol)) (t (error "if*: illegal form ~s" args)))) (when (and (symbolp (car xx)) (member (symbol-name (car xx)) if*-keyword-list :test #'string-equal)) (setq lookat (symbol-name (car xx)))) (case state (:init (if lookat (if (string-equal lookat "thenret") (setq col nil state :then) (error "if*: bad keyword ~a" lookat)) (progn (setq state :col col nil) (push (car xx) col)))) (:col (if lookat (cond ((string-equal lookat "else") (cond (elseseen (error "if*: multiples elses"))) (setq elseseen t) (setq state :init) (push `(t ,@col) totalcol)) ((string-equal lookat "then") (setq state :then)) (t (error "if*: bad keyword ~s" lookat))) (push (car xx) col))) (:then (if lookat (error "if*: keyword ~s at the wrong place " (car xx)) (progn (setq state :compl) (push `(,(car xx) ,@col) totalcol)))) (:compl (unless (string-equal lookat "elseif") (error "if*: missing elseif clause ")) (setq state :init)))))