Moved package-related code to namespace.lisp, added back *enable-package-system*.
authorVladimir Sedach <vsedach@gmail.com>
Sat, 4 Aug 2007 00:59:48 +0000 (00:59 +0000)
committerVladimir Sedach <vsedach@gmail.com>
Sat, 4 Aug 2007 00:59:48 +0000 (00:59 +0000)
parenscript.asd
src/builtin-packages.lisp
src/js-translation.lisp
src/namespace.lisp [new file with mode: 0644]
src/parser.lisp
src/ps-macrology.lisp
src/ps-source-model.lisp

index 8ef1fb1..b72e98e 100644 (file)
@@ -20,7 +20,8 @@
                              (:file "utils" :depends-on ("package"))
                             (:file "js-source-model" :depends-on ("package" "utils"))
                             (:file "ps-source-model" :depends-on ("js-source-model"))
-                            (:file "parser" :depends-on ("js-source-model" "ps-source-model"))
+                             (:file "namespace" :depends-on ("js-source-model" "ps-source-model"))
+                            (:file "parser" :depends-on ("js-source-model" "ps-source-model" "namespace"))
                             (:file "builtin-packages" :depends-on ("parser"))
                             (:file "deprecated-interface" :depends-on ("parser"))
                             (:file "parse-lambda-list" :depends-on ("package"))
index 357c552..9efa9d7 100644 (file)
    nil
    ))
 
