44 lines
1.4 KiB
Scheme
44 lines
1.4 KiB
Scheme
(define (sexpr-read port)
|
|
(define (help port)
|
|
(let ((char (read-char port)))
|
|
(cond
|
|
((or (eof-object? char) (eq? char #\) )) '())
|
|
((eq? char #\( ) (cons (help port) (help port)))
|
|
((char-whitespace? char) (help port))
|
|
((eq? char #\"") (cons (quote-read port) (help port)))
|
|
(#t (unread-char char port) (cons (string-read port) (help port))))))
|
|
; This is needed because the function conses all parsed sexprs onto something,
|
|
; so the top expression is one level too deep.
|
|
(car (help port)))
|
|
|
|
(define (quote-read port)
|
|
(define (help port)
|
|
(let ((char (read-char port)))
|
|
(if
|
|
(or (eof-object? char) (eq? char #\""))
|
|
'()
|
|
(cons char (help port)))))
|
|
(list->string (help port)))
|
|
|
|
(define (string-read port)
|
|
(define (help port)
|
|
(let ((char (read-char port)))
|
|
(cond
|
|
((or (eof-object? char) (char-whitespace? char)) '())
|
|
((eq? char #\) ) (unread-char char port) '())
|
|
(#t (cons char (help port))))))
|
|
(list->string (help port)))
|
|
|
|
(define (format-sexpr expr)
|
|
(define (help expr pad)
|
|
(if
|
|
(list? expr)
|
|
(begin
|
|
(format #t "~a(~%" (make-string pad #\tab))
|
|
(for-each (lambda (x) (help x (1+ pad))) expr)
|
|
(format #t "~a)~%" (make-string pad #\tab)))
|
|
(format #t "~a~a~%" (make-string pad #\tab) expr)))
|
|
(help expr 0))
|
|
|
|
(format-sexpr (sexpr-read
|
|
(open-input-string "((data \"quoted data\" 123 4.5) (data (!@# (4.5) \"(more\" \"data)\")))")))
|