Tuesday, August 11, 2009

A Simple First SHP

To use SHP - we should define start as follows:
(define start
(make-shp-handler "c:\\shp"))

SHP handler would then create a dispatcher based on the path, and call the appropriate script to handle the request.

A SHP page could look like:

;; index.shp
;; index.shp will be the default page displayed
;; notice we return an xexpr for this page
`(p "this is a test page")


Let's try to use the above to develop a very simple SHP handler. We want the following:
  1. load the script (okay to be hardcoded for now)
  2. evaluate the script into a procedure
  3. execute the procedure and return the xexpr


We can accomplish the above with:


;; read all terms
(define (read-all in)
(define (helper acc)
(let ((term (read in)))
(if (eof-object? term)
(reverse acc)
(helper (cons term acc)))))
(helper '()))

;; convert file into complete terms
(define (file->values path)
(call-with-input-file path read-all))

(define (make-shp-handler path)
(lambda (request)
;; let's load the request page. we'll hard code the page for now
(let ((terms (file->values (build-path path "index.shp"))))
;; once we loaded the page we'll conver the page's expressions into a procedure
(let ((proc (eval `(lambda (request) . ,terms))))
;; then we can call the procedure.
(proc request))
)))
Great! We now have a trivial functional SHP system! Every request will load index.shp and reevaluate the script into a procedure to return results. Because the script gets evaluated into a scheme procedure (yes I know some of you are thinking this is dangerous... later on that topic), we can directly include inline scheme functions via quasiquotes:


;; index.shp
;; index.shp will be the default page displayed
;; notice we return an xexpr for this page
;; below will return 6
`(p "this is a test page = " ,(number->string (+ 1 2 3)))


We can use this as the basis for further development to add features, robustness, and performance, but for now this is good enough for the first shot!

No comments:

Post a Comment