+(defgeneric install-standard-script-packages (comp-env)
+  (:documentation "Creates standard script packages and installs them in the current compilation
+environment."))
+
 (defmethod install-standard-script-packages ((comp-env compilation-environment))
   (list
    (create-script-package
index 6ee8692..bff0828 100644 (file)
@@ -197,36 +197,6 @@ vice-versa.")
            finally (write-char *js-quote-char* escaped)))))
 
 ;;; variables
-(defgeneric js-translate-symbol-contextually (symbol package env)
-  (:documentation "Translates a symbol to a string in the given environment & package
-and for the given symbol."))
-
-(defparameter *obfuscate-standard-identifiers* nil)
-
-(defparameter *obfuscation-table* (make-hash-table))
-
-(defun obfuscated-symbol (symbol)
-  (or (gethash symbol *obfuscation-table*)
-      (setf (gethash symbol *obfuscation-table*) (string (gensym)))))
-
-(defmethod js-translate-symbol-contextually ((symbol symbol)
-                                            (package ps::script-package)
-                                            (env ps::compilation-environment))
-  (cond
-    ((member (ps::script-package-lisp-package package)
-            (mapcar #'find-package '(:keyword :parenscript.global)))
-     (symbol-to-js symbol))
-    (*obfuscate-standard-identifiers*
-     (obfuscated-symbol symbol))
-    (t
-     (case *package-prefix-style*
-       (:prefix
-       (format nil "~A~A"
-               (or (ps::script-package-prefix package) (concatenate 'string (ps::script-package-name package) "_"))
-               (symbol-to-js symbol)))
-       (t
-       (symbol-to-js (value symbol)))))))
-
 (defgeneric js-translate-symbol (var)
   (:documentation "Given a JS-VARIABLE returns an output
 JavaScript version of it as a string."))
@@ -235,7 +205,7 @@ JavaScript version of it as a string."))
   (js-translate-symbol (value var)))
 
 (defmethod js-translate-symbol ((var-name symbol))
-  (js-translate-symbol-contextually var-name (ps::symbol-script-package var-name) ps::*compilation-environment*))
+  (ps::js-translate-symbol-contextually var-name (ps::symbol-script-package var-name) ps::*compilation-environment*))
 
 (defmethod js-to-strings ((v js-variable) start-form)
   (declare (ignore start-form))
diff --git a/src/namespace.lisp b/src/namespace.lisp
new file mode 100644 (file)
index 0000000..e3aeb7d
--- /dev/null
@@ -0,0 +1,311 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; ParenScript package system
+
+(in-package :parenscript)
+
+(defclass script-package ()
+  ;; configuration slots
+  ((name          :accessor script-package-name          :initform nil :initarg :name :type string
+                 :documentation "Canonical name of the package (a String).")
+   (nicknames     :accessor script-package-nicknames     :initform nil :initarg :nicknames
+                 :documentation "List of nicknames for the package (as strings).")
+   (prefix        :accessor script-package-prefix        :initform nil :initarg :prefix :type string
+                  :documentation "The prefix string that will be used when translating the symbols in the current package to Javascript.")
+   (lisp-package  :accessor script-package-lisp-package  :initform nil :initarg :lisp-package)
+   (secondary-lisp-packages :accessor script-package-secondary-lisp-packages :initform nil
+                           :initarg :secondary-lisp-packages)
+   (exports       :accessor script-package-exports       :initarg :exports
+                 :initform nil;(make-hash-table :test #'equal)
+                 :documentation "List of exported identifiers.")
+   (used-packages :accessor script-package-used-packages :initform nil :initarg :used-packages
+                 :documentation "")
+   (documentation :accessor script-package-documentation :initform nil :initarg :documentation)
+   (compilation-env :accessor script-package-comp-env    :initform nil :initarg :comp-env)
+   (locked?       :accessor script-package-locked? :initform nil :initarg :locked?
+                 :documentation "t if redefinition of top-level symbols is disallowed.")
+   ;; internal use slots
+   (symbol-table :accessor script-package-symbol-table :initform nil :initarg :symbol-table
+                :documentation "Contains symbols when there is no lisp package for this package.")
+   )
+  (:documentation "A Parenscript package is a lisp object that holds information
+about a set of code.
+
+"))
+
+(defmethod print-object ((sp script-package) stream)
+  (format stream "#<SCRIPT-PACKAGE ~s>" (script-package-name sp)))
+
+(defclass compilation-environment ()
+  ((script-packages :accessor comp-env-script-packages :initform nil :initarg :packages
+                   :documentation "List of packages defined in this environment.")
+   (current-package :accessor comp-env-current-package :initform nil :initarg :current-package
+                   :documentation "Current in-package.")
+   (lisp-to-script-package-table
+    :accessor comp-env-lisp-to-script-package-table :initform (make-hash-table)
+    :documentation   "Maps a lisp package to a script package.")
+   (compiling-toplevel-p 
+    :accessor comp-env-compiling-toplevel-p :initform nil :initarg :processing-toplevel-p
+    :documentation "T if the environment is currently processing toplevel forms.")
+   (symbol-table :accessor symbol-to-script-package :initform (make-hash-table)
+                :documentation "Maps symbols to script packages.  Used for only the
+symbols in script packages that do not have a primary lisp package."))
+  (:documentation ""))
+
+(defgeneric symbol-script-package (symbol)
+  (:documentation "Gets the Parenscript package associated with a Lisp/Parenscript symbol."))
+
+(defvar *warn-ps-package* nil
+  "If true, warns when ParenScript attempts to compile symbols that
+don't have an associated ParenScript package.")
+
+(defun lisp-to-script-package (lisp-package &optional (comp-env *compilation-environment*))
+  "Gets a script package corresponding to the given Lisp package."
+  (gethash lisp-package (comp-env-lisp-to-script-package-table comp-env)))
+
+(defsetf lisp-to-script-package (lisp-package &optional (comp-env *compilation-environment*))
+    (script-package)
+  "Sets the script package corresponding to the given Lisp package."
+  `(setf (gethash ,lisp-package (comp-env-lisp-to-script-package-table ,comp-env))
+    ,script-package))
+
+(defmethod symbol-script-package ((symbol symbol))
+  (if (symbol-package symbol)
+      (or (lisp-to-script-package (symbol-package symbol) *compilation-environment*)
+          (progn (when *warn-ps-package*
+                   (warn 'simple-style-warning
+                         :format-control "~s is a symbol with lisp package ~s, which has no corresponding ParenScript package.
+Defaulting to :parenscript-user."
+                         :format-arguments (list symbol (symbol-package symbol))))
+                 (find-script-package "PARENSCRIPT-USER" (make-basic-compilation-environment))))
+      (find-script-package "UNINTERNED" *compilation-environment*)))
+
+(defun find-script-package (name &optional (comp-env *compilation-environment*))
+  "Find the script package with the name NAME in the given compilation environment."
+  (typecase name
+    ((or symbol string)
+     (find-if #'(lambda (script-package)
+                 (find (string name)
+                       (cons (script-package-name script-package)
+                             (script-package-nicknames script-package))
+                       :test #'equal))
+             (comp-env-script-packages comp-env)))
+    (script-package name)
+    (t (error "~A has unknown type" name))))
+
+(defun script-intern (name script-package-name)
+  "Returns a Parenscript symbol with the string value STRING interned for the
+given SCRIPT-PACKAGE."
+  (declare (type string name))
+  (let ((script-package (find-script-package script-package-name)))
+    (flet ((find-exported-symbol (name script-package)
+             (let ((res
+                    (find name (script-package-exports script-package)
+                          :key #'(lambda (exported-symbol) (string exported-symbol))
+                          :test #'equal)))
+               res)))
+      (let ((res
+             (or
+              (some #'(lambda (used-package)
+                        (find-exported-symbol name used-package))
+                    (script-package-used-packages script-package))
+              (if (script-package-lisp-package script-package)
+                  (intern name (script-package-lisp-package script-package))
+                  (progn
+                    (let ((sym (intern-without-package name)))
+                      (setf (gethash name (script-package-symbol-table script-package))
+                            sym)
+                      (setf (gethash sym (symbol-to-script-package (script-package-comp-env script-package)))
+                            script-package)
+                      sym))))))
+        (declare (type symbol res))
+        res))))
+
+(defun find-script-symbol (name script-package)
+  "Finds the symbol with name NAME in the script package SCRIPT-PACKAGE.  NAME is a
+string and SCRIPT-PACKAGE is a package designator.  If NAME does not specify a symbol of
+script-package, returns nil.  Otherwise returns 2 values:
+1.  the symbol
+2.  :external if the symbol is external.  :internal if the symbol is internal. NIL if
+the symbol is not interned in the package."
+  (setf script-package (find-script-package script-package))
+  (let (symbol interned-p)
+
+    (if (script-package-lisp-package script-package)
+       (multiple-value-bind (lisp-symbol lisp-status)
+           (find-symbol name (script-package-lisp-package script-package))
+         (setf symbol lisp-symbol)
+         (setf interned-p (and lisp-status t)))
+       (multiple-value-bind (sym sym-found-p)
+           (gethash name (script-package-symbol-table script-package))
+         (setf symbol sym)
+         (setf interned-p sym-found-p)))
+    (let ((exported? (member symbol (script-package-exports script-package))))
+      (values symbol
+             (if exported? :external (if interned-p :internal nil))))))
+
+(defun script-export (symbols
+                     &optional (script-package (comp-env-current-package *compilation-environment*)))
+  "Exports the given symbols in the given script package."
+  (when (not (listp symbols)) (setf symbols (list symbols)))
+  (setf script-package (find-script-package script-package))
+  (let ((symbols-not-in-package
+        (remove-if #'(lambda (symbol)
+                       (declare (type symbol symbol))
+                       (eql symbol (find-script-symbol (string symbol) script-package)))
+                   symbols)))
+    (when symbols-not-in-package
+      (error "Invalid exports.  The following symbols are not interned in the package ~A:~%~A"
+            (script-package-name script-package) symbols-not-in-package)))
+  (mapc #'(lambda (symbol)
+           (pushnew symbol (script-package-exports script-package)))
+       symbols)
+  t)
+
+(defun use-script-package (packages-to-use
+                          &optional (into-package (comp-env-current-package *compilation-environment*)))
+  "use-script-package causes INTO-PACKAGE to inherit all the external symbols of packages-to-use. 
+The inherited symbols become accessible as internal symbols of package."
+  (when (not (listp packages-to-use)) (setf packages-to-use (list packages-to-use)))
+  (setf packages-to-use (mapcar #'find-script-package packages-to-use))
+  (setf into-package (find-script-package into-package))
+
+  (let ((all-used-symbols (apply #'append (mapcar #'script-package-exports packages-to-use))))
+    (mapc #'(lambda (used-symbol)
+             (let ((symbol-same-name (find-script-symbol (string used-symbol) into-package)))
+               (when (not (or (null symbol-same-name)
+                              (eql symbol-same-name used-symbol)))
+                 (error "Import of symbol ~A into package ~A conflicts with interned symbol ~A"
+                        used-symbol (script-package-name into-package) symbol-same-name))))
+         all-used-symbols))
+  (setf (script-package-used-packages into-package)
+       (append (script-package-used-packages into-package) packages-to-use)))
+
+(defun intern-without-package (name)
+  (macrolet ((with-temp-package ((var) &body body)
+              (let ((result-var (gensym)))
+              `(let* ((,var (make-package ',(gensym)))
+                      (,result-var (progn ,@body)))
+                (delete-package ,var)
+                ,result-var))))
+    (with-temp-package (package)
+      (let ((sym (intern name package)))
+       (unintern sym package)
+       sym))))
+
+(defun create-script-package (comp-env
+                             &key name nicknames prefix secondary-lisp-packages used-packages
+                             lisp-package exports documentation)
+  "Creates a script package in the given compilation environment"
+  (when (and lisp-package (not (find-package lisp-package)))
+    (error "Package ~A does not exists" lisp-package))
+  (let* ((script-package
+         (make-instance 'script-package
+                        :name (string name)
+                        :comp-env comp-env
+                         :prefix prefix
+                        :nicknames (mapcar #'string nicknames)
+                        :lisp-package (when lisp-package (find-package lisp-package))
+                        :secondary-lisp-packages (mapcar #'find-package secondary-lisp-packages)
+                        :documentation documentation)))
+    (use-script-package used-packages script-package)
+    (labels ((package-intern (string-like)
+              (script-intern (string string-like) script-package)))
+      (script-export (mapcar #'package-intern exports) script-package))
+    (push script-package (comp-env-script-packages comp-env))
+    script-package))
+
+(defmethod initialize-instance :after ((package script-package) &key)
+  (assert (script-package-comp-env package))
+  (when (null (script-package-lisp-package package))
+    (setf (script-package-symbol-table package)
+         (make-hash-table :test #'equal)))
+  (let ((lisp-packages
+        (remove-if #'null
+                   (cons (script-package-lisp-package package)
+                         (script-package-secondary-lisp-packages package)))))
+    (dolist (lisp-package lisp-packages)
+      (when (lisp-to-script-package lisp-package (script-package-comp-env package))
+       (error "Lisp package already has corresponding script package: ~A" (package-name lisp-package)))
+      (setf (lisp-to-script-package lisp-package (script-package-comp-env package))
+           package))))
+
+(defgeneric comp-env-find-package (comp-env package-designator)
+  (:documentation "Finds the script package named by PACKAGE-DESIGNATOR in the current 
+compilation environment. PACKAGE-DESIGNATOR is a string or symbol.")
+  (:method ((comp-env compilation-environment) (name string))
+    (find name (comp-env-script-packages comp-env)
+         :key #'script-package-name :test #'equal))
+  (:method ((comp-env compilation-environment) (package-designator symbol))
+    (comp-env-find-package comp-env (string package-designator))))
+
+;; TODO loop through all defined macros and add them to the script package's
+;; macro environment
+;        (labels ((name-member (name)
+;                   (eql (script-package-lisp-package script-package) (symbol-package name)))
+;                 (import-macro (name function)
+;                   (when (name-member name)
+;                     (setf (gethash name (script-package-macro-table script-package))
+;                           function)))
+;                 (import-special-form (name function)
+;                   (when (name-member name)
+;                     (setf (gethash name (script-package-special-form-table script-package))
+;                           function))))
+;        (maphash #'import-special-form *toplevel-special-forms*)
+;        (maphash #'import-special-form *toplevel-special-forms*)
+
+;(defgeneric comp-env-select-package (comp-env script-package)
+;  (:documentation "")
+;  (:method ((comp-env compilation-environment) (package script-package))
+;    (setf (comp-env-current-package 
+
+
+(defvar *enable-package-system* nil)
+
+;;; Interface for reading in identifier
+
+(defgeneric lisp-symbol-to-ps-identifier (symbol context &optional compilation-environment) 
+  (:documentation "Context is one of :special-form, :macro or nil."))
+
+(defmethod lisp-symbol-to-ps-identifier ((symbol symbol) (context (eql :special-form)) &optional comp-ev)
+  (declare (ignore context comp-ev))
+  (symbol-name symbol))
+
+(defmethod lisp-symbol-to-ps-identifier ((symbol symbol) (context (eql :macro)) &optional comp-ev)
+  (declare (ignore context comp-ev))
+  symbol)
+
+(defmethod lisp-symbol-to-ps-identifier :around ((symbol symbol) context &optional comp-ev)
+  (declare (ignore context comp-ev))
+  (if *enable-package-system*
+      (call-next-method)
+      (symbol-name symbol)))
+
+;;; Symbol obfuscation (this should really go somewhere else)
+(defvar *obfuscate-standard-identifiers* nil)
+
+(defparameter *obfuscation-table* (make-hash-table))
+
+(defun obfuscated-symbol (symbol)
+  (or (gethash symbol *obfuscation-table*)
+      (setf (gethash symbol *obfuscation-table*) (string (gensym)))))
+
+;;; Interface for printing identifiers
+
+(defvar *package-prefix-style* :prefix
+  "Determines how package symbols are serialized to JavaScript identifiers.  NIL for
+no prefixes.  :prefix to prefix variables with something like packagename_identifier.")
+
+(defgeneric js-translate-symbol-contextually (symbol package env)
+  (:documentation "Translates a symbol to a string in the given environment & package
+and for the given symbol."))
+
+(defmethod js-translate-symbol-contextually ((symbol symbol) (package ps::script-package) (env ps::compilation-environment))
+  (cond ((member (ps::script-package-lisp-package package) (mapcar #'find-package '(:keyword :parenscript.global)))
+         (symbol-to-js symbol))
+        (*obfuscate-standard-identifiers* (obfuscated-symbol symbol))
+        (t (if (and *enable-package-system* (eql *package-prefix-style* :prefix))
+               (format nil "~A~A"
+                       (or (ps::script-package-prefix package) (concatenate 'string (ps::script-package-name package) "_"))
+                       (symbol-to-js symbol))
+               (symbol-to-js symbol)))))
+
index 5000367..2d30b43 100644 (file)
@@ -1,62 +1,6 @@
 (in-package :parenscript)
 
 ;;;; The mechanisms for defining macros & parsing Parenscript.
-
-(eval-when (:compile-toplevel :load-toplevel)
-  (defun macro-name-hash-function ()
-    #'eql))
-
-(defclass script-package ()
-  ;; configuration slots
-  ((name          :accessor script-package-name          :initform nil :initarg :name :type string
-                 :documentation "Canonical name of the package (a String).")
-   (nicknames     :accessor script-package-nicknames     :initform nil :initarg :nicknames
-                 :documentation "List of nicknames for the package (as strings).")
-   (prefix        :accessor script-package-prefix        :initform nil :initarg :prefix :type string
-                  :documentation "The prefix string that will be used when translating the symbols in the current package to Javascript.")
-   (lisp-package  :accessor script-package-lisp-package  :initform nil :initarg :lisp-package)
-   (secondary-lisp-packages :accessor script-package-secondary-lisp-packages :initform nil
-                           :initarg :secondary-lisp-packages)
-   (exports       :accessor script-package-exports       :initarg :exports
-                 :initform nil;(make-hash-table :test #'equal)
-                 :documentation "List of exported identifiers.")
-   (used-packages :accessor script-package-used-packages :initform nil :initarg :used-packages
-                 :documentation "")
-   (documentation :accessor script-package-documentation :initform nil :initarg :documentation)
-   (compilation-env :accessor script-package-comp-env    :initform nil :initarg :comp-env)
-   (locked?       :accessor script-package-locked? :initform nil :initarg :locked?
-                 :documentation "t if redefinition of top-level symbols is disallowed.")
-   ;; internal use slots
-   (symbol-table :accessor script-package-symbol-table :initform nil :initarg :symbol-table
-                :documentation "Contains symbols when there is no lisp package for this package.")
-   )
-  (:documentation "A Parenscript package is a lisp object that holds information
-about a set of code.
-
-"))
-
-(defmethod print-object ((sp script-package) stream)
-  (format stream "#<SCRIPT-PACKAGE ~s>" (script-package-name sp)))
-
-(defclass compilation-environment ()
-  ((script-packages :accessor comp-env-script-packages :initform nil :initarg :packages
-                   :documentation "List of packages defined in this environment.")
-   (current-package :accessor comp-env-current-package :initform nil :initarg :current-package
-                   :documentation "Current in-package.")
-   (lisp-to-script-package-table
-    :accessor comp-env-lisp-to-script-package-table :initform (make-hash-table)
-    :documentation   "Maps a lisp package to a script package.")
-   (compiling-toplevel-p 
-    :accessor comp-env-compiling-toplevel-p :initform nil :initarg :processing-toplevel-p
-    :documentation "T if the environment is currently processing toplevel forms.")
-   (symbol-table :accessor symbol-to-script-package :initform (make-hash-table)
-                :documentation "Maps symbols to script packages.  Used for only the
-symbols in script packages that do not have a primary lisp package."))
-  (:documentation ""))
-
-(defgeneric symbol-script-package (symbol)
-  (:documentation "Gets the Parenscript package associated with a Lisp/Parenscript symbol."))
-
 (defgeneric compiler-in-situation-p (comp-env situation)
   (:documentation "Returns true when the compiler is considered 'in' the situation
 given by SITUATION, which is one of :compile-toplevel :execute.")
@@ -73,258 +17,20 @@ http://www.lispworks.com/documentation/HyperSpec/Body/03_bca.htm")
     (comp-env-compiling-toplevel-p comp-env)
     ))
 
-(defvar *compilation-environment* nil
-  "The active compilation environment."
-;; Right now all code assumes that *compilation-environment* is accurately bound to the
-;; current compilation environment--even some functions that take the compilation environment
-;; as arguments.
-  )
-
-(defvar *package-prefix-style* :prefix
-  "Determines how package symbols are serialized to JavaScript identifiers.  NIL for
-no prefixes.  :prefix to prefix variables with something like packagename_identifier.")
-
-(defvar *warn-ps-package* nil
-  "If true, warns when ParenScript attempts to compile symbols that
-don't have an associated ParenScript package.")
-
-;;; parenscript packages
-(defun lisp-to-script-package (lisp-package &optional (comp-env *compilation-environment*))
-  "Gets a script package corresponding to the given Lisp package."
-  (gethash lisp-package (comp-env-lisp-to-script-package-table comp-env)))
-
-(defsetf lisp-to-script-package (lisp-package &optional (comp-env *compilation-environment*))
-    (script-package)
-  "Sets the script package corresponding to the given Lisp package."
-  `(setf (gethash ,lisp-package (comp-env-lisp-to-script-package-table ,comp-env))
-    ,script-package))
-
-(defmethod symbol-script-package ((symbol symbol))
-  (if (symbol-package symbol)
-      (or (lisp-to-script-package (symbol-package symbol) *compilation-environment*)
-          (progn (when *warn-ps-package*
-                   (warn 'simple-style-warning
-                         :format-control "~s is a symbol with lisp package ~s, which has no corresponding ParenScript package.
-Defaulting to :parenscript-user."
-                         :format-arguments (list symbol (symbol-package symbol))))
-                 (find-script-package "PARENSCRIPT-USER" (make-basic-compilation-environment))))
-      (find-script-package "UNINTERNED" *compilation-environment*)))
-
-(defun find-script-package (name &optional (comp-env *compilation-environment*))
-  "Find the script package with the name NAME in the given compilation environment."
-  (typecase name
-    ((or symbol string)
-     (find-if #'(lambda (script-package)
-                 (find (string name)
-                       (cons (script-package-name script-package)
-                             (script-package-nicknames script-package))
-                       :test #'equal))
-             (comp-env-script-packages comp-env)))
-    (script-package name)
-    (t (error "~A has unknown type" name))))
-     
-(defun script-intern (name script-package-name)
-  "Returns a Parenscript symbol with the string value STRING interned for the
-given SCRIPT-PACKAGE."
-  (declare (type string name))
-  (let ((script-package (find-script-package script-package-name)))
-    (flet ((find-exported-symbol (name script-package)
-             (let ((res
-                    (find name (script-package-exports script-package)
-                          :key #'(lambda (exported-symbol) (string exported-symbol))
-                          :test #'equal)))
-               res)))
-      (let ((res
-             (or
-              (some #'(lambda (used-package)
-                        (find-exported-symbol name used-package))
-                    (script-package-used-packages script-package))
-              (if (script-package-lisp-package script-package)
-                  (intern name (script-package-lisp-package script-package))
-                  (progn
-                    (let ((sym (intern-without-package name)))
-                      (setf (gethash name (script-package-symbol-table script-package))
-                            sym)
-                      (setf (gethash sym (symbol-to-script-package (script-package-comp-env script-package)))
-                            script-package)
-                      sym))))))
-        (declare (type symbol res))
-        res))))
-
-(defun find-script-symbol (name script-package)
-  "Finds the symbol with name NAME in the script package SCRIPT-PACKAGE.  NAME is a
-string and SCRIPT-PACKAGE is a package designator.  If NAME does not specify a symbol of
-script-package, returns nil.  Otherwise returns 2 values:
-1.  the symbol
-2.  :external if the symbol is external.  :internal if the symbol is internal. NIL if
-the symbol is not interned in the package."
-  (setf script-package (find-script-package script-package))
-  (let (symbol interned-p)
-
-    (if (script-package-lisp-package script-package)
-       (multiple-value-bind (lisp-symbol lisp-status)
-           (find-symbol name (script-package-lisp-package script-package))
-         (setf symbol lisp-symbol)
-         (setf interned-p (and lisp-status t)))
-       (multiple-value-bind (sym sym-found-p)
-           (gethash name (script-package-symbol-table script-package))
-         (setf symbol sym)
-         (setf interned-p sym-found-p)))
-    (let ((exported? (member symbol (script-package-exports script-package))))
-      (values symbol
-             (if exported? :external (if interned-p :internal nil))))))
-
-(defun script-export (symbols
-                     &optional (script-package (comp-env-current-package *compilation-environment*)))
-  "Exports the given symbols in the given script package."
-  (when (not (listp symbols)) (setf symbols (list symbols)))
-  (setf script-package (find-script-package script-package))
-  (let ((symbols-not-in-package
-        (remove-if #'(lambda (symbol)
-                       (declare (type symbol symbol))
-                       (eql symbol (find-script-symbol (string symbol) script-package)))
-                   symbols)))
-    (when symbols-not-in-package
-      (error "Invalid exports.  The following symbols are not interned in the package ~A:~%~A"
-            (script-package-name script-package) symbols-not-in-package)))
-  (mapc #'(lambda (symbol)
-           (pushnew symbol (script-package-exports script-package)))
-       symbols)
-  t)
-  
-(defun use-script-package (packages-to-use
-                          &optional (into-package (comp-env-current-package *compilation-environment*)))
-  "use-script-package causes INTO-PACKAGE to inherit all the external symbols of packages-to-use. 
-The inherited symbols become accessible as internal symbols of package."
-  (when (not (listp packages-to-use)) (setf packages-to-use (list packages-to-use)))
-  (setf packages-to-use (mapcar #'find-script-package packages-to-use))
-  (setf into-package (find-script-package into-package))
-
-  (let ((all-used-symbols (apply #'append (mapcar #'script-package-exports packages-to-use))))
-    (mapc #'(lambda (used-symbol)
-             (let ((symbol-same-name (find-script-symbol (string used-symbol) into-package)))
-               (when (not (or (null symbol-same-name)
-                              (eql symbol-same-name used-symbol)))
-                 (error "Import of symbol ~A into package ~A conflicts with interned symbol ~A"
-                        used-symbol (script-package-name into-package) symbol-same-name))))
-         all-used-symbols))
-  (setf (script-package-used-packages into-package)
-       (append (script-package-used-packages into-package) packages-to-use)))
-       
-
-
-;; environmental considerations
-(defgeneric setup-compilation-environment (comp-env)
-  (:documentation "Sets up a basic compilation environment prepared for a language user.
-This should do things like define packages and set the current package.
-
-Returns the compilation-environment."))
-
-(defgeneric install-standard-script-packages (comp-env)
-  (:documentation "Creates standard script packages and installs them in the current compilation
-environment."))
-
-(defun make-basic-compilation-environment ()
-  "Creates a compilation environment object from scratch.  Fills it in with the default
-script packages (parenscript, global, and parenscript-user)."
-  (let ((*compilation-environment* (make-instance 'compilation-environment)))
-    (setup-compilation-environment *compilation-environment*)))
-
-(defun intern-without-package (name)
-  (macrolet ((with-temp-package ((var) &body body)
-              (let ((result-var (gensym)))
-              `(let* ((,var (make-package ',(gensym)))
-                      (,result-var (progn ,@body)))
-                (delete-package ,var)
-                ,result-var))))
-    (with-temp-package (package)
-      (let ((sym (intern name package)))
-       (unintern sym package)
-       sym))))
-
-                
-
-(defun create-script-package (comp-env
-                             &key name nicknames prefix secondary-lisp-packages used-packages
-                             lisp-package exports documentation)
-  "Creates a script package in the given compilation environment"
-  (when (and lisp-package (not (find-package lisp-package)))
-    (error "Package ~A does not exists" lisp-package))
-  (let* ((script-package
-         (make-instance 'script-package
-                        :name (string name)
-                        :comp-env comp-env
-                         :prefix prefix
-                        :nicknames (mapcar #'string nicknames)
-                        :lisp-package (when lisp-package (find-package lisp-package))
-                        :secondary-lisp-packages (mapcar #'find-package secondary-lisp-packages)
-                        :documentation documentation)))
-    (use-script-package used-packages script-package)
-    (labels ((package-intern (string-like)
-              (script-intern (string string-like) script-package)))
-      (script-export (mapcar #'package-intern exports) script-package))
-    (push script-package (comp-env-script-packages comp-env))
-    script-package))
-
-(defmethod initialize-instance :after ((package script-package) &key)
-  (assert (script-package-comp-env package))
-  (when (null (script-package-lisp-package package))
-    (setf (script-package-symbol-table package)
-         (make-hash-table :test #'equal)))
-  (let ((lisp-packages
-        (remove-if #'null
-                   (cons (script-package-lisp-package package)
-                         (script-package-secondary-lisp-packages package)))))
-    (dolist (lisp-package lisp-packages)
-      (when (lisp-to-script-package lisp-package (script-package-comp-env package))
-       (error "Lisp package already has corresponding script package: ~A" (package-name lisp-package)))
-      (setf (lisp-to-script-package lisp-package (script-package-comp-env package))
-           package))))
-
-(defgeneric comp-env-find-package (comp-env package-designator)
-  (:documentation "Finds the script package named by PACKAGE-DESIGNATOR in the current 
-compilation environment. PACKAGE-DESIGNATOR is a string or symbol.")
-  (:method ((comp-env compilation-environment) (name string))
-    (find name (comp-env-script-packages comp-env)
-         :key #'script-package-name :test #'equal))
-  (:method ((comp-env compilation-environment) (package-designator symbol))
-    (comp-env-find-package comp-env (string package-designator))))
-
-;; TODO loop through all defined macros and add them to the script package's
-;; macro environment
-;        (labels ((name-member (name)
-;                   (eql (script-package-lisp-package script-package) (symbol-package name)))
-;                 (import-macro (name function)
-;                   (when (name-member name)
-;                     (setf (gethash name (script-package-macro-table script-package))
-;                           function)))
-;                 (import-special-form (name function)
-;                   (when (name-member name)
-;                     (setf (gethash name (script-package-special-form-table script-package))
-;                           function))))
-;        (maphash #'import-special-form *toplevel-special-forms*)
-;        (maphash #'import-special-form *toplevel-special-forms*)
-
-;(defgeneric comp-env-select-package (comp-env script-package)
-;  (:documentation "")
-;  (:method ((comp-env compilation-environment) (package script-package))
-;    (setf (comp-env-current-package 
-  
-
 (eval-when (:compile-toplevel :load-toplevel :execute)
   (defvar *toplevel-special-forms* (make-hash-table :test #'equal)
     "A hash-table containing functions that implement Parenscript special forms,
 indexed by name (as symbols)")
   (defun undefine-script-special-form (name)
     "Undefines the special form with the given name (name is a symbol)."
-    (remhash (symbol-name name) *toplevel-special-forms*)))
+    (remhash (lisp-symbol-to-ps-identifier name :special-form) *toplevel-special-forms*)))
 
 (defmacro define-script-special-form (name lambda-list &rest body)
   "Define a special form NAME. Arguments are destructured according to
 LAMBDA-LIST. The resulting Parenscript language types are appended to the
 ongoing javascript compilation."
   (let ((arglist (gensym "ps-arglist-")))
-    `(setf (gethash ,(symbol-name name) *toplevel-special-forms*)
+    `(setf (gethash (lisp-symbol-to-ps-identifier ',name :special-form) *toplevel-special-forms*)
       (lambda (&rest ,arglist)
         (destructuring-bind ,lambda-list
             ,arglist
@@ -332,7 +38,7 @@ ongoing javascript compilation."
 
 (defun get-script-special-form (name)
   "Returns the special form function corresponding to the given name."
-  (gethash (symbol-name name) *toplevel-special-forms*))
+  (gethash (lisp-symbol-to-ps-identifier name :special-form) *toplevel-special-forms*))
 
 ;;; sexp form predicates
 (defun script-special-form-p (form)
@@ -355,11 +61,11 @@ ongoing javascript compilation."
 (eval-when (:compile-toplevel :load-toplevel :execute)
   (defun make-macro-env-dictionary ()
     "Creates a standard macro dictionary."
-    (make-hash-table :test (macro-name-hash-function)))
+    (make-hash-table :test #'equal))
   (defvar *script-macro-toplevel* (make-macro-env-dictionary)
     "Toplevel macro environment dictionary. Key is the symbol of the
 macro, value is (symbol-macro-p . expansion-function).")
-  (defvar *script-macro-env* (list *script-macro-toplevel*) ;(list nil)
+  (defvar *script-macro-env* (list *script-macro-toplevel*)
     "Current macro environment.")
 
   (defvar *script-setf-expanders* (make-macro-env-dictionary)
@@ -368,17 +74,13 @@ function of the place, value is an expansion function that takes the
 arguments of the access functions as a first value and the form to be
 stored as the second value.")
   
-  (defun find-macro-spec (name env-dict)
-    (gethash name env-dict))
-  (defsetf find-macro-spec (name env-dict)
-      (spec)
-    `(setf (gethash ,name ,env-dict) ,spec)))
-
-
-(defmacro get-macro-spec (name env-dict)
-  "Retrieves the macro spec of the given name with the given environment dictionary.
+  (defun get-macro-spec (name env-dict)
+    "Retrieves the macro spec of the given name with the given environment dictionary.
 SPEC is of the form (symbol-macro-p . expansion-function)."
-  `(find-macro-spec ,name ,env-dict))
+    (gethash (lisp-symbol-to-ps-identifier name :macro) env-dict))
+  (defsetf get-macro-spec (name env-dict)
+      (spec)
+    `(setf (gethash (lisp-symbol-to-ps-identifier ,name :macro) ,env-dict) ,spec)))
 
 (defun lookup-macro-spec (name &optional (environment *script-macro-env*))
   "Looks up the macro spec associated with NAME in the given environment.  A
index a4b1294..f5ceb23 100644 (file)
@@ -10,7 +10,7 @@
   (concatenate 'string
                prefix (princ-to-string (incf *gen-script-name-counter*))))
 
-(defun gen-script-name (&key (prefix ""))
+(defun gen-script-name (&key (prefix "_ps_"))
   "Generate a new javascript identifier."
   (intern (gen-script-name-string :prefix prefix)
           (find-package :parenscript.ps-gensyms)))
@@ -392,7 +392,7 @@ lambda-list::=
       ,@effective-body)))
 
 (ps:defscriptmacro defsetf-long (access-fn lambda-list (store-var) form)
-  (setf (find-macro-spec access-fn *script-setf-expanders*)
+  (setf (get-macro-spec access-fn *script-setf-expanders*)
         (compile nil
                  (let ((var-bindings (ordered-set-difference lambda-list lambda-list-keywords)))
                    `(lambda (access-fn-args store-form)
@@ -410,7 +410,7 @@ lambda-list::=
 
 (ps:defscriptmacro defsetf-short (access-fn update-fn &optional docstring)
   (declare (ignore docstring))
-  (setf (find-macro-spec access-fn *script-setf-expanders*)
+  (setf (get-macro-spec access-fn *script-setf-expanders*)
         (lambda (access-fn-args store-form)
           `(,update-fn ,@access-fn-args ,store-form)))
   nil)
@@ -420,11 +420,11 @@ lambda-list::=
 
 (defpsmacro setf (&rest args)
   (flet ((process-setf-clause (place value-form)
-           (if (and (listp place) (find-macro-spec (car place) *script-setf-expanders*))
-               (funcall (find-macro-spec (car place) *script-setf-expanders*) (cdr place) value-form)
+           (if (and (listp place) (get-macro-spec (car place) *script-setf-expanders*))
+               (funcall (get-macro-spec (car place) *script-setf-expanders*) (cdr place) value-form)
                (let ((exp-place (expand-script-form place)))
-                 (if (and (listp exp-place) (find-macro-spec (car exp-place) *script-setf-expanders*))
-                     (funcall (find-macro-spec (car exp-place) *script-setf-expanders*) (cdr exp-place) value-form)
+                 (if (and (listp exp-place) (get-macro-spec (car exp-place) *script-setf-expanders*))
+                     (funcall (get-macro-spec (car exp-place) *script-setf-expanders*) (cdr exp-place) value-form)
                      `(parenscript.javascript::setf1% ,exp-place ,value-form))))))
     (assert (evenp (length args)) ()
             "~s does not have an even number of arguments." (cons 'setf args))
index 02c8a34..f7c4f1c 100644 (file)
@@ -4,3 +4,24 @@
 (defscriptclass script-quote (ps-js::expression)
   ())
 
+;;; Compilation environment stuff
+
+(defvar *compilation-environment* nil
+  "The active compilation environment."
+;; Right now all code assumes that *compilation-environment* is accurately bound to the
+;; current compilation environment--even some functions that take the compilation environment
+;; as arguments.
+  )
+
+;; environmental considerations
+(defgeneric setup-compilation-environment (comp-env)
+  (:documentation "Sets up a basic compilation environment prepared for a language user.
+This should do things like define packages and set the current package.
+
+Returns the compilation-environment."))
+
+(defun make-basic-compilation-environment ()
+  "Creates a compilation environment object from scratch.  Fills it in with the default
+script packages (parenscript, global, and parenscript-user)."
+  (let ((*compilation-environment* (make-instance 'compilation-environment)))
+    (setup-compilation-environment *compilation-environment*)))
\ No newline at end of file