root/trunk/pcc/runtime/ext/skeleton/php-skeleton.scm

Revision 408, 10.0 kB (checked in by weyrick, 6 months ago)

more documentation of the skeleton extension

Line 
1 ;; ***** BEGIN LICENSE BLOCK *****
2 ;; Roadsend PHP Compiler Runtime Libraries
3 ;; Copyright (C) 2008 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
20 (module php-skeleton-lib
21    ; required
22    (include "../phpoo-extension.sch")
23    (library profiler)
24    ; import any required modules here, e.g. c bindings
25    (import
26     (skeleton-c-bindings "c-bindings.scm"))
27    ;
28    ; list of exports. should include all defbuiltin and defconstant
29    ;
30    (export
31     (init-php-skeleton-lib)
32     ;
33     SKELETON_CONST
34     ;
35     (skel_hello_world var1)
36     (skel_hash str int)
37     ;
38     ))
39
40 ;
41 ; this procedure needs to exist, but it need not
42 ; do much (normally just returns 1).
43 ;
44 (define (init-php-skeleton-lib) 1)
45
46 ; all top level statements are run on module initialization
47 ; here we will initalize our builtin class
48 (create-skeleton-class)
49
50 ; register the extension. required. note: version is not checked anywhere right now
51 (register-extension "skeleton" ; extension title, shown in e.g. phpinfo()
52                     "1.0.0"              ; version
53                     "skeleton")          ; library name. make sure this matches LIBNAME in Makefile
54
55 ;
56 ; this is how you can define a PHP resource. these are
57 ; opaque objects in PHP, like a socket or database connection
58 ; defresource is mostly a wrapper for define-struct.
59 ; "Sample Resource" is the string this object coerces to
60 ; in php land, if you try to print it
61 ;
62 ;(defresource php-skel-resource "Sample Resource"
63 ;   field1
64 ;   field2)
65
66 ;
67 ; if you use resources, you should use some code like that below
68 ; which handles resource finalization. see the mysql extension,
69 ; for example
70 ;
71
72 ; (define *resource-counter* 0)
73 ; (define (make-finalized-resource)
74 ;    (when (> *resource-counter* 255) ; an arbitrary constant which may be a php.ini entry
75 ;       (gc-force-finalization (lambda () (<= *resource-counter* 255))))
76 ;    (let ((new-resource (php-skel-resource 1 2)))
77 ;       (set! *resource-counter* (+fx *resource-counter* 1))
78 ;       (register-finalizer! new-resource (lambda (res)
79 ;                                          ; some theoretical procedure that closes the resource properly
80 ;                                          (resource-cleanup res)
81 ;                                          (set! *resource-counter* (- *resource-counter* 1)))))
82 ;       new-resource)
83
84
85 ;;;;;;;;;;;;;;;;;;;;;;;;;;; PHP TYPES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
86 ;
87 ; Bigloo itself supports a variety of types, but the only ones we
88 ; use in PHP land are: string, boolean, onum, php-hash and php-object
89 ;
90 ; You can use the normal bigloo functions for dealing with strings
91 ; and booleans:
92 ;
93 ; string?
94 ; boolean?
95 ; make-string
96 ; string=?
97 ; substring
98 ; ... etc
99 ;
100 ; Otherwise we have to do type juggling. If a bigloo type winds up
101 ; in php land (such as a fixnum (bint) or #unspecified), it will
102 ; show up strange when coerced to a string (i.e. ":ufo:") and may cause
103 ; calculations to fail in general.
104 ;
105 ; "onum" is an "opaque number" and represents all numbers in php land.
106 ; it follows zend's semantics for overflowing an integer into a float. you
107 ; can use: onum-long? and onum-float? to see which it is
108 ;
109 ; You should use php versions of some normal scheme functions when
110 ; dealing with php types. See runtime/php-types.scm and runtime/php-operators.scm
111 ;
112 ; Some commonly used functions:
113 ;
114 ; php-null?  php-empty?  php-hash?  php-object?  php-number?
115 ;
116 ; php-+  php--  php-=  php-/  php-*  php-%
117 ;
118 ;
119 ; There are a few constants that should be used as well:
120 ;
121 ; NULL
122 ; TRUE
123 ; FALSE
124 ; *zero*
125 ; *one*
126 ;
127 ;;;;;;;;;;;;
128 ;
129 ; NOTE: You should coerce all input variables and return values to the required PHP type
130 ;
131 ; convert-to-number  - returns an onum, may be long or float depending on input
132 ; convert-to-float   - returns an onum, forces float
133 ; convert-to-integer - returns an onum, forces integer
134 ; convert-to-boolean - returns boolean
135 ; convert-to-string  - returns string (also see mkstr)
136 ;
137 ;;;;;
138
139
140 ;;;;;;;;;;;;;;;;;;;;;;; LOCAL FUNCTIONS ;;;;;;;;;;;;;;;;;;;;;;;;;;
141 ;
142 ; Normal scheme procedures created with define are not callable by
143 ; PHP scripts.
144 ;
145
146 ;
147 ; here we have a scheme procedure that's run on init, which creates
148 ; a builtin php object
149 ;
150 (define (create-skeleton-class)
151
152    ; define a "builtin" class or interface. interfaces are simply abstract
153    ; classes, but the 'interface flag should be used so the object system
154    ; knows it is implementable
155    ;
156    ; a builtin class means it is always available while this extension is loaded,
157    ; and it doesn't disappear at runtime reset
158
159    ; note that for class/interface names, property names and method names, case
160    ; will be kept but only properties are actually case sensitive
161   
162    ; class or interface defition. note that parent classes and interfaces should be defined
163    ; first if the class will extend any
164    (define-builtin-php-class 'Skeleton   ; class name. a symbol
165                              '()         ; extends, a list of one entry, a symbol
166                              '()         ; implements, a list of symbols
167                              '()         ; flags: abstract, interface, final
168                              )
169
170    ; define a class property
171    (define-php-property 'Skeleton           ; the class name. a symbol.
172                         "message"           ; the property name. a string.
173                         "default message"   ; default value, a string or other php type (e.g. NULL)
174                         'protected          ; visibility, one of: public, private, protected
175                         #f                  ; static?
176                         )
177
178    ; define a php class method
179    (define-php-method 'Skeleton             ; the class name, a symbol.
180                       "__construct"         ; method name, a string.
181                       '(public)             ; flags: public, private, protected, final, abstract
182                       Skeleton:__construct  ; scheme procedure that implements this method (see below)
183                       )
184
185    )
186
187 ;
188 ; Skeleton::__construct
189 ;
190 ; This is the scheme procedure that implements the "__construct" method for
191 ; the Skeleton class, as defined in define-php-method above. The procedure
192 ; name is arbitrary, but the arguments must be handled as shown. The first
193 ; parameter will always be $this, which will always be a php-object or NULL
194 ; for static methods.
195 ;
196 ; optional-args is a list of possible arguments that were passed into the method.
197 ; this method looks for two arguments, message and code.
198 ;
199 (define (Skeleton:__construct this-unboxed . optional-args)
200    (let ((message '())
201          (code '()))
202       ; do we have arguments passed in?
203       (when (pair? optional-args)
204          ; yes, the first is message. save it and shift the argument list.
205          (set! message
206                (maybe-unbox (car optional-args)))
207          (set! optional-args (cdr optional-args)))
208       ; do we have another argument?
209       (when (pair? optional-args)
210          ; yes, save it as code. we aren't looking for any more,
211          ; so don't bother with a shift
212          (set! code
213                (maybe-unbox (car optional-args))))
214       ;
215       ; if the arguments now have a value, set our local properties
216       ; note that 'all means we don't do a visibility check
217       ;
218       (when message
219          (php-object-property-set!/string this-unboxed "message" message 'all))
220       (when code
221          (php-object-property-set!/string this-unboxed "code" code 'all))))
222
223
224 ;;;;;;;;;;;;;;;
225
226
227 ; a little function to compute x^n. not we don't do type conversion
228 ; here, we assume it's done by our defbuiltin caller. that means
229 ; we're just using bigloo's fixnums here. we've added type annotation
230 ; to that effect (::bint)
231 (define (my-little-expt x::bint n::bint)
232    (expt x n))
233
234 ;;;;;;;;;;;;;;;; PHP VISIBLE BUILTIN FUNCTIONS ;;;;;;;;;;;;;;;;;;;
235 ;
236 ; Functions created with the defbuiltin macro are visible to
237 ; PHP scripts
238 ;
239
240 ;
241 ; defbuiltin creates a builtin php function
242 ;
243
244 ; take one parameter, echo it with a worldly greeting
245 (defbuiltin (skel_hello_world var1)
246    ; one way to do debugging: add a debug-trace. the first parameter
247    ; is the required debug level for the output to be shown (via -d)
248    ;
249    (debug-trace 1 "this is a debug message, shown at level 1. var1 is: " var1)
250    ;
251    (echo (mkstr "hello world" var1)))
252
253 ; take two parameters and return a hash with two entries,
254 ; one for each parameter. we'll force str to be a string,
255 ; and int to be a number
256 (defbuiltin (skel_hash str int)
257    (let ((result (make-php-hash)))
258       ; :next is a special key which will use the next available int key
259       ; mkstr coerces to a string
260       ; convert-to-number coerces to a php number (onum)
261       (php-hash-insert! result :next (mkstr str))
262       (php-hash-insert! result :next (convert-to-number str))
263       ; we can also specify a string key
264       (php-hash-insert! result "somekey" "some value")
265       result))
266
267 ; this function uses our help scheme function above
268 ; note that we do the type conversions here, and there is no
269 ; type annotation for defbuiltin parameters. also, we have to
270 ; not only convert the parameters, but the return value!
271 (defbuiltin (skel_expt x n)
272    ; mkfixnum makes a bigloo fixnum (bint)
273    ; it should only be used be calling bigloo functions
274    ; that require it, otherwise stick with onum (php numbers)
275    ; or bigloo elong
276    (let ((real-x (mkfixnum x))
277          (real-n (mkfixnum n)))
278       ; convert-to-number ensures we return a php number (onum)
279       ; see definition on my-little-expt in LOCAL FUNCTIONS section above
280       (convert-to-number (my-little-expt real-x real-n))))
281    
282 ;;;;;;;;;;;;;;;;;;;;; PHP VISIBLE CONSTANTS ;;;;;;;;;;;;;;;;;;;;;
283 ;
284 ; Constants created with the defconstant macro are visible to
285 ; PHP scripts
286 ;
287
288 ;
289 ; defconstant creates a builtin constant
290 ; note, values are automatically coerced to php types
291 ;
292 (defconstant SKELETON_CONST  0)
293
Note: See TracBrowser for help on using the browser.