pull/10/head
Matthew Butterick 8 years ago
parent 50eb4964cd
commit 6221ca5959

@ -3,8 +3,10 @@
(matching-identifiers-out #rx"^b-" (all-defined-out))) (matching-identifiers-out #rx"^b-" (all-defined-out)))
(define-macro (b-module-begin (b-program LINE ...)) (define-macro (b-module-begin (b-program LINE ...))
(with-pattern ([(LINE-NUM ...) (with-pattern
(filter-stx-prop 'b-line-number (stx-flatten #'(LINE ...)))] ([(LINE-NUM ...)
(filter-stx-prop 'b-line-number
(stx-flatten #'(LINE ...)))]
[(LINE-ID ...) (prefix-ids "line-" #'(LINE-NUM ...))]) [(LINE-ID ...) (prefix-ids "line-" #'(LINE-NUM ...))])
#'(#%module-begin #'(#%module-begin
LINE ... LINE ...
@ -13,7 +15,8 @@
(run line-table)))) (run line-table))))
(define-macro (b-line LINE-NUMBER STATEMENT ...) (define-macro (b-line LINE-NUMBER STATEMENT ...)
(with-pattern ([LINE-NUMBER-ID (prefix-id "line-" #'LINE-NUMBER (with-pattern
([LINE-NUMBER-ID (prefix-id "line-" #'LINE-NUMBER
#:source #'LINE-NUMBER)] #:source #'LINE-NUMBER)]
[ORIG-LOC caller-stx]) [ORIG-LOC caller-stx])
(syntax/loc caller-stx (syntax/loc caller-stx
@ -31,24 +34,28 @@
(struct $program-end-signal ()) (struct $program-end-signal ())
(define (b-end) (raise ($program-end-signal))) (define (b-end) (raise ($program-end-signal)))
(struct $change-line-signal (num)) (struct $change-line-signal (val))
(define (b-goto expr) (raise ($change-line-signal expr))) (define (b-goto expr) (raise ($change-line-signal expr)))
(define-exn line-not-found exn:fail) (define-exn line-not-found exn:fail)
(define (run line-table) (define (run line-table)
(define line-vec (list->vector (sort (hash-keys line-table) <))) (define line-vec
(list->vector (sort (hash-keys line-table) <)))
(with-handlers ([$program-end-signal? void]) (with-handlers ([$program-end-signal? void])
(for/fold ([line-idx 0]) (for/fold ([line-idx 0])
([i (in-naturals)]) ([i (in-naturals)])
(unless (< line-idx (vector-length line-vec)) (b-end)) (unless (< line-idx (vector-length line-vec)) (b-end))
(define line-num (vector-ref line-vec line-idx)) (define line-num (vector-ref line-vec line-idx))
(define line-proc (hash-ref line-table line-num)) (define line-proc (hash-ref line-table line-num))
(with-handlers ([$change-line-signal? (with-handlers
([$change-line-signal?
(λ (cls) (λ (cls)
(define clsv ($change-line-signal-val cls))
(or (or
(and (exact-positive-integer? ($change-line-signal-num cls)) (and (exact-positive-integer? clsv)
(vector-member ($change-line-signal-num cls) line-vec)) (vector-member clsv line-vec))
(raise-line-not-found (line-proc #:srcloc? #t))))]) (raise-line-not-found
(line-proc #:srcloc? #t))))])
(line-proc) (line-proc)
(add1 line-idx))))) (add1 line-idx)))))

@ -0,0 +1,21 @@
#lang br
(require brag/support racket/contract)
(define basic-lexer
(lexer-srcloc
[(eof) eof]
[whitespace (token lexeme #:skip? #t)]
[(from/to "rem" "\n") (token 'REM lexeme)]
[(:or "print" "goto" "end" "+" ":") lexeme]
[(:+ numeric) (token 'INTEGER (string->number lexeme))]
[(:or (:seq (:+ numeric) ".")
(:seq (:* numeric) "." (:+ numeric)))
(token 'DECIMAL (string->number lexeme))]
[(from/to "\"" "\"")
(token 'STRING (trim-ends "\"" lexeme "\""))]))
(provide
(contract-out
[basic-lexer
(input-port? . -> .
(or/c eof-object? string? srcloc-token?))]))

@ -1,15 +1,16 @@
#lang br/quicklang #lang br/quicklang
(require "parser.rkt" "tokenizer.rkt" brag/support) (require "parser.rkt" "tokenizer.rkt")
(module+ reader (provide read-syntax)) (module+ reader (provide read-syntax))
(define (read-syntax path port) (define (read-syntax path port)
(define-values (line col pos) (port-next-location port)) (define-values (pline pcol ppos) (port-next-location port))
(define port+newline (input-port-append #f port (open-input-string "\n"))) (define port+newline
(input-port-append #f port (open-input-string "\n")))
(port-count-lines! port+newline) (port-count-lines! port+newline)
(set-port-next-location! port+newline line col pos) (set-port-next-location! port+newline pline pcol ppos)
(with-handlers ([exn:fail:parsing? (λ (exn) (displayln "Sorry!") (raise exn))]) (define parse-tree
(define parse-tree (parse path (make-tokenizer port+newline))) (parse path (make-tokenizer port+newline path)))
(strip-bindings (strip-bindings
#`(module basic-mod basic-demo/expander #`(module basic-mod basic-demo/expander
#,parse-tree)))) #,parse-tree)))

@ -1,8 +1,8 @@
#lang basic-demo #lang basic-demo
30 rem print "statement ignored" 30 rem print "ignored"
40 end
50 print "never gets here" 50 print "never gets here"
60 print "two" : print 1.2 + 1.8 40 end
60 print "three" : print 2 + 2
70 goto 11 + 10.5 + 8.5 70 goto 11 + 10.5 + 8.5
10 print "one" 10 print "one"
20 print : goto 60 : end 20 print : goto 60 : end

@ -1,20 +1,14 @@
#lang br #lang br
(require brag/support) (require "lexer.rkt" brag/support racket/contract)
(provide (all-defined-out))
(define basic-lexer (define (make-tokenizer ip [path #f])
(lexer-srcloc
[(eof) eof]
[whitespace (token lexeme #:skip? #t)]
[(from/to "rem" "\n") (token 'REM lexeme)]
[(:or "print" "goto" "end" "+" ":") lexeme]
[(:+ numeric) (token 'INTEGER (string->number lexeme))]
[(:or (:seq (:+ numeric) ".")
(:seq (:* numeric) "." (:+ numeric)))
(token 'DECIMAL (string->number lexeme))]
[(from/to "\"" "\"") (token 'STRING (trim-ends "\"" lexeme "\""))]))
(define (make-tokenizer ip)
(port-count-lines! ip) (port-count-lines! ip)
(file-path path)
(define (next-token) (basic-lexer ip)) (define (next-token) (basic-lexer ip))
next-token) next-token)
(provide
(contract-out
[make-tokenizer
((input-port?) (path?) . ->* .
(-> (or/c eof-object? string? srcloc-token?)))]))
Loading…
Cancel
Save