Implemented fluid-based variable references and setting using setq.
authorDaniel Kraft <d@domob.eu>
Fri, 3 Jul 2009 21:00:12 +0000 (23:00 +0200)
committerDaniel Kraft <d@domob.eu>
Fri, 3 Jul 2009 21:00:12 +0000 (23:00 +0200)
* module/language/elisp/README: Document this.
* module/language/elisp/compile-tree-il.scm: Implement variable references, setq
* module/language/elisp/runtime.scm: New file for runtime definitions.
* module/language/elisp/runtime/function-slot.scm: Ditto.
* module/language/elisp/runtime/value-slot.scm: Ditto.

module/language/elisp/README
module/language/elisp/compile-tree-il.scm
module/language/elisp/runtime.scm [new file with mode: 0644]
module/language/elisp/runtime/function-slot.scm [new file with mode: 0644]
module/language/elisp/runtime/value-slot.scm [new file with mode: 0644]

index fab9f62..124af17 100644 (file)
@@ -7,8 +7,9 @@ as status information.
 Already implemented:
   * progn
   * if, cond
-  * and
+  * and, or
   * quote
+  * referencing and setting (setq) variables
 
 Especially still missing:
   * other progX forms, will be done in macros
@@ -16,7 +17,10 @@ Especially still missing:
   * while, other loops using macros
   * catch/throw, unwind-protect
   * real elisp reader instead of Scheme's
-  * handling of variables: setq, referencing, let -- using fluids for scoping
+  * let, set based on setq
+  * makunbound, boundp
+  * automatic creation of fluids when needed
   * macros
   * general primitives (+, -, *, cons, ...)
   * functions, lambdas
+  * defvar, defun
index ae27533..7583368 100644 (file)
 (define (t-value loc) (make-const loc #t))
 
 
+; Modules that contain the value and function slot bindings.
+
+(define runtime '(language elisp runtime))
+(define value-slot '(language elisp runtime value-slot))
+(define function-slot '(language elisp runtime function-slot))
+
+
+; Error reporting routine for syntax/compilation problems.
+
+(define (report-error loc . args)
+  (apply error args))
+
+
+; Generate code to ensure a fluid is there for further use of a given symbol.
+
+(define (ensure-fluid! loc sym module)
+  ; FIXME: Do this!
+  (make-void loc))
+
+
+; Generate code to reference a fluid saved variable.
+
+(define (reference-variable loc sym module)
+  (make-sequence loc
+    (list (ensure-fluid! loc sym module)
+          (make-application loc (make-primitive-ref loc 'fluid-ref)
+            (list (make-module-ref loc module sym #f))))))
+
+
+; Reference a variable and error if the value is void.
+
+(define (reference-with-check loc sym module)
+  (let ((var (gensym)))
+    (make-let loc '(value) `(,var) `(,(reference-variable loc sym module))
+      (make-conditional loc
+        (make-application loc (make-primitive-ref loc 'eq?)
+          (list (make-module-ref loc runtime 'void #t)
+                (make-lexical-ref loc 'value var)))
+        (make-application loc (make-primitive-ref loc 'error)
+          (list (make-const loc "variable is void:")
+                (make-const loc sym)))
+        (make-lexical-ref loc 'value var)))))
+
+
+; Generate code to set a fluid saved variable.
+
+(define (set-variable! loc sym module value)
+  (make-sequence loc
+    (list (ensure-fluid! loc sym module)
+          (make-application loc (make-primitive-ref loc 'fluid-set!)
+            (list (make-module-ref loc module sym #f)
+                  value)))))
+
+
 ; Compile a symbol expression.  This is a variable reference or maybe some
 ; special value like nil.
 
 
     ((t) (t-value loc))
     
-    ; FIXME: Use fluids.
     (else
-      (make-module-ref loc '(language elisp variables) sym #f))))
+      (reference-with-check loc sym value-slot))))
 
 
 ; Compile a pair-expression (that is, any structure-like construct).
                (make-lexical-ref loc 'condition var)
                (iterate (cdr tail))))))))
 
+    ; Build a set form for possibly multiple values.  The code is not formulated
+    ; tail recursive because it is clearer this way and large lists of symbol
+    ; expression pairs are very unlikely.
+    ((setq . ,args)
+     (make-sequence loc
+       (let iterate ((tail args))
+         (if (null? tail)
+           (list (make-void loc))
+           (let ((sym (car tail))
+                 (tailtail (cdr tail)))
+             (if (not (symbol? sym))
+               (report-error loc "expected symbol in setq")
+               (if (null? tailtail)
+                 (report-error loc "missing value for symbol in setq" sym)
+                 (let* ((val (compile-expr (car tailtail)))
+                        (op (set-variable! loc sym value-slot val)))
+                   (cons op (iterate (cdr tailtail)))))))))))
+
     (('quote ,val)
      (make-const loc val))
 
     (else
-      (error "unrecognized elisp" expr))))
+      (report-error loc "unrecognized elisp" expr))))
 
 
 ; Compile a single expression to TreeIL.
diff --git a/module/language/elisp/runtime.scm b/module/language/elisp/runtime.scm
new file mode 100644 (file)
index 0000000..871f3a2
--- /dev/null
@@ -0,0 +1,28 @@
+;;; Guile Emac Lisp
+
+;; Copyright (C) 2001 Free Software Foundation, Inc.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;; 
+;; This program 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 General Public License for more details.
+;; 
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+(define-module (language elisp runtime)
+  #:export (void ensure-fluid! set-value! get-value unbind! bound?))
+
+; This module provides runtime support for the Elisp front-end.
+
+; The reserved value to mean (when eq?) void.
+(define void (list 42))
diff --git a/module/language/elisp/runtime/function-slot.scm b/module/language/elisp/runtime/function-slot.scm
new file mode 100644 (file)
index 0000000..05aa6ee
--- /dev/null
@@ -0,0 +1,24 @@
+;;; Guile Emac Lisp
+
+;; Copyright (C) 2001 Free Software Foundation, Inc.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;; 
+;; This program 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 General Public License for more details.
+;; 
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+(define-module (language elisp runtime value-slot))
+
+; This module contains the function-slots of elisp symbols.
diff --git a/module/language/elisp/runtime/value-slot.scm b/module/language/elisp/runtime/value-slot.scm
new file mode 100644 (file)
index 0000000..201813a
--- /dev/null
@@ -0,0 +1,24 @@
+;;; Guile Emac Lisp
+
+;; Copyright (C) 2001 Free Software Foundation, Inc.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;; 
+;; This program 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 General Public License for more details.
+;; 
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+(define-module (language elisp runtime value-slot))
+
+; This module contains the value-slots of elisp symbols.