Category: misc


; mooix



Navigation:    Index Top-Level Index Text Version (No Diffs)
Last Modified: Thu Oct 5 11:49:37 2006
 

; To make a mooix file, wrap a single procedure of one argument in (mooix ...).
; mooix coerces the values returned into the correct form. It accepts the following return values:
; A number - converted to a string
; A string - left alone
; A mooix object reference - converted to its ID string
; A list of any of the above - each element converted, elements seperated by newlines
;
; The first argument passed in by mooix is the mooix object the code is on, the second is the parameters the method was called with, as a list.
; The input parameter code coerces mooix objects and numbers into their Scheme types

; NB: all code that is passed or returns values used as booleans must respect Perl boolean conventions, to wit: FILL IN

; Need to be able to distinguish built-in methods from actual mooix object methods, so need both dispatch and can-dispatch funcs
; dispatch on strings, not idents, since files can start with . and so on

(define (mooix code)
; The core bit: get inbound args, pass them to the given code, process the outbound args
(process-return
(code
; TODO: $this should be passed here
(process-args)
)
)
; mooix objects are largely glorified wrappers to dispatch
; TODO: is dir the right internal data bit??
(define (mooix-obj dir)
(letrec ((this ; NB: we use "this" in this def'n; I believe this to be legal due to the lambda, but not sure until actually run
(lambda (method . args)
; base data selectors
(cond
((string=? method "dir") dir)
(else (dispatch this method args))
)
)))
this
)
)
(define (dispatch this method args)
(display ("In dispatch: " (this "dir") method args) (current-error-port))
(cond
; built-in methods
((assoc method dispatch-table) => (lambda (meth) (meth this args)))
; file methods/fields
(else (file-dispatch this method args))
)
)
; Call on-disk method or retrieve/set field value
(define (file-dispatch this method args)
(let ((file (this "fieldfile" (list method))))
(if (and file (file-exists? file))
(if (regular-file? file)
; Regular on-disk field or method call
(if (file-execute-access? method)
(file-field this method args)
(file-method this method args)
)
; File is dir or symlink - return associated mooix object
(if (and (directory? file) (file-exists? (make-absolute-path file ".mooix")))
; "file" is mooix dir
(mooix-obj file)
(if (and (symbolic-link? file) (file-exists? (make-absolute-path (read-symbolic-link file) ".mooix")))
; "file" is mooix dir
(mooix-obj (read-symbolic-link file))
; Not regular file, not mooix obj - badness
(and (display ("Object " (obj "fieldget_lang" "name") " has no regular field or method or mooix object pointer named " file ".") (current-error-port)) #f)
)
)
)
; No such file - might be setting a new field
(if (= (length args) 1)
(obj "setfield" file (car args))
(and (display ("Object " (obj "fieldget_lang" "name") " has no field or method named " file " at all.") (current-error-port)) #f)
)
)
)
)
; Call a method from a file
(define (file-method this method args)
(let ((file (this "fieldfile" (list method))))
(let-values (
((fromport toport pid)
; We pass the empty argument string just to avoid the shell
(process file ""))
)
(display (scheme->mooix-string this) toport)
(display (scheme->mooix-string args) toport)
(mooix-string->scheme (read-string from-port))
)
)
)
; TODO: inline this?
(define (process-return list)
(scheme->mooix-string list)
)
; TODO: inline this?
(define (process-args)
(mooix-string->scheme (read-string))
)