1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-01 04:10:18 +02:00
guile/module/system/base/language.scm
Andy Wingo f95f82f8e1 compilation enviroments are always modules; simplifications & refactorings
* module/ice-9/boot-9.scm (make-fresh-user-module): New public function,
  makes an anonymous beautified module.

* module/language/objcode/spec.scm: We used to have some things in here
  that allowed lexical variable names and values to be a part of the
  environment, but no more. Now an environment is just a module. If you
  want to "inject" free variables into code, just use lambda.

* module/language/scheme/compile-tree-il.scm (compile-tree-il): Same
  here. Also, rely on the fact that an environment *will* be a module --
  because (system base compile) guarantees that for us.

* module/language/scheme/spec.scm (scheme): In the reader, rely on the
  environment being a module. Define a #:make-default-environment
  handler, which returns a beautified module, augmented with a fresh
  definition for current-reader, so that side effects to current-reader
  are restricted to the compilation unit.

* module/language/tree-il/analyze.scm
  (report-possibly-unbound-variables):
* module/language/tree-il/compile-glil.scm (compile-glil):
* module/language/tree-il/optimize.scm (optimize!): The environment will
  be a module.

* module/system/base/language.scm (<language>): New field,
  `make-default-environment'. Defaults to `make-fresh-user-module'.
  (default-environment): New accessor, returns a default environment for
  a language.

* module/system/repl/common.scm (repl-compile): Always compile relative
  to the current module, because a module is always acceptable as an
  environment.

* module/system/base/compile.scm (compile-file, compile-and-load): Both
  of these have a new keyword argument, #:env. For `compile-file', it
  defaults to the default environment of the source language, and for
  `compile-and-load', to the current module.
  (read-and-compile): If there are no expressions read, pass the joiner
  its default environment (via `default-environment joint').
2009-10-16 15:33:32 +02:00

105 lines
3.5 KiB
Scheme
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; Multi-language support
;; Copyright (C) 2001, 2009 Free Software Foundation, Inc.
;; This library is free software; you can redistribute it and/or
;; modify it under the terms of the GNU Lesser General Public
;; License as published by the Free Software Foundation; either
;; version 3 of the License, or (at your option) any later version.
;;
;; This library is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; Lesser General Public License for more details.
;;
;; You should have received a copy of the GNU Lesser General Public
;; License along with this library; if not, write to the Free Software
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301 USA
;;; Code:
(define-module (system base language)
#:use-module (system base syntax)
#:export (define-language language? lookup-language make-language
language-name language-title language-version language-reader
language-printer language-parser
language-compilers language-decompilers language-evaluator
language-joiner language-make-default-environment
lookup-compilation-order lookup-decompilation-order
invalidate-compilation-cache! default-environment))
;;;
;;; Language class
;;;
(define-record/keywords <language>
name
title
version
reader
printer
(parser #f)
(compilers '())
(decompilers '())
(evaluator #f)
(joiner #f)
(make-default-environment make-fresh-user-module))
(define-macro (define-language name . spec)
`(begin
(invalidate-compilation-cache!)
(define ,name (make-language #:name ',name ,@spec))))
(define (lookup-language name)
(let ((m (resolve-module `(language ,name spec))))
(if (module-bound? m name)
(module-ref m name)
(error "no such language" name))))
(define *compilation-cache* '())
(define *decompilation-cache* '())
(define (invalidate-compilation-cache!)
(set! *decompilation-cache* '())
(set! *compilation-cache* '()))
(define (compute-translation-order from to language-translators)
(cond
((not (language? to))
(compute-translation-order from (lookup-language to) language-translators))
(else
(let lp ((from from) (seen '()))
(cond
((not (language? from))
(lp (lookup-language from) seen))
((eq? from to) (reverse! seen))
((memq from seen) #f)
(else (or-map (lambda (pair)
(lp (car pair) (acons from (cdr pair) seen)))
(language-translators from))))))))
(define (lookup-compilation-order from to)
(let ((key (cons from to)))
(or (assoc-ref *compilation-cache* key)
(let ((order (compute-translation-order from to language-compilers)))
(set! *compilation-cache*
(acons key order *compilation-cache*))
order))))
(define (lookup-decompilation-order from to)
(let ((key (cons from to)))
(or (assoc-ref *decompilation-cache* key)
;; trickery!
(let ((order (and=>
(compute-translation-order to from language-decompilers)
reverse!)))
(set! *decompilation-cache* (acons key order *decompilation-cache*))
order))))
(define (default-environment lang)
"Return the default compilation environment for source language LANG."
((language-make-default-environment
(if (language? lang) lang (lookup-language lang)))))