#lang scheme ;; Not well tested: ;; Non-character input data (i.e. specials) ;; The R5RS part of numbers ;; ;; Not supported ;; Honu (#hx, #sx, #honu) ;; #reader (require syntax-color/scheme-lexer) (define (char kind) (case kind ((white-space) #\space) ((symbol) #\i) ((constant) #\c) ((comment) #\;) ((sexp-comment) #\;) ((string) #\s) ((parenthesis) #\p) ((other) #\o) ((no-color) #\n) ((error) #\x) (else (error 'char "Given ~a" kind)))) (define (chunks x) (cond ((null? x) 0) ((null? (cdr x)) 1) ((char=? (car x) (cadr x)) (chunks (cdr x))) (else (add1 (chunks (cdr x)))))) (define (lex f p) (define-values (lexeme kind paren? start end) (f p)) (cond ((eq? 'eof kind) null) (else (cons (make-string (- end start) (char kind)) (lex f p))))) (define (test input expected [e-n (chunks (string->list expected))]) (let* ([p (input->port input)] (l (lex scheme-lexer p)) (s (apply string-append l))) (close-input-port p) (unless (string=? s expected) (printf "input : ~s\n" input) (printf "output : ~s\n" s) (printf "expected: ~s\n\n" expected)) (let ((a-n (length l))) (unless (= e-n a-n) (printf "input : ~a\n" input) (printf "expected: ~a tokens\n" e-n) (printf "got : ~a tokens\n\n" a-n))))) (define (input->port input) (let-values ([(in out) (make-pipe-with-specials)]) (thread (λ () (let loop ([input input]) (cond [(list? input) (for-each loop input)] [(string? input) (display input out)] [else (write-special input out)])) (close-output-port out))) in)) ;; Delimiters (test " " " ") (test "\t" " ") (test "\n" " ") (test "\"" "x") (test "," "o") (test "'" "c") (test "`" "c") (test ";" ";") (test "(" "p") (test ")" "p") (test "[" "p") (test "]" "p") (test "{" "p") (test "}" "p") ;; # (test "#fq" "xxx") (test "#Fq" "xxx") (test "#tq" "xxx") (test "#Tq" "xxx") (test "#true" "ccccc") (test "#false" "cccccc") (test "#f q" "cc i") (test "#F q" "cc i") (test "#t q" "cc i") (test "#T q" "cc i") (test "#true q" "ccccc i") (test "#false q" "cccccc i") (test "#f(q" "ccpi") (test "#T(q" "ccpi") (test "#true{q" "cccccpi") (test "#012423(a" "ppppppppi") (test "#1{a" "pppi") (test "#1[a" "pppi") (test "#(a" "ppi") (test "#{a" "ppi") (test "#[a" "ppi") (test "#&a" "cci") (test "#'a" "cci") (test "#`a" "cci") (test "#,a" "ooi") (test "#,@a" "oooi") (test "#CsA" "oooi") (test "#cIA" "oooi") (test "#hash(a" "ppppppi") (test "#hasheq(a" "ppppppppi") (test "#hash[a" "ppppppi") (test "#hasheq[a" "ppppppppi") (test "#hash{a" "ppppppi") (test "#hasheq{a" "ppppppppi") (test "#135#a" "oooooi") (test "#453=a" "oooooi") (test #<