From 944d6728430dfb5a6241defcd82c7d9e844224dd Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 30 May 2012 17:16:06 -0400 Subject: [PATCH] implement "do" block syntax. closes #441 foo(a,b) do x,y # ... end is syntax for foo((x,y)->begin # ... end, a,b) --- base/array.jl | 8 ++++---- contrib/julia-mode.el | 4 ++-- src/julia-parser.scm | 38 ++++++++++++++++++++++++++++---------- src/julia-syntax.scm | 22 ---------------------- 4 files changed, 34 insertions(+), 38 deletions(-) diff --git a/base/array.jl b/base/array.jl index f73e2c0e1e69f..1b565f399db11 100644 --- a/base/array.jl +++ b/base/array.jl @@ -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 diff --git a/contrib/julia-mode.el b/contrib/julia-mode.el index 1f239d5b0636e..bd1bfc1d979c9 100644 --- a/contrib/julia-mode.el +++ b/contrib/julia-mode.el @@ -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) @@ -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")) diff --git a/src/julia-parser.scm b/src/julia-parser.scm index a6374c01e3dce..fc89225c530f6 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -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)) @@ -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 @@ -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 @@ -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 '())) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 305c66d74cf7d..b58453a43320e 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -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)