Skip to content

Commit

Permalink
rewriting macros to use esc(), remove manual gensyms where possible
Browse files Browse the repository at this point in the history
fix new expansion algorithm enough to be able to build sys image.
I had to resort to some pretty bad hacks to make this work. The
problem is that macros deal only with surface syntax, but local
variable/argument names can only be identified after some expansion.
  • Loading branch information
JeffBezanson committed Jul 23, 2012
1 parent 90f16ff commit b5bb5ce
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 88 deletions.
2 changes: 1 addition & 1 deletion base/base.jl
Expand Up @@ -135,7 +135,7 @@ end


append(xs...) = append_any(xs...) append(xs...) = append_any(xs...)


macro thunk(ex); :(()->$ex); end macro thunk(ex); :(()->$esc(ex)); end
macro L_str(s); s; end macro L_str(s); s; end


function compile_hint(f, args::Tuple) function compile_hint(f, args::Tuple)
Expand Down
2 changes: 1 addition & 1 deletion base/error.jl
Expand Up @@ -21,5 +21,5 @@ assert(x) = assert(x,'?')
assert(x,labl) = x ? nothing : error("assertion failed: ", labl) assert(x,labl) = x ? nothing : error("assertion failed: ", labl)


macro assert(ex) macro assert(ex)
:(($ex) ? nothing : error("assertion failed: ", $string(ex))) :($esc(ex) ? nothing : error("assertion failed: ", $string(ex)))
end end
24 changes: 3 additions & 21 deletions base/expr.jl
Expand Up @@ -14,34 +14,16 @@ gensym(a::Array{Uint8,1}) =
ccall(:jl_tagged_gensym, Any, (Ptr{Uint8}, Int32), a, length(a))::Symbol ccall(:jl_tagged_gensym, Any, (Ptr{Uint8}, Int32), a, length(a))::Symbol
gensym(ss::Union(ASCIIString, UTF8String)...) = map(gensym, ss) gensym(ss::Union(ASCIIString, UTF8String)...) = map(gensym, ss)


type UniqueNames
names::Array{Any,1}
UniqueNames() = new({})
end

let _names = {}
global gensym
function gensym(u::UniqueNames)
nu = length(u.names)
if nu >= length(_names)
push(_names, gensym())
end
s = _names[nu+1]
push(u.names, s)
return s
end
end

macro gensym(names...) macro gensym(names...)
blk = expr(:block) blk = expr(:block)
for name in names for name in names
push(blk.args, :($name = gensym($(string(name))))) push(blk.args, :($esc(name) = gensym($(string(name)))))
end end
push(blk.args, :nothing) push(blk.args, :nothing)
return blk return blk
end end


syntax_escape(e) = expr(:escape, {e}) esc(e::ANY) = expr(:escape, {e})


## expressions ## ## expressions ##


Expand Down Expand Up @@ -75,5 +57,5 @@ macro eval(x)
end end


macro task(ex) macro task(ex)
:(Task(()->$ex)) :(Task(()->$esc(ex)))
end end
9 changes: 2 additions & 7 deletions base/intfuncs.jl
Expand Up @@ -286,20 +286,15 @@ base(b::Union(Int,Array{Uint8}), x::Unsigned) = base(b,x,1,false)
base(b::Union(Int,Array{Uint8}), x::Integer, p::Int) = base(b,unsigned(abs(x)),p,x<0) base(b::Union(Int,Array{Uint8}), x::Integer, p::Int) = base(b,unsigned(abs(x)),p,x<0)
base(b::Union(Int,Array{Uint8}), x::Integer) = base(b,unsigned(abs(x)),1,x<0) base(b::Union(Int,Array{Uint8}), x::Integer) = base(b,unsigned(abs(x)),1,x<0)


macro _jl_int_stringifier(sym) for sym in (:bin, :oct, :dec, :hex)
quote @eval begin
($sym)(x::Unsigned, p::Int) = ($sym)(x,p,false) ($sym)(x::Unsigned, p::Int) = ($sym)(x,p,false)
($sym)(x::Unsigned) = ($sym)(x,1,false) ($sym)(x::Unsigned) = ($sym)(x,1,false)
($sym)(x::Integer, p::Int) = ($sym)(unsigned(abs(x)),p,x<0) ($sym)(x::Integer, p::Int) = ($sym)(unsigned(abs(x)),p,x<0)
($sym)(x::Integer) = ($sym)(unsigned(abs(x)),1,x<0) ($sym)(x::Integer) = ($sym)(unsigned(abs(x)),1,x<0)
end end
end end


@_jl_int_stringifier bin
@_jl_int_stringifier oct
@_jl_int_stringifier dec
@_jl_int_stringifier hex

