(use-syntax (ice-9 syncase)) (define (operator? x) (and (member x '(#\+ #\- #\/ #\*)) #t)) (define (separator? x) (and (member x '(#\space #\tab #\newline)) #t)) (define (digit? x) (and (<= 48 (char->integer x)) (>= 57 (char->integer x)))) (define-syntax ++ (syntax-rules () ((_ i) (+ i 1)))) (define-syntax while (syntax-rules () ((while a expr ...) (let loop () (if a (begin expr ... (loop))))))) (define (check-integer string) (let loop ((i 0)) (cond ((= i (string-length string))) ((or (and (= i 0) (> (string-length string) 1) (operator? (string-ref string i))) (digit? (string-ref string i))) (loop (++ i))) (else #f)))) (define (scan-integer string) (cond ((check-integer string) string) (else #f))) (define (scan-many-integers string) (let loop ((i 0) (start 0) (res '())) (cond ((= i (string-length string)) (make-numbers (reverse (cons (substring string start i) res)))) ((separator? (string-ref string i)) (loop (++ i) (++ i) (if (not (= i start)) (cons (substring string start i) res) res))) ((or (and (= i start) (operator? (string-ref string i))) (digit? (string-ref string i))) (loop (++ i) start res)) (else #f)))) (define (empty? xs) (member (car xs) '("+" "-" "/" "*"))) (define (make-numbers xs) (cond ((null? xs) '()) ((empty? xs) #f) (else (if (not (equal? (car xs) "")) (cons (string->number (car xs)) (make-numbers (cdr xs))) (make-numbers (cdr xs))))))