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:
- load the script (okay to be hardcoded for now)
- evaluate the script into a procedure
- execute the procedure and return the xexpr
We can accomplish the above with:
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:
;; 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))
)))
;; 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