bits(x::Union(Bool,Int8,Uint8)) = bin(reinterpret(Uint8,x),8) bits(x::Union(Bool,Int8,Uint8)) = bin(reinterpret(Uint8,x),8)
bits(x::Union(Int16,Uint16)) = bin(reinterpret(Uint16,x),16) bits(x::Union(Int16,Uint16)) = bin(reinterpret(Uint16,x),16)
bits(x::Union(Char,Int32,Uint32,Float32)) = bin(reinterpret(Uint32,x),32) bits(x::Union(Char,Int32,Uint32,Float32)) = bin(reinterpret(Uint32,x),32)
Expand Down
36 changes: 17 additions & 19 deletions base/multi.jl
Expand Up @@ -1277,12 +1277,11 @@ function sync_end()
end end


macro sync(block) macro sync(block)
@gensym v
quote quote
sync_begin() sync_begin()
$v = $block v = $esc(block)
sync_end() sync_end()
$v v
end end
end end


Expand Down Expand Up @@ -1348,7 +1347,7 @@ end


macro spawn(expr) macro spawn(expr)
expr = localize_vars(:(()->($expr))) expr = localize_vars(:(()->($expr)))
:(spawn($expr)) :(spawn($esc(expr)))
end end


function spawnlocal(thunk) function spawnlocal(thunk)
Expand All @@ -1367,12 +1366,12 @@ end


macro spawnlocal(expr) macro spawnlocal(expr)
expr = localize_vars(:(()->($expr))) expr = localize_vars(:(()->($expr)))
:(spawnlocal($expr)) :(spawnlocal($esc(expr)))
end end


macro spawnat(p, expr) macro spawnat(p, expr)
expr = localize_vars(:(()->($expr))) expr = localize_vars(:(()->($expr)))
:(spawnat($p, $expr)) :(spawnat($p, $esc(expr)))
end end


function at_each(f, args...) function at_each(f, args...)
Expand Down Expand Up @@ -1469,28 +1468,26 @@ function pfor(f, r::Range1{Int})
end end


function make_preduce_body(reducer, var, body) function make_preduce_body(reducer, var, body)
@gensym ac lo hi
localize_vars( localize_vars(
quote quote
function (($lo)::Int, ($hi)::Int) function (lo::Int, hi::Int)
($var) = ($lo) $esc(var) = lo
($ac) = $body ac = $esc(body)
for ($var) = (($lo)+1):($hi) for $esc(var) = (lo+1):hi
($ac) = ($reducer)($ac, $body) ac = $esc(reducer)(ac, $esc(body))
end end
$ac ac
end end
end end
) )
end end


