;;; -*-scheme-*- ;;; Mes --- Maxwell Equations of Software ;;; Copyright © 2016,2017 Jan Nieuwenhuizen ;;; ;;; This file is part of Mes. ;;; ;;; Mes is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; Mes is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with Mes. If not, see . ;;; Commentary: ;;; Code: (mes-use-module (mes scm)) ;;(mes-use-module (mes srfi srfi-1)) (define (srfi-1:member x lst eq) (if (null? lst) #f (if (eq x (car lst)) lst (srfi-1:member x (cdr lst) eq)))) (define (next-xassq x a) (and=> (srfi-1:member x a (lambda (x e) (eq? x (cdr e)))) (lambda (a) (xassq x (cdr a))))) (define (next-xassq2 x a) (and=> (srfi-1:member x a (lambda (x e) (eq? x (cdr e)))) (lambda (a) (and=> (srfi-1:member x (cdr a) (lambda (x e) (eq? x (cdr e)))) (lambda (a) (xassq x (cdr a))))))) (define (display x . rest) (let* ((port (if (null? rest) (current-output-port) (car rest))) (write? (and (pair? rest) (pair? (cdr rest)) (cadr rest)))) (define-macro (cut f slot n1) `(lambda (slot) (,f slot ,n1))) (define-macro (cut2 f slot n1 n2) `(lambda (slot) (,f slot ,n1 ,n2))) (define (display-char x port write?) (cond ((and write? (or (eq? x #\") (eq? x #\\))) (write-char #\\ port) (write-char x port)) ((and write? (eq? x #\newline)) (write-char #\\ port) (write-char #\n port)) (#t (write-char x port)))) (define (d x cont? sep) (for-each (cut write-char <> port) (string->list sep)) (cond ((char? x) (if (not write?) (write-char x port) (let ((name (and=> (assq x '((#\*eof* . *eof*) (#\nul . nul) (#\alarm . alarm) (#\backspace . backspace) (#\tab . tab) (#\newline . newline) (#\vtab . vtab) (#\page . page) (#\return . return) (#\space . space))) cdr))) (write-char #\# port) (write-char #\\ port) (if name (display name port) (write-char x port))))) ((closure? x) (display "# (next-xassq2 x (current-module)) car))) (display name port)) (display " " port) (display (cadr (core:cdr x)) port) (display ">" port)) ((continuation? x) (display "#" port)) ((macro? x) (display "#" port)) ((number? x) (display (number->string x) port)) ((pair? x) (if (not cont?) (write-char #\( port)) (cond ((eq? (car x) '*circular*) (display "(*circ* . #-1#)" port)) ((eq? (car x) '*closure*) (display "(*closure* . #-1#)" port)) (#t (display (car x) port write?) (if (pair? (cdr x)) (d (cdr x) #t " ") (if (and (cdr x) (not (null? (cdr x)))) (begin (display " . " port) (display (cdr x) port write?)))) (if (not cont?) (write-char #\) port))))) ((or (keyword? x) (special? x) (string? x) (symbol? x)) (if (and (string? x) write?) (write-char #\" port)) (if (keyword? x) (display "#:" port)) (for-each (cut2 display-char <> port write?) (string->list x)) (if (and (string? x) write?) (write-char #\" port))) ((vector? x) (display "#(" port) (for-each (lambda (i) (let ((x (vector-ref x i))) (if (vector? x) (begin (display (if (= i 0) "" " ") port) (display "#(...)" port)) (d x #f (if (= i 0) "" " "))))) (iota (vector-length x))) (display ")" port)) ((function? x) (display "#" port)) ((broken-heart? x) (display "<3" port)) (#t (display "TODO type=") (display (cell:type-name x)) (newline))) *unspecified*) (d x #f ""))) (define (write-char x . rest) (apply write-byte (cons (char->integer x) rest))) (define (write x . rest) (let ((port (if (null? rest) (current-output-port) (car rest)))) (display x port #t))) (define (newline . rest) (apply display (cons "\n" rest))) (define (with-output-to-string thunk) (define save-write-byte write-byte) (let ((stdout '())) (set! write-byte (lambda (x . rest) (let ((out? (or (null? rest) (eq? (car rest) (current-output-port))))) (if (not out?) (apply save-write-byte (cons x rest)) (begin (set! stdout (append stdout (list (integer->char x)))) x))))) (thunk) (let ((r (apply string stdout))) (set! write-byte save-write-byte) r))) (define (simple-format destination format . rest) (let ((port (if (boolean? destination) (current-output-port) destination)) (lst (string->list format))) (define (simple-format lst args) (if (pair? lst) (let ((c (car lst))) (if (not (eq? c #\~)) (begin (write-char (car lst) port) (simple-format (cdr lst) args)) (let ((c (cadr lst))) (case c ((#\a) (display (car args) port)) ((#\s) (write (car args) port))) (simple-format (cddr lst) (cdr args))))))) (if destination (simple-format lst rest) (with-output-to-string (lambda () (simple-format lst rest)))))) (define format simple-format)