Skip to content

Commit

Permalink
implement "do" block syntax. closes #441
Browse files Browse the repository at this point in the history
    foo(a,b) do x,y
      # ...
    end

is syntax for

    foo((x,y)->begin
      # ...
    end, a,b)
  • Loading branch information
JeffBezanson committed May 30, 2012
1 parent 754bee3 commit 944d672
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 38 deletions.
8 changes: 4 additions & 4 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ length(a::Array) = arraylen(a)

## copy ##

function copy_to{T}(dest::Array{T}, do, src::Array{T}, so, N)
if so+N-1 > numel(src) || do+N-1 > numel(dest) || do < 1 || so < 1
function copy_to{T}(dest::Array{T}, dsto, src::Array{T}, so, N)
if so+N-1 > numel(src) || dsto+N-1 > numel(dest) || dsto < 1 || so < 1
throw(BoundsError())
end
if isa(T, BitsKind)
ccall(:memcpy, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Uint),
pointer(dest, do), pointer(src, so), N*sizeof(T))
pointer(dest, dsto), pointer(src, so), N*sizeof(T))
else
for i=0:N-1
dest[i+do] = src[i+so]
dest[i+dsto] = src[i+so]
end
end
return dest
Expand Down
4 changes: 2 additions & 2 deletions contrib/julia-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
'("if" "else" "elseif" "while" "for" "begin" "end" "quote"
"try" "catch" "return" "local" "abstract" "function" "macro" "ccall"
"typealias" "break" "continue" "type" "global" "@\\w+"
"module" "import" "export" "const" "let" "bitstype")
"module" "import" "export" "const" "let" "bitstype" "do")
"\\|") "\\)\\>")
'font-lock-keyword-face)
'("\\<\\(true\\|false\\|C_NULL\\|Inf\\|NaN\\|Inf32\\|NaN32\\)\\>" . font-lock-constant-face)
Expand All @@ -81,7 +81,7 @@

(defconst julia-block-start-keywords
(list "if" "while" "for" "begin" "try" "function" "type" "let" "macro"
"quote"))
"quote" "do"))

(defconst julia-block-other-keywords
(list "else" "elseif"))
Expand Down
38 changes: 28 additions & 10 deletions src/julia-parser.scm
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
(define reserved-words '(begin while if for try return break continue
function macro quote let local global const
abstract typealias type bitstype
module import export ccall))
module import export ccall do))

(define (syntactic-op? op) (memq op syntactic-operators))
(define (syntactic-unary-op? op) (memq op syntactic-unary-operators))
Expand Down Expand Up @@ -622,7 +622,12 @@
ex
(case t
((#\( ) (take-token s)
(loop (list* 'call ex (parse-arglist s #\) ))))
(let ((al (parse-arglist s #\) )))
(if (eq? (peek-token s) 'do)
(begin
(take-token s)
(loop `(call ,ex ,(parse-do s) ,@al)))
(loop `(call ,ex ,@al)))))
((#\[ ) (take-token s)
; ref is syntax, so we can distinguish
; a[i] = x from
Expand Down Expand Up @@ -656,16 +661,20 @@

;(define (parse-dot s) (parse-LtoR s parse-atom (prec-ops 13)))

(define expect-end-current-line 0)

(define (expect-end- s word)
(let ((t (peek-token s)))
(if (eq? t 'end)
(take-token s)
(error (string "incomplete: " word " at "
current-filename ":" expect-end-current-line
" requires end")))))

; parse expressions or blocks introduced by syntactic reserved words
(define (parse-resword s word)
(define current-line (input-port-line (ts:port s)))
(define (expect-end s)
(let ((t (peek-token s)))
(if (eq? t 'end)
(take-token s)
(error (string "incomplete: " word " at "
current-filename ":" current-line
" requires end")))))
(set! expect-end-current-line (input-port-line (ts:port s)))
(define (expect-end s) (expect-end- s word))
(with-normal-ops
(without-whitespace-newline
(case word
Expand Down Expand Up @@ -815,8 +824,17 @@
;; place (callingconv) at end of arglist
`(ccall ,(car al) ,@(cddr al) (,(cadr al)))
`(ccall ,.al))))
((do)
(error "invalid do syntax"))
(else (error "unhandled reserved word"))))))

(define (parse-do s)
(set! expect-end-current-line (input-port-line (ts:port s)))
(let ((doargs (parse-comma-separated-assignments s)))
`(-> (tuple ,@doargs)
,(begin0 (parse-block s)
(expect-end- s 'do)))))

; parse comma-separated assignments, like "i=1:n,j=1:m,..."
(define (parse-comma-separated-assignments s)
(let loop ((ranges '()))
Expand Down
22 changes: 0 additions & 22 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1003,28 +1003,6 @@

)) ; patterns

; patterns that verify all syntactic sugar was well-formed
; if any sugary forms remain after the above patterns, it means the
; patterns didn't match, which implies a syntax error.
(define check-desugared
(pattern-set
(pattern-lambda (function . any)
(error "invalid function definition"))

(pattern-lambda (for . any)
(error "invalid for loop syntax"))

(pattern-lambda (type . any)
(error "invalid type definition"))

(pattern-lambda (typealias . any)
(error "invalid typealias statement"))

(pattern-lambda (macro . any)
(error "macros must be defined at the top level"))

))

;; Comprehensions

(define (lower-nd-comprehension expr ranges)
Expand Down

6 comments on commit 944d672

@StefanKarpinski
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YESSSS!!!!!

@StefanKarpinski
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One issue: doesn't handle the zero-argument case for, e.g., cd:

cd(dir) do
  # stuff
end

It's also sometimes convenient to write one-liners, something like this:

cd(dir) do whatever() end

Maybe parens around the do-block arguments should be required?

@JeffBezanson
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zero arg case fixed.

The other case is sort of a one-line version of a multi-line version of a one-line syntax...
Too ambiguous for me right now.

@StefanKarpinski
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. Thanks for the fix and the feature.

@nolta
Copy link
Member

@nolta nolta commented on 944d672 May 31, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upstream pygments now recognizes do as a keyword.

@pao
Copy link
Member

@pao pao commented on 944d672 May 31, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was quick! Thanks, @nolta.

Please sign in to comment.