diff --git a/rash-lang.rkt b/rash-lang.rkt new file mode 100644 index 0000000..e992d3b --- /dev/null +++ b/rash-lang.rkt @@ -0,0 +1,51 @@ +#lang racket/base + +(require syntax/readerr + (prefix-in rash: "rash.rkt")) + +(define (rash-read in) + (syntax->datum (rash-read-syntax #f in))) + +(define (rash-read-syntax src in) + (define-values (start-line start-col start-pos) (port-next-location in)) + (define (list->rash-syntax l span) + (datum->syntax #f + (cons 'start l) + (vector src start-line start-col start-pos span))) + + (let loop ([words '()] + [delta 0]) + (define-values (line col pos) (port-next-location in)) + (cond + [(regexp-try-match #px"^[[:alnum:]]+" in) => + (λ (r) + (define m (bytes->string/utf-8 (car r))) + (define len (string-length m)) + (define word (datum->syntax #f m (vector src line col pos len))) + (loop (cons word words) len))] + [(regexp-try-match #px"^\n" in) => (λ (m) (list->rash-syntax + (reverse words) + delta))] + [(regexp-try-match #px"^[ \t]+" in) => (λ (r) + (define m + (bytes->string/utf-8 (car r))) + (displayln m) + (loop words (string-length m)))] + [(eof-object? (peek-char in)) (list->rash-syntax (reverse words) delta)] + [else (raise-read-error + (string-append "Unknown character " (read-char in)) + src line col pos 1)]))) + +(module+ test + (require rackunit) + + (define (2port str) + (open-input-string str)) + + (test-case + "Read alphanumeric words with EOF" + (check equal? '(start "echo" "hello1") (rash-read (2port "echo hello1")))) + + (test-case + "Read string with newline" + (check equal? '(start "echo") (rash-read (2port "echo\n")))))