root/trunk/pcc/runtime/constants.scm

Revision 339, 6.7 KB (checked in by weyrick, 12 months ago)

move these type annotations to bstring. in bigloo, string means a c string so
this causes an unnecessary type caste in the generated c code because we only
ever use these with bstrings

Line 
1;; ***** BEGIN LICENSE BLOCK *****
2;; Roadsend PHP Compiler Runtime Libraries
3;; Copyright (C) 2007 Roadsend, Inc.
4;;
5;; This program is free software; you can redistribute it and/or
6;; modify it under the terms of the GNU Lesser General Public License
7;; as published by the Free Software Foundation; either version 2.1
8;; of the License, or (at your option) any later version.
9;;
10;; This program is distributed in the hope that it will be useful,
11;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13;; GNU Lesser General Public License for more details.
14;;
15;; You should have received a copy of the GNU Lesser General Public License
16;; along with this program; if not, write to the Free Software
17;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18;; ***** END LICENSE BLOCK *****
19(module constants
20   (export
21    (reset-constants!)
22    (constant-defined? name::bstring)
23    (lookup-constant name::bstring)
24    (lookup-constant/smash name::pair)
25    (store-constant name::bstring value case-insensitive?)
26    (store-persistent-constant name::bstring value)
27    (store-special-constant name::bstring value)
28    (constants-for-each k)
29    (php-constant? value)
30    *PHP-LINE*
31    *PHP-FILE*))
32
33;;;; constants
34
35;;these are "superconstants".  They actually change value, so they are
36;;associated with a function for getting the current value.
37(define *special-constants* (make-hashtable))
38
39(define *PHP-LINE* 0)
40(define *PHP-FILE* "unknown")
41
42; magical constants
43(store-special-constant "__FILE__" (lambda () *PHP-FILE*))
44(store-special-constant "__LINE__" (lambda () *PHP-LINE*))
45
46; these are defined in php-errors, where the stack tracing happens
47;(store-special-constant "__CLASS__" (lambda () ""))
48;(store-special-constant "__METHOD__" (lambda () ""))
49;(store-special-constant "__FUNCTION__" (lambda () ""))
50
51; store a magical "dynamic constant"
52(define (store-special-constant name::bstring value)
53   (hashtable-put! *special-constants* name value))
54
55(define %constant-not-defined% (cons '() '()))
56
57;;these are user-defined constants (from the define() function)
58(define *constant-table* (make-hashtable))
59
60;;these are system-defined constants made using DEFCONSTANT  It's
61;;called persistent because they are not removed from the table
62;;between requests.
63(define *persistent-constant-table* (make-hashtable))
64
65(define (reset-constants!)
66   (set! *constant-table* (make-hashtable)))
67
68(define (constant-defined? name::bstring)
69   (if (eq? (%get-constant name) %constant-not-defined%)
70       #f
71       #t))
72
73(define (lookup-constant name::bstring)
74   ;;XXX looks like special constants can't return false!
75   (let ((c (%get-constant name)))
76      (if (eq? c %constant-not-defined%)
77          ;;XXX perhaps there should be an "undefined constant" warning here
78          name
79          c)))
80
81
82;; this is lookup-constant, except it also stores the %constant
83;; structure into the cdr of the pair that gets passed in.
84;; We're playing fast and loose with literal scheme constants as well
85;; as constant redefinition in php here, so expect bugs.  But it's a
86;; first shot.
87(define (lookup-constant/smash name::pair)
88   (if (null? (cdr name))
89       ;; no previous looked cached
90       (let ((c (%get-constant-itself (car name))))
91          (if (%constant? c)
92              (begin
93                 (set-cdr! name c)
94                 (%constant-value c))
95              ;; we don't cache a failed lookup
96              (if (eq? c %constant-not-defined%)
97                  ;; it's undefined, so return the name
98                  (car name)
99                  ;; it's not a constant, and it's not undefined, so it
100                  ;; must be a special-constant
101                  c)))
102       (%constant-value (cdr name))))
103
104
105(define (store-constant name::bstring value case-insensitive?)
106   ;;store a plain user constant
107   ;;does not override existing constants
108   (%put-constant name value case-insensitive? #f #f))
109
110(define (store-persistent-constant name::bstring value)
111   ;;store a constant that won't be discarded on page reload
112   ;;overrides existing constants
113   (%put-constant name value #f #t #t))
114
115
116(define (constants-for-each k)
117   ;;call k once for each constant, persistent ones first,
118   ;;excluding the special constants
119   (hashtable-for-each *persistent-constant-table* (lambda (key val) (k key (%constant-value val))))
120   (hashtable-for-each *constant-table* (lambda (key val) (k key (%constant-value val)))))
121
122(define-struct %constant
123   name
124   value
125   case-insensitive?)
126
127(define (php-constant? val)
128   ;; analagous to php-hash? php-object? etc
129   (%constant? val))
130
131(define (%put-constant name value case-insensitive? persistent? force?)
132   ;;only define the constant if it's being defined for the first time,
133   ;;or FORCE? is true
134   
135   ;; PHP 4.3.7 allows for an uppercase
136   ;; case-sensitive constant to coexist with
137   ;; a case insensitive one of the same name,
138   ;; hence we use string-downcase.
139   (when case-insensitive? (set! name (string-downcase name)))
140   (if (or force?
141           ;;%get-constant will find it if there's already a case-insensitive
142           ;;constant and we're defining a case-sensitive one, so we do the lookup
143           ;;ourselves
144           (not (or (hashtable-get *special-constants* name)
145                    (hashtable-get *persistent-constant-table* name)
146                    (hashtable-get *constant-table* name))))
147       (begin
148          (hashtable-put! (if persistent?
149                           *persistent-constant-table*
150                           *constant-table*)
151                       name
152                       (%constant name value case-insensitive?))
153          #t)
154       #f))
155
156
157(define (%get-constant name)
158   (let ((the-constant (%get-constant-itself name)))
159      (if (eq? the-constant %constant-not-defined%)
160          %constant-not-defined%
161          (if (%constant? the-constant)
162              (%constant-value the-constant)
163              ;; special constant
164              the-constant))))
165       
166
167(define (%get-constant-itself name)
168   (let* ((special-constant-function (hashtable-get *special-constants* name)))
169      (if special-constant-function
170          ;;the special constants aren't constant at all.  instead we call
171          ;;their function to get their current value.
172          (special-constant-function) 
173          ;;normal constants are first looked up case-insensitively
174          (let* ((lname (string-downcase name))
175                 (the-constant (or (hashtable-get *persistent-constant-table* name)
176                                   (hashtable-get *persistent-constant-table* lname)
177                                   ;;lookup the case-sensitive constant first
178                                   (hashtable-get *constant-table* name)
179                                   ;;now lookup the case-insensitive version
180                                   (hashtable-get *constant-table* lname))))
181             (if the-constant
182                 (if (%constant-case-insensitive? the-constant)
183                     the-constant
184                     ;;if the constant is case-sensitive, make sure we've got the right case
185                     (if (string=? name (%constant-name the-constant))
186                         the-constant
187                         %constant-not-defined%))
188                 %constant-not-defined%)))))
Note: See TracBrowser for help on using the browser.