;;; basport.el - Convert MS BASIC source for portability

(defun basport ()
  (interactive)
  (let ((basport-autofixed 0))
    ;; Convert to Unix-style file coding ...
    (set-buffer-file-coding-system 'unix)
    ;; Automatic fixes ...
    (beginning-of-buffer)
    (while (re-search-forward "^\\([0-9]+ +REM\\)\\([-*0-9]\\)" nil t)
      (progn
	(replace-match "\\1 \\2" nil nil)
	(setq basport-autofixed (1+ basport-autofixed))))
    (beginning-of-buffer)
    (while (re-search-forward "^\\([0-9]+ +REM\\)\\([A-Za-z]\\)" nil t)
      (progn
	(replace-match "\\1 REM\\2" nil nil)
	(setq basport-autofixed (1+ basport-autofixed))))
    (beginning-of-buffer)
    (while (re-search-forward  "\\(PRINT\\|INPUT\\)\\([\":]\\)" nil t)
      (progn
	(replace-match "\\1 \\2" nil nil)
	(setq basport-autofixed (1+ basport-autofixed))))
    (beginning-of-buffer)
    (while (re-search-forward "\\([A-Za-z0-9.] *; *\"\\)\\([A-Za-z0-9]\\)" nil t)
      (progn
	(replace-match "\\1 \\2" nil nil)
	(setq basport-autofixed (1+ basport-autofixed))))
    (beginning-of-buffer)
    (while (re-search-forward "\\(PRINT +\\([A-Za-z0-9.-]+|\\(\"[^\"]\"\\) *[;,] *\\)*[A-Za-z0-9.-]+|\\(\"[^\"]\"\\)\\) *\\([A-Za-z0-9.-\"]\\)" nil t)
; (PRINT +(<var-or-num>|<string><sep><var-or-num>|<string>)*<var-or-num>|<string>) *(<var-or-num>|<string>) ==> \1<sep>\3
      (progn
	(replace-match "\\1;\\5" nil nil)
	(setq basport-autofixed (1+ basport-autofixed))))
    (beginning-of-buffer)
    (while (re-search-forward "RND([01]*)" nil t)
      (progn
	(replace-match "RND" nil nil)
	(setq basport-autofixed (1+ basport-autofixed))))
    (beginning-of-buffer)
    (while (re-search-forward "RND(\\([0-9]+\\))" nil t)
      (progn
	(replace-match "RND*\\1" nil nil)
	(setq basport-autofixed (1+ basport-autofixed))))

    ;; Fix by hand ...
    (beginning-of-buffer)
    (if (re-search-forward ": *NEXT" nil t)
	(message "*** basport: NEXT not first command on line (autofixed: %d)" basport-autofixed)
      (if (re-search-forward " STEP +[0-9]*\\.[0-9]" nil t)
	  (message "*** basport: Non-integer FOR loop STEP (autofixed: %d)" basport-autofixed)
	(if (re-search-forward "[ :]PRINT [^:]*\"[^:]*\"[,;] *:" nil t)
	    (message "*** basport: PRINT ending with format character not last command on line (autofixed: %d)" basport-autofixed)
	  (if (re-search-forward "\\(\".*\"[^\"]*\\)*:" nil t)
	      (message "*** basport: Multiple statements on line (autofixed: %d)" basport-autofixed)
	    (message "* basport: No problems found (autofixed: %d)" basport-autofixed)))))))