function make_pfor_body(var, body) function make_pfor_body(var, body)
@gensym lo hi
localize_vars( localize_vars(
quote quote
function (($lo)::Int, ($hi)::Int) function (lo::Int, hi::Int)
for ($var) = ($lo):($hi) for $esc(var) = lo:hi
$body $esc(body)
end end
end end
end end
Expand All @@ -1515,11 +1512,12 @@ macro parallel(args...)
body = loop.args[2] body = loop.args[2]
if na==1 if na==1
quote quote
pfor($make_pfor_body(var, body), $r) pfor($make_pfor_body(var, body), $esc(r))
end end
else else
quote quote
preduce($reducer, $make_preduce_body(reducer, var, body), $r) preduce($esc(reducer),
$make_preduce_body(reducer, var, body), $esc(r))
end end
end end
end end
Expand Down
2 changes: 2 additions & 0 deletions base/operators.jl
Expand Up @@ -215,6 +215,7 @@ to_index(i::Real) = convert(Int, i)
# vectorization # vectorization


macro vectorize_1arg(S,f) macro vectorize_1arg(S,f)
S = esc(S); f = esc(f)
quote quote
function ($f){T<:$S}(x::AbstractArray{T,1}) function ($f){T<:$S}(x::AbstractArray{T,1})
[ ($f)(x[i]) for i=1:length(x) ] [ ($f)(x[i]) for i=1:length(x) ]
Expand All @@ -229,6 +230,7 @@ macro vectorize_1arg(S,f)
end end


macro vectorize_2arg(S,f) macro vectorize_2arg(S,f)
S = esc(S); f = esc(f)
quote quote
function ($f){T1<:$S, T2<:$S}(x::T1, y::AbstractArray{T2}) function ($f){T1<:$S, T2<:$S}(x::T1, y::AbstractArray{T2})
reshape([ ($f)(x, y[i]) for i=1:numel(y) ], size(y)) reshape([ ($f)(x, y[i]) for i=1:numel(y) ], size(y))
Expand Down
4 changes: 2 additions & 2 deletions base/osutils.jl
Expand Up @@ -2,15 +2,15 @@ include("os_detect.jl")


macro windows_only(ex) macro windows_only(ex)
if(CURRENT_OS == :Windows) if(CURRENT_OS == :Windows)
return ex return esc(ex)
else else
return :nothing return :nothing
end end
end end


macro unix_only(ex) macro unix_only(ex)
if(_jl_is_unix(CURRENT_OS)) if(_jl_is_unix(CURRENT_OS))
return ex return esc(ex)
else else
return :nothing return :nothing
end end
Expand Down
8 changes: 4 additions & 4 deletions base/printf.jl
Expand Up @@ -495,7 +495,7 @@ end


macro handle_zero() macro handle_zero()
quote quote
if x == 0 if $esc(:x) == 0
_jl_point[1] = 1 _jl_point[1] = 1
_jl_digits[1] = '0' _jl_digits[1] = '0'
return return
Expand Down Expand Up @@ -574,9 +574,9 @@ _jl_int_HEX(x::Unsigned) = (_jl_neg[1]=false; _jl_decode_HEX(x))


macro handle_negative() macro handle_negative()
quote quote
if x < 0 if $esc(:x) < 0
_jl_neg[1] = true _jl_neg[1] = true
x = -x $esc(:x) = -($esc(:x))
else else
_jl_neg[1] = false _jl_neg[1] = false
end end
Expand Down Expand Up @@ -761,7 +761,7 @@ macro printf(f, exps...)
end end
for i = length(args):-1:1 for i = length(args):-1:1
arg = args[i].args[1] arg = args[i].args[1]
unshift(blk.args, :($arg = $(exps[i]))) unshift(blk.args, :($arg = $esc(exps[i])))
end end
blk blk
end end
Expand Down
4 changes: 2 additions & 2 deletions base/string.jl
Expand Up @@ -626,7 +626,7 @@ function _jl_interp_parse(s::String, unescape::Function, printer::Function)
if isa(ex,Expr) && is(ex.head,:continue) if isa(ex,Expr) && is(ex.head,:continue)
throw(ParseError("incomplete expression")) throw(ParseError("incomplete expression"))
end end
push(sx, ex) push(sx, esc(ex))
i = j i = j
elseif c == '\\' && !done(s,k) elseif c == '\\' && !done(s,k)
if s[k] == '$' if s[k] == '$'
Expand Down Expand Up @@ -710,7 +710,7 @@ function _jl_shell_parse(s::String, interp::Bool)
error("space not allowed right after \$") error("space not allowed right after \$")
end end
ex, j = parseatom(s,j) ex, j = parseatom(s,j)
update_arg(ex); i = j update_arg(esc(ex)); i = j
else else
if !in_double_quotes && c == '\'' if !in_double_quotes && c == '\''
in_single_quotes = !in_single_quotes in_single_quotes = !in_single_quotes
Expand Down
2 changes: 1 addition & 1 deletion base/sysimg.jl
Expand Up @@ -14,7 +14,7 @@ export
Rational,Regex,RegexMatch,RegexMatchIterator,Region,RemoteRef,RepString, Rational,Regex,RegexMatch,RegexMatchIterator,Region,RemoteRef,RepString,
RevString,Reverse,RopeString,Set,StridedArray,StridedMatrix,StridedVecOrMat, RevString,Reverse,RopeString,Set,StridedArray,StridedMatrix,StridedVecOrMat,
StridedVector,SubArray,SubDArray,SubOrDArray,SubString,TransformedString, StridedVector,SubArray,SubDArray,SubOrDArray,SubString,TransformedString,
UniqueNames,VecOrMat,Vector,VersionNumber,WeakKeyDict,Zip, VecOrMat,Vector,VersionNumber,WeakKeyDict,Zip,
Stat, Factorization, Cholesky, LU, QR, QRP, Stat, Factorization, Cholesky, LU, QR, QRP,
# Exceptions # Exceptions
ArgumentError,BackTrace,DisconnectException,ErrorException,KeyError, ArgumentError,BackTrace,DisconnectException,ErrorException,KeyError,
Expand Down
19 changes: 8 additions & 11 deletions base/util.jl
Expand Up @@ -33,24 +33,21 @@ end


# print elapsed time, return expression value # print elapsed time, return expression value
macro time(ex) macro time(ex)
@gensym t0 val t1
quote quote
local $t0 = time() local t0 = time()
local $val = $ex local val = $esc(ex)
local $t1 = time() local t1 = time()
println("elapsed time: ", $t1-$t0, " seconds") println("elapsed time: ", t1-t0, " seconds")
$val val
end end
end end


# print nothing, return elapsed time # print nothing, return elapsed time
macro elapsed(ex) macro elapsed(ex)
@gensym t0 val t1
quote quote
local $t0 = time() local t0 = time()
local $val = $ex local val = $esc(ex)
local $t1 = time() time()-t0
$t1-$t0
end end
end end


Expand Down

2 comments on commit b5bb5ce

@dreiss-isb
Copy link
Contributor

Choose a reason for hiding this comment

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

I am now getting errors that say

syntax error: prefix $ outside of quote block
syntax error: error expanding macro parallel at /home/ISB/dreiss/scratch/julia/cmonkey/kmeans.jl:78

Do you mean to have $esc(ex) in there or was it an incomplete search/replace and should be esc($ex) ? ;)

@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.

Thanks; fixed.

Please sign in to comment.