Skip to content

Commit

Permalink
implement where syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Dec 31, 2016
1 parent e54a275 commit 0c7a2fd
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 150 deletions.
2 changes: 2 additions & 0 deletions src/ast.scm
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
(string "[ " (deparse (cadr e)) " for " (deparse-arglist (cddr e) ", ") " ]"))
((generator)
(string "(" (deparse (cadr e)) " for " (deparse-arglist (cddr e) ", ") ")"))
((where)
(string (deparse (cadr e)) " where " (deparse (caddr e))))
(else
(string e))))))

Expand Down
69 changes: 48 additions & 21 deletions src/julia-parser.scm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
(define prec-rational (add-dots '(//)))
(define prec-power (add-dots '(^ ↑ ↓ ⇵ ⟰ ⟱ ⤈ ⤉ ⤊ ⤋ ⤒ ⤓ ⥉ ⥌ ⥍ ⥏ ⥑ ⥔ ⥕ ⥘ ⥙ ⥜ ⥝ ⥠ ⥡ ⥣ ⥥ ⥮ ⥯ ↑ ↓)))
(define prec-decl '(|::|))
;; `where`
(define prec-dot '(|.|))

(define prec-names '(prec-assignment
Expand Down Expand Up @@ -137,12 +138,15 @@
(define end-symbol #f)
; treat newline like ordinary whitespace instead of as a potential separator
(define whitespace-newline #f)
; enable parsing `where` with high precedence
(define where-enabled #t)

(define current-filename 'none)

(define-macro (with-normal-ops . body)
`(with-bindings ((range-colon-enabled #t)
(space-sensitive #f))
(space-sensitive #f)
(where-enabled #t))
,@body))

(define-macro (without-range-colon . body)
Expand Down Expand Up @@ -579,6 +583,22 @@
(list 'if ex then (parse-eq* s))))))
(else ex))))

(define (parse-where-chain s first)
(with-bindings ((where-enabled #f))
(let loop ((ex first)
(t 'where))
(if (eq? t 'where)
(begin (take-token s)
(loop (list 'where ex (parse-comparison s)) (peek-token s)))
ex))))

(define (parse-where s)
(let ((ex (parse-call s)))
(if (and where-enabled
(eq? (peek-token s) 'where))
(parse-where-chain s ex)
ex)))

(define (invalid-initial-token? tok)
(or (eof-object? tok)
(memv tok '(#\) #\] #\} else elseif catch finally =))))
Expand Down Expand Up @@ -928,11 +948,11 @@
(parse-factor-h s parse-decl is-prec-power?))

(define (parse-decl s)
(let loop ((ex (parse-call s)))
(let loop ((ex (parse-where s)))
(let ((t (peek-token s)))
(case t
((|::|) (take-token s)
(loop (list t ex (parse-call s))))
(loop (list t ex (parse-where s))))
((->) (take-token s)
;; -> is unusual: it binds tightly on the left and
;; loosely on the right.
Expand All @@ -947,7 +967,7 @@
(begin (take-token s)
(cond ((let ((next (peek-token s)))
(or (closing-token? next) (newline? next))) op)
((memq op '(& |::|)) (list op (parse-call s)))
((memq op '(& |::|)) (list op (parse-where s)))
(else (list op (parse-unary-prefix s)))))
(parse-atom s))))

Expand All @@ -960,16 +980,18 @@
(parse-call-chain s ex #f))))

(define (parse-def s is-func)
(let ((ex (parse-unary-prefix s)))
(let ((sig (if (or (and is-func (reserved-word? ex)) (initial-reserved-word? ex))
(error (string "invalid name \"" ex "\""))
(parse-call-chain s ex #f))))
(if (and is-func
(eq? (peek-token s) '|::|))
(begin (take-token s)
`(|::| ,sig ,(parse-call s)))
sig))))

(let* ((ex (parse-unary-prefix s))
(sig (if (or (and is-func (reserved-word? ex)) (initial-reserved-word? ex))
(error (string "invalid name \"" ex "\""))
(parse-call-chain s ex #f)))
(decl-sig
(if (and is-func (eq? (peek-token s) '|::|))
(begin (take-token s)
`(|::| ,sig ,(parse-call s)))
sig)))
(if (eq? (peek-token s) 'where)
(parse-where-chain s decl-sig)
decl-sig)))

(define (deprecated-dict-replacement ex)
(if (dict-literal? ex)
Expand Down Expand Up @@ -1101,6 +1123,16 @@
(define (parse-subtype-spec s)
(parse-comparison s))

(define (valid-func-sig? sig)
(and (pair? sig)
(or (eq? (car sig) 'call)
(eq? (car sig) 'tuple)
(and (eq? (car sig) '|::|)
(pair? (cadr sig))
(eq? (car (cadr sig)) 'call))
(and (eq? (car sig) 'where)
(valid-func-sig? (cadr sig))))))

;; parse expressions or blocks introduced by syntactic reserved words
(define (parse-resword s word)
(with-bindings
Expand Down Expand Up @@ -1194,12 +1226,7 @@
`(tuple ,sig)
;; function foo => syntax error
(error (string "expected \"(\" in " word " definition")))
(if (not (and (pair? sig)
(or (eq? (car sig) 'call)
(eq? (car sig) 'tuple)
(and (eq? (car sig) '|::|)
(pair? (cadr sig))
(eq? (car (cadr sig)) 'call)))))
(if (not (valid-func-sig? sig))
(error (string "expected \"(\" in " word " definition"))
sig)))
(body (parse-block s)))
Expand All @@ -1220,7 +1247,7 @@
(parse-subtype-spec s)))
((typealias)
(let ((lhs (with-space-sensitive (parse-call s))))
(list 'typealias lhs (parse-arrow s))))
(list 'typealias lhs (parse-where s))))
((try)
(let ((try-block (if (memq (require-token s) '(catch finally))
'(block)
Expand Down
Loading

0 comments on commit 0c7a2fd

Please sign in to comment.