guile-pstk

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 7bbddff92c5331f4a47c95350e592eb1a3bb5d15
parent 177f635f9e93fa11b6439f969ed38049b437952f
Author: Yuval Langer <yuval.langer@gmail.com>
Date:   Sat, 15 Jun 2024 02:05:39 +0300

Use procedure definitions instead of named lambdas.

Diffstat:
Mpstk.scm | 655++++++++++++++++++++++++++++++++++++++-----------------------------------------
1 file changed, 312 insertions(+), 343 deletions(-)

diff --git a/pstk.scm b/pstk.scm @@ -234,16 +234,15 @@ enabled (set! enabled (car args)))))) -(define ->string - (lambda (x) - (cond ((string? x) x) - ((symbol? x) (symbol->string x)) - ((char? x) (string x)) - ((number? x) (number->string x)) - (else - (let ((out (open-output-string))) - (display x out) - (get-output-string out)))))) +(define (->string x) + (cond ((string? x) x) + ((symbol? x) (symbol->string x)) + ((char? x) (string x)) + ((number? x) (number->string x)) + (else + (let ((out (open-output-string))) + (display x out) + (get-output-string out))))) ;;; Start weird letrec definitions: @@ -385,27 +384,24 @@ (define flush-output-port force-output) -(define flush-wish - (lambda () - (flush-output-port wish-input))) - -(define option? - (lambda (x) - (or (and *use-keywords?* - (keyword? x)) - (and (symbol? x) - (let* ((s (symbol->string x)) - (n (string-length s))) - (char=? #\: (string-ref s (- n 1)))))))) - -(define make-option-string - (lambda (x) - (if (and *use-keywords?* - (keyword? x)) - (string-append " -" (keyword->string x)) - (let ((s (symbol->string x))) - (string-append " -" - (substring s 0 (- (string-length s) 1))))))) +(define (flush-wish) + (flush-output-port wish-input)) + +(define (option? x) + (or (and *use-keywords?* + (keyword? x)) + (and (symbol? x) + (let* ((s (symbol->string x)) + (n (string-length s))) + (char=? #\: (string-ref s (- n 1))))))) + +(define (make-option-string x) + (if (and *use-keywords?* + (keyword? x)) + (string-append " -" (keyword->string x)) + (let ((s (symbol->string x))) + (string-append " -" + (substring s 0 (- (string-length s) 1)))))) (define (improper-list->string a first) (cond ((pair? a) @@ -431,19 +427,18 @@ (else "#<other>"))) (define (string-translate s map) - (letrec - ((s-prepend (lambda (s1 s2) - (cond ((null? s1) s2) - (else (s-prepend (cdr s1) (cons (car s1) s2)))))) - (s-xlate (lambda (s r) - (cond ((null? s) (reverse r)) - (else (let ((n (assv (car s) map))) - (cond (n (s-xlate (cdr s) - (s-prepend (string->list (cdr n)) r))) - (else (s-xlate (cdr s) - (cons (car s) r)))))))))) - (list->string - (s-xlate (string->list s) '())))) + (define (s-prepend s1 s2) + (cond ((null? s1) s2) + (else (s-prepend (cdr s1) (cons (car s1) s2))))) + (define (s-xlate s r) + (cond ((null? s) (reverse r)) + (else (let ((n (assv (car s) map))) + (cond (n (s-xlate (cdr s) + (s-prepend (string->list (cdr n)) r))) + (else (s-xlate (cdr s) + (cons (car s) r)))))))) + (list->string + (s-xlate (string->list s) '()))) (define (string-trim-left str) (cond ((string=? str "") "") @@ -574,306 +569,280 @@ (cons result tk-ids+widgets))) result)) -(define scheme-arg->tk-arg - (lambda (x) - (cond ((eq? x #f) " 0") - ((eq? x #t) " 1") - ((eq? x '()) " {}") - ((option? x) (make-option-string x)) - ((widget? x) (string-append " " (x 'get-id))) - ((and (pair? x) (procedure? (car x))) - (let* ((lambda-term (car x)) - (rest (cdr x)) - (l (memq lambda-term - inverse-commands-invoked-by-tk)) - (keystr (if l (form->string (cadr l)) - (symbol->string (gen-symbol))))) - (if (not l) - (let ((key (string->symbol keystr))) - (set! inverse-commands-invoked-by-tk - (cons lambda-term - (cons key - inverse-commands-invoked-by-tk))) - (set! commands-invoked-by-tk - (cons key - (cons lambda-term - commands-invoked-by-tk))))) - (string-append " {callToScm " - keystr - (scheme-arglist->tk-argstring rest) - "}"))) - ((procedure? x) - (scheme-arglist->tk-argstring `((,x)))) - ((list? x) - (cond ((eq? (car x) '+) - (let ((result (string-trim-left - (scheme-arglist->tk-argstring - (cdr x))))) - (cond ((string=? result "") " +") - ((string=? "{" (substring result 0 1)) - (string-append - " {+ " - (substring result 1 - (string-length result)))) - (else (string-append " +" result))))) - ((and (= (length x) 3) - (equal? (car x) (string->symbol "@")) - (number? (cadr x)) - (number? (caddr x))) - (string-append - "@" - (number->string (cadr x)) - "," - (number->string (caddr x)))) - (else - (string-append - " {" - (string-trim-left - (scheme-arglist->tk-argstring x)) - "}")))) - ((pair? x) - (string-append - " " - (form->string (car x)) - "." - (form->string (cdr x)))) - ((string? x) - (if (string->number x) - (string-append " " x) - (string-append - " \"" - (string-translate x - '((#\\ . "\\\\") (#\" . "\\\"") - (#\[ . "\\u005b") (#\] . "\\]") - (#\$ . "\\u0024") - (#\{ . "\\{") (#\} . "\\}"))) - "\""))) - (else (string-append " " (form->string x)))))) - -(define scheme-arglist->tk-argstring - (lambda (args) - (apply string-append - (map scheme-arg->tk-arg - args)))) - -(define make-wish-func - (lambda (tkname) - (let ((name (form->string tkname))) - (lambda args - (eval-wish +(define (scheme-arg->tk-arg x) + (cond ((eq? x #f) " 0") + ((eq? x #t) " 1") + ((eq? x '()) " {}") + ((option? x) (make-option-string x)) + ((widget? x) (string-append " " (x 'get-id))) + ((and (pair? x) (procedure? (car x))) + (let* ((lambda-term (car x)) + (rest (cdr x)) + (l (memq lambda-term + inverse-commands-invoked-by-tk)) + (keystr (if l (form->string (cadr l)) + (symbol->string (gen-symbol))))) + (if (not l) + (let ((key (string->symbol keystr))) + (set! inverse-commands-invoked-by-tk + (cons lambda-term + (cons key + inverse-commands-invoked-by-tk))) + (set! commands-invoked-by-tk + (cons key + (cons lambda-term + commands-invoked-by-tk))))) + (string-append " {callToScm " + keystr + (scheme-arglist->tk-argstring rest) + "}"))) + ((procedure? x) + (scheme-arglist->tk-argstring `((,x)))) + ((list? x) + (cond ((eq? (car x) '+) + (let ((result (string-trim-left + (scheme-arglist->tk-argstring + (cdr x))))) + (cond ((string=? result "") " +") + ((string=? "{" (substring result 0 1)) + (string-append + " {+ " + (substring result 1 + (string-length result)))) + (else (string-append " +" result))))) + ((and (= (length x) 3) + (equal? (car x) (string->symbol "@")) + (number? (cadr x)) + (number? (caddr x))) + (string-append + "@" + (number->string (cadr x)) + "," + (number->string (caddr x)))) + (else + (string-append + " {" + (string-trim-left + (scheme-arglist->tk-argstring x)) + "}")))) + ((pair? x) (string-append - name - (scheme-arglist->tk-argstring args))))))) - -(define read-wish - (lambda () - (let ((term (read wish-output))) - (cond (*wish-debug-output* - (display "wish->scheme: ") - (write term) - (newline))) - term))) - -(define wish - (lambda arguments - (for-each - (lambda (argument) - (cond (*wish-debug-input* - (display "scheme->wish: ") - (display argument) - (newline))) - (display argument wish-input) - (newline wish-input) - (flush-wish)) - arguments))) - -(define start-wish - (lambda () - (let ((result (run-program *wish-program*))) - (set! wish-input (cadr result)) - (set! wish-output (car result))))) - -(define read-line - (lambda (in) - (letrec - ((collect-chars - (lambda (c s) - (cond ((or (eof-object? c) (char=? c #\newline)) - (apply string (reverse s))) - (else (collect-chars (read-char in) (cons c s)))))) - (first-char - (read-char in))) - (cond ((eof-object? first-char) first-char) - (else (collect-chars first-char '())))))) - -(define eval-wish - (lambda (cmd) - (wish (string-append - "evalCmdFromScm \"" - (string-translate cmd - '((#\\ . "\\\\") (#\" . "\\\""))) - "\"")) - (let again ((result (read-wish))) - (cond ((not (pair? result)) - (report-error (string-append - "An error occurred inside Tcl/Tk" nl - " --> " (form->string result) - " " (read-line wish-output)))) - ((eq? (car result) 'return) - (cadr result)) - ((eq? (car result) 'call) - (apply call-by-key (cdr result)) - (again (read-wish))) - ((eq? (car result) 'error) - (report-error (string-append - "An error occurred inside Tcl/Tk" nl - " " cmd nl - " --> " (cadr result)))) - (else (report-error result)))))) - -(define id->widget - (lambda (id) - (get-property - (string->symbol (form->string id)) - tk-ids+widgets - (lambda () - (if (tcl-true? (tk/winfo 'exists id)) - (make-widget-by-id - (tk/winfo 'class id) - (form->string id)) - #f))))) - -(define var - (lambda (varname) - (set-var! varname "") - (string-append - "::scmVar(" - (form->string varname) - ")"))) - -(define get-var - (lambda (varname) - (eval-wish - (string-append - "set ::scmVar(" - (form->string varname) - ")")))) - -(define set-var! - (lambda (varname value) - (eval-wish - (string-append - "set ::scmVar(" - (form->string varname) - ") {" - (form->string value) - "}")))) - -(define start - (lambda () - (start-wish) - (wish tk-init-string) - (set! tk-ids+widgets '()) - (set! tk-widgets '()) - (set! in-callback #f) - (set! tk (make-widget-by-id 'toplevel "." 'class: 'Wish)) - (set! commands-invoked-by-tk '()) - (set! inverse-commands-invoked-by-tk '()) - (tk/wm 'protocol tk 'WM_DELETE_WINDOW end-tk))) - -(define end-tk - (lambda () - (set! tk-is-running #f) - (wish "after 200 exit"))) - -(define ispatch-event - (lambda () - (let ((tk-statement (read-wish))) - (if (and (list? tk-statement) - (eq? (car tk-statement) 'call)) - (apply call-by-key (cdr tk-statement)))))) - -(define loop - (lambda () - (cond ((not tk-is-running) - (if wish-output - (tk/wm 'protocol tk 'WM_DELETE_WINDOW '()))) - (else (dispatch-event) - (loop))))) - -(define event-loop - (lambda () - (set! tk-is-running #t) - (loop))) - -(define map-ttk-widgets - (lambda (x) - (cond ((eq? x 'all) - (set! ttk-widget-map '("button" "checkbutton" "radiobutton" - "menubutton" "label" "entry" "frame" - "labelframe" "scrollbar" "notebook" - "progressbar" "combobox" "separator" - "scale" "sizegrip" "treeview"))) - ((eq? x 'none) - (set! ttk-widget-map '())) - ((pair? x) (set! ttk-widget-map - (map form->string x))) - (else (report-error - (string-append - "Argument to TTK-MAP-WIDGETS must be " - "ALL, NONE or a list of widget types.")))))) - -(define string-split - (lambda (c s) - (letrec - ((split (lambda (i k tmp res) - (cond ((= i k) - (if (null? tmp) res (cons tmp res))) - ((char=? (string-ref s i) c) - (split (+ i 1) k "" (cons tmp res))) - (else (split (+ i 1) k - (string-append tmp - (string (string-ref s i))) - res)))))) - (reverse (split 0 (string-length s) "" '()))))) - -(define ttk-available-themes - (lambda () - (string-split #\space (eval-wish "ttk::style theme names")))) - -(define do-wait-for-window - (lambda (w) - (dispatch-event) - (cond ((equal? (tk/winfo 'exists w) "0") '()) - (else (do-wait-for-window w))))) - -(define wait-for-window - (lambda (w) - (let ((outer-allow callback-mutex)) - (set! callback-mutex #t) - (do-wait-for-window w) - (set! callback-mutex outer-allow)))) - -(define wait-until-visible - (lambda (w) - (tk/wait 'visibility w))) - -(define lock! - (lambda () - (set! callback-mutex - (cons callback-mutex #t)))) - -(define unlock! - (lambda () - (if (pair? callback-mutex) - (set! callback-mutex - (cdr callback-mutex))))) - -(define with-lock - (lambda (thunk) - (lock!) - (thunk) - (unlock!))) + " " + (form->string (car x)) + "." + (form->string (cdr x)))) + ((string? x) + (if (string->number x) + (string-append " " x) + (string-append + " \"" + (string-translate x + '((#\\ . "\\\\") (#\" . "\\\"") + (#\[ . "\\u005b") (#\] . "\\]") + (#\$ . "\\u0024") + (#\{ . "\\{") (#\} . "\\}"))) + "\""))) + (else (string-append " " (form->string x))))) + +(define (scheme-arglist->tk-argstring args) + (apply string-append + (map scheme-arg->tk-arg + args))) + +(define (make-wish-func tkname) + (let ((name (form->string tkname))) + (lambda args + (eval-wish + (string-append + name + (scheme-arglist->tk-argstring args)))))) + +(define (read-wish) + (let ((term (read wish-output))) + (cond (*wish-debug-output* + (display "wish->scheme: ") + (write term) + (newline))) + term)) + +(define (wish arguments) + (for-each + (lambda (argument) + (cond (*wish-debug-input* + (display "scheme->wish: ") + (display argument) + (newline))) + (display argument wish-input) + (newline wish-input) + (flush-wish)) + arguments)) + +(define (start-wish) + (let ((result (run-program *wish-program*))) + (set! wish-input (cadr result)) + (set! wish-output (car result)))) + +(define (read-line in) + (letrec + ((collect-chars + (lambda (c s) + (cond ((or (eof-object? c) (char=? c #\newline)) + (apply string (reverse s))) + (else (collect-chars (read-char in) (cons c s)))))) + (first-char + (read-char in))) + (cond ((eof-object? first-char) first-char) + (else (collect-chars first-char '()))))) + +(define (eval-wish cmd) + (wish (string-append + "evalCmdFromScm \"" + (string-translate cmd + '((#\\ . "\\\\") (#\" . "\\\""))) + "\"")) + (let again ((result (read-wish))) + (cond ((not (pair? result)) + (report-error (string-append + "An error occurred inside Tcl/Tk" nl + " --> " (form->string result) + " " (read-line wish-output)))) + ((eq? (car result) 'return) + (cadr result)) + ((eq? (car result) 'call) + (apply call-by-key (cdr result)) + (again (read-wish))) + ((eq? (car result) 'error) + (report-error (string-append + "An error occurred inside Tcl/Tk" nl + " " cmd nl + " --> " (cadr result)))) + (else (report-error result))))) + +(define (id->widget id) + (get-property + (string->symbol (form->string id)) + tk-ids+widgets + (lambda () + (if (tcl-true? (tk/winfo 'exists id)) + (make-widget-by-id + (tk/winfo 'class id) + (form->string id)) + #f)))) + +(define (var varname) + (set-var! varname "") + (string-append + "::scmVar(" + (form->string varname) + ")")) + +(define (get-var varname) + (eval-wish + (string-append + "set ::scmVar(" + (form->string varname) + ")"))) + +(define (set-var! varname value) + (eval-wish + (string-append + "set ::scmVar(" + (form->string varname) + ") {" + (form->string value) + "}"))) + +(define (start) + (start-wish) + (wish tk-init-string) + (set! tk-ids+widgets '()) + (set! tk-widgets '()) + (set! in-callback #f) + (set! tk (make-widget-by-id 'toplevel "." 'class: 'Wish)) + (set! commands-invoked-by-tk '()) + (set! inverse-commands-invoked-by-tk '()) + (tk/wm 'protocol tk 'WM_DELETE_WINDOW end-tk)) + +(define (end-tk) + (set! tk-is-running #f) + (wish "after 200 exit")) + +(define (ispatch-event) + (let ((tk-statement (read-wish))) + (if (and (list? tk-statement) + (eq? (car tk-statement) 'call)) + (apply call-by-key (cdr tk-statement))))) + +(define (loop) + (cond ((not tk-is-running) + (if wish-output + (tk/wm 'protocol tk 'WM_DELETE_WINDOW '()))) + (else (dispatch-event) + (loop)))) + +(define (event-loop) + (set! tk-is-running #t) + (loop)) + +(define (map-ttk-widgets x) + (cond ((eq? x 'all) + (set! ttk-widget-map '("button" "checkbutton" "radiobutton" + "menubutton" "label" "entry" "frame" + "labelframe" "scrollbar" "notebook" + "progressbar" "combobox" "separator" + "scale" "sizegrip" "treeview"))) + ((eq? x 'none) + (set! ttk-widget-map '())) + ((pair? x) (set! ttk-widget-map + (map form->string x))) + (else (report-error + (string-append + "Argument to TTK-MAP-WIDGETS must be " + "ALL, NONE or a list of widget types."))))) + +(define (string-split c s) + (letrec + ((split (lambda (i k tmp res) + (cond ((= i k) + (if (null? tmp) res (cons tmp res))) + ((char=? (string-ref s i) c) + (split (+ i 1) k "" (cons tmp res))) + (else (split (+ i 1) k + (string-append tmp + (string (string-ref s i))) + res)))))) + (reverse (split 0 (string-length s) "" '())))) + +(define (ttk-available-themes) + (string-split #\space (eval-wish "ttk::style theme names"))) + +(define (do-wait-for-window w) + (dispatch-event) + (cond ((equal? (tk/winfo 'exists w) "0") '()) + (else (do-wait-for-window w)))) + +(define (wait-for-window w) + (let ((outer-allow callback-mutex)) + (set! callback-mutex #t) + (do-wait-for-window w) + (set! callback-mutex outer-allow))) + +(define (wait-until-visible w) + (tk/wait 'visibility w)) + +(define (lock!) + (set! callback-mutex + (cons callback-mutex #t))) + +(define (unlock!) + (if (pair? callback-mutex) + (set! callback-mutex + (cdr callback-mutex)))) + +(define (with-lock thunk) + (lock!) + (thunk) + (unlock!)) ;;; End weird letrec definitions.