git.fiddlerwoaroof.com
top/phases.scm
4e987026
 
 ;;; This is the top-level phase structure of the compiler.
 
 ;;; Compilation phase support
 
 (define *phase* '#f)
 (define *abort-phase* '#f)         ; abort when this phase completes
 (define *abort-compilation*
   (lambda ()
     (error "No error continuation defined here!")))
 
 (define *module-asts* '())   ; a global only for debugging purposes
 
 ;;; Later add the printing and timing stuff here
 
 (define-local-syntax (phase-body phase-name body printer)
   `(dynamic-let ((*phase*       ',phase-name))
      (when (memq ',phase-name (dynamic *printers*))
        (format '#t "~%Phase ~a:~%" ',phase-name)
        (force-output))
      (let* ((phase-start-time (get-run-time))
 	    (result ,body)
 	    (current-time  (get-run-time)))
        (when (eq? (dynamic *abort-phase*) ',phase-name)
 	 (abort-compilation))
        ,@(if (eq? printer '#f)
 	     '()
 	     `((when (memq ',phase-name (dynamic *printers*))
 		 (funcall ,printer result)
 		 (force-output))))
        (when (memq 'phase-time *printers*)
 	 (let ((elapsed-time (- current-time phase-start-time)))
 	   (format '#t "~&~A complete: ~A seconds~%"
 		   ',phase-name elapsed-time)
 	   (force-output)))
        result)))
 
 
 
 ;;; Returns 2 values: module ast's and lisp code.
 
 (define (compile-haskell-files files)
   (dynamic-let ((*abort-phase*                '#f))
      (let ((all-mods       (haskell-parse-files files))
 	   (interface-mods '())
 	   (regular-mods   '()))
        (dolist (m all-mods)
 	 (if (eq? (module-type m) 'interface)
 	     (push m interface-mods)
 	     (push m regular-mods)))
        (dynamic-let ((*unit*  (module-name (car all-mods))))
 	 (values
 	   all-mods
 	   `(begin
 	      ,(if interface-mods
 		   (compile-interface-modules (nreverse interface-mods))
 		   '#f)
 	      ,(if regular-mods
 		   (compile-modules (nreverse regular-mods))
 		   '#f))
 	   )))))
 
 
 
 (define (compile-modules mods)
   (dynamic-let ((*context*                    '#f)
 		(*recoverable-error-handler*  '#f)
 		(*abort-phase*                '#f)
 		(*unique-name-counter*        1)
 		(*suffix-table*               (make-table)))
   	  (haskell-import-export mods '#f)
 	  (haskell-process-type-declarations mods)
 	  (haskell-scope mods)
 	  (let ((big-let (haskell-dependency-analysis mods)))
 	    (cond ((not (void? big-let))
 		   (haskell-type-check big-let mods)
 		   (setf big-let (haskell-cfn big-let))
 		   (setf big-let (haskell-dependency-reanalysis big-let))
 		   (setf big-let (haskell-ast-to-flic big-let))
 		   (setf big-let (haskell-optimize big-let))
 		   (setf big-let (haskell-strictness big-let))
 		   (haskell-codegen big-let mods))
 		  (else
 		   ''#f)
 		  ))))
 
 
 (define (modules->lisp-code modules)
   (dynamic-let ((*unit* (module-name (car modules))))
     (compile-modules modules)))
 
 
 (predefine (notify-error))  ; in command-interface/command-utils.scm
 
 (define (abort-compilation)
   (notify-error)
   (funcall (dynamic *abort-compilation*)))
 
 (define (halt-compilation)
   (setf (dynamic *abort-phase*) (dynamic *phase*)))
 
 
 ;;; Here are the actual phase bodies
 
 (predefine (parse-files files))
 
 (define (haskell-parse-files filenames)
   (phase-body parse
     (let ((mods (parse-files filenames)))
       mods)
     #f))
 
 (predefine (import-export modules))  ; in import-export/import-export.scm
 (predefine (import-export/interface modules))
 
 (define (haskell-import-export modules interface?)
   (phase-body import
     (if interface?
 	(import-export/interface modules)
 	(import-export modules))
     #f))
 
 
 (predefine (process-type-declarations modules)) 
     ; in tdecl/type-declaration-analysis.scm
 
 (define (haskell-process-type-declarations modules)
   (phase-body type-decl
     (begin
       (process-type-declarations modules))
     #f))
 
 
 (predefine (scope-modules x))  ; in prec/scope.scm
 (predefine (print-full-module x . maybe-stream)) ; in the printers
 
 (define (haskell-scope modules)
   (phase-body scope
     (scope-modules modules)
     (lambda (result)
       (declare (ignore result))
       (dolist (m modules) (print-full-module m)))
     ))
 
 
 (predefine (do-dependency-analysis x))  ; in depend/dependency-analysis.scm
 
 (define (haskell-dependency-analysis modules)
   (phase-body depend
     (do-dependency-analysis modules)
     (function pprint*)))
 
 
 (predefine (do-haskell-type-check big-let mods))
 
 (define (haskell-type-check big-let modules)
   (phase-body type
     (do-haskell-type-check big-let modules)
     #f))
 
 (predefine (cfn-ast x))  ; in cfn/main.scm
 
 (define (haskell-cfn big-let)
   (phase-body cfn
     (cfn-ast big-let)
     (function pprint*)))
 
 
 (predefine (analyze-dependency-top x))  ; in depend/dependency-analysis.scm
 
 (define (haskell-dependency-reanalysis big-let)
   (phase-body depend2
     (begin
       (analyze-dependency-top big-let)
       big-let)
     (function pprint*)))
 
 
 (predefine (ast-to-flic x))		; in flic/ast-to-flic.scm
 
 (define (haskell-ast-to-flic big-let)
   (phase-body flic
     (ast-to-flic big-let)
     (function pprint*)))
 
 
 (predefine (optimize-top x))  ; in backend/optimize.scm
 
 (define (haskell-optimize big-let)
   (phase-body optimize
     (optimize-top big-let)
     (function pprint*)))
 
 (predefine (strictness-analysis-top x)) ; in backend/strictness.scm
 (predefine (strictness-analysis-printer x))
 
 (define (haskell-strictness big-let)
   (phase-body strictness
     (strictness-analysis-top big-let)
     (function strictness-analysis-printer)))
 
 
 (predefine (codegen-top x))  ; in backend/codegen.scm
 (predefine (codegen-exported-types x)) ; "
 (predefine (codegen-prim-entries x))  ; ditto
 
 (define (haskell-codegen big-let mods)
   (phase-body codegen
     `(begin
        ,(codegen-exported-types mods)
        ,(codegen-top big-let))
     #f))
 
 	       
 ;;; This is for interface modules.
 
 (predefine (haskell-codegen/interface mods))
 
 (define (compile-interface-modules mods)
  (dynamic-let ((*context*                    '#f)
 	       (*recoverable-error-handler*  '#f)
 	       (*abort-phase*                '#f))
      (haskell-import-export mods '#t)
      (haskell-process-type-declarations mods)
      (haskell-scope mods)
      (haskell-codegen/interface mods)))