179 lines
5.7 KiB
Scheme
179 lines
5.7 KiB
Scheme
;;; -*-Scheme-*-
|
|
|
|
(define type-name #f)
|
|
|
|
(define classes '())
|
|
(define callbacks '())
|
|
(define primitives '())
|
|
(define converters '())
|
|
|
|
(define f)
|
|
|
|
(define (check-string proc x name)
|
|
(if (not (memq (type x) '(symbol string)))
|
|
(error proc (format #f "~s must be string or symbol" name))))
|
|
|
|
(define (define-widget-type name include)
|
|
(if type-name
|
|
(error 'define-widget-type "must be called once"))
|
|
(check-string 'define-widget-type name 'name)
|
|
(if (pair? include)
|
|
(for-each
|
|
(lambda (i) (check-string 'define-widget-type i 'include)) include)
|
|
(check-string 'define-widget-type include 'include))
|
|
(set! type-name name)
|
|
(format f "#include \"../xt.h\"~%")
|
|
(case widget-set
|
|
(motif
|
|
(format f "#include <Xm/Xm.h>~%")))
|
|
(if (and (not (eqv? include "")) (not (null? include)))
|
|
(begin
|
|
(define dir)
|
|
(case widget-set
|
|
(motif
|
|
(set! dir "Xm"))
|
|
(xaw
|
|
(set! dir "X11/Xaw")))
|
|
(if (pair? include)
|
|
(for-each
|
|
(lambda (i)
|
|
(if (char=? (string-ref (format #f "~a" i) 0) #\<)
|
|
(format f "#include ~a~%" i)
|
|
(format f "#include <~a/~a>~%" dir i)))
|
|
include)
|
|
(if (char=? (string-ref (format #f "~a" include) 0) #\<)
|
|
(format f "#include ~a~%" include)
|
|
(format f "#include <~a/~a>~%" dir include)))))
|
|
(newline f))
|
|
|
|
(define (prolog code)
|
|
(if (not type-name)
|
|
(error 'prolog "must define a widget-type first"))
|
|
(check-string 'prolog code 'code)
|
|
(display code f)
|
|
(format f "~%~%"))
|
|
|
|
(define (define-callback class name has-arg?)
|
|
(check-string 'define-callback class 'class)
|
|
(check-string 'define-callback name 'name)
|
|
(if (not (boolean? has-arg?))
|
|
(error 'define-callback "has-arg? must be boolean"))
|
|
(set! callbacks (cons (list class name has-arg?) callbacks)))
|
|
|
|
(define (c->scheme name body)
|
|
(check-string 'c->scheme name 'name)
|
|
(define c-name (scheme-to-c-name name))
|
|
(string-set! c-name 0 #\S)
|
|
(format f "static Object ~a (XtArgVal x) {~%" c-name)
|
|
(display body f)
|
|
(format f "~%}~%~%")
|
|
(define s
|
|
(format #f " Define_Converter_To_Scheme (\"~a\", ~a);~%"
|
|
name c-name))
|
|
(set! converters (cons s converters)))
|
|
|
|
(define (scheme->c name body)
|
|
(check-string 'scheme->c name 'name)
|
|
(define c-name (scheme-to-c-name name))
|
|
(string-set! c-name 0 #\C)
|
|
(format f "static XtArgVal ~a (Object x) {~%" c-name)
|
|
(display body f)
|
|
(format f "~%}~%~%")
|
|
(define s
|
|
(format #f " Define_Converter_To_C (\"~a\", ~a);~%"
|
|
name c-name))
|
|
(set! converters (cons s converters)))
|
|
|
|
(define (define-primitive scheme-name args body)
|
|
(check-string 'define-primitive scheme-name 'scheme-name)
|
|
(if (not (pair? args))
|
|
(error 'define-primitive "args must be a list"))
|
|
(define c-name (scheme-to-c-name scheme-name))
|
|
(format f "static Object ~a (" c-name)
|
|
(do ((a args a)) ((null? a))
|
|
(display "Object " f)
|
|
(display (car a) f)
|
|
(set! a (cdr a))
|
|
(if (not (null? a)) (display ", " f)))
|
|
(display ") {" f)
|
|
(newline f)
|
|
(display body f)
|
|
(format f "~%}~%~%")
|
|
(define s
|
|
(format #f " Define_Primitive (~a, \"~a\", ~a, ~a, EVAL);~%"
|
|
c-name scheme-name (length args) (length args)))
|
|
(set! primitives (cons s primitives)))
|
|
|
|
;;; [missing conversion from -> to "to"]
|
|
(define (scheme-to-c-name s)
|
|
(if (symbol? s)
|
|
(set! s (symbol->string s)))
|
|
(define len (string-length s))
|
|
(if (char=? (string-ref s (1- len)) #\?)
|
|
(string-set! s (1- len) #\p))
|
|
(if (char=? (string-ref s (1- len)) #\!)
|
|
(set! len (1- len)))
|
|
(let loop ((ret "P") (i 0))
|
|
(if (>= i len)
|
|
ret
|
|
(define next
|
|
(do ((j i (1+ j)))
|
|
((or (= j len) (memq (string-ref s j) '(#\- #\:))) j)))
|
|
(loop (format #f "~a_~a~a" ret (char-upcase (string-ref s i))
|
|
(substring s (1+ i) next)) (1+ next)))))
|
|
|
|
(define (define-widget-class name class . sub-resources)
|
|
(check-string 'define-widget-class name 'name)
|
|
(check-string 'define-widget-class class 'class)
|
|
(set! classes (cons (list name class sub-resources) classes)))
|
|
|
|
(define (feature-name fn)
|
|
(let ((i (substring? ".d" fn)))
|
|
(display "filename: ") (display fn) (newline)
|
|
(if (not i)
|
|
(error 'mkwidget "bad filename suffix in ~a (expected .d)" fn))
|
|
(string->symbol (substring fn 0 i))))
|
|
|
|
(define args (command-line-args))
|
|
(if (not (= (length args) 3))
|
|
(error 'mkwidget "expected three arguments"))
|
|
(define widget-set (string->symbol (caddr args)))
|
|
(set! f (open-output-file (cadr args)))
|
|
(load (car args))
|
|
(if (not type-name)
|
|
(error 'mkwidget "no widget type defined"))
|
|
(format f "void elk_init_~a_~a () {~%" widget-set type-name)
|
|
(if (not (null? classes))
|
|
(format f " XtResourceList r = 0;~%"))
|
|
(do ((c classes (cdr c))) ((null? c))
|
|
(define cl (car c))
|
|
(define res (caddr cl))
|
|
(if (not (null? res))
|
|
(begin
|
|
(format f
|
|
" r = (XtResourceList)XtMalloc (~a * sizeof (XtResource));~%"
|
|
(length res))
|
|
(do ((r res (cdr r)) (num 0 (1+ num))) ((null? r))
|
|
(define x (car r))
|
|
(if (not (= (length x) 3))
|
|
(error 'mkwidget "bad sub-resource declaration"))
|
|
(for-each
|
|
(lambda (r)
|
|
(if (not (memq (type r) '(symbol string)))
|
|
(error 'mkwidget "bad type in sub-resource declaration")))
|
|
x)
|
|
(format f " r[~a].resource_name = \"~a\";~%" num (car x))
|
|
(format f " r[~a].resource_class = \"~a\";~%" num (cadr x))
|
|
(format f " r[~a].resource_type = \"~a\";~%" num (caddr x)))))
|
|
(format f " Define_Class (\"~a\", ~a, r, ~a);~%" (car cl) (cadr cl)
|
|
(length res)))
|
|
(do ((c callbacks (cdr c))) ((null? c))
|
|
(define cb (car c))
|
|
(format f " Define_Callback (\"~a\", \"~a\", ~a);~%" (car cb) (cadr cb)
|
|
(if (caddr cb) 1 0)))
|
|
(for-each (lambda (x) (display x f)) primitives)
|
|
(for-each (lambda (x) (display x f)) converters)
|
|
(format f " P_Provide(Intern(\"~a:~a\"));~%" widget-set
|
|
(feature-name (car args)))
|
|
(format f "}~%")
|