Can I concatenate expressions in macro?

i have array of expressions generated in macro and i want to return it all so they will be executed one by one

You could look at how a block of expressions is normally represented and try to rebuild that. For example

julia> a = quote
       a = 1+1
       b = a + 4
       end
quote
    #= REPL[16]:2 =#
    a = 1 + 1
    #= REPL[16]:3 =#
    b = a + 4
end

julia> dump(a)
Expr
  head: Symbol block
  args: Array{Any}((6,))
    1: LineNumberNode
      line: Int64 2
      file: Symbol REPL[16]
    2: Expr
      head: Symbol =
      args: Array{Any}((2,))
        1: Symbol a
        2: Expr
          head: Symbol call
          args: Array{Any}((3,))
            1: Symbol +
            2: Int64 1
            3: Int64 1
    3: LineNumberNode
      line: Int64 3
      file: Symbol REPL[16]
    4: Expr
      head: Symbol =
      args: Array{Any}((2,))
        1: Symbol b
        2: Expr
          head: Symbol call
          args: Array{Any}((3,))
            1: Symbol +
            2: Symbol a
            3: Int64 4

Here the LineNumberNode is not interesting, but what we see is that we just have an expression with head being :block, and the remaining expressions are in the args. So if you have an array with expressions you could probably do something along the lines of

macro mymacro(args...)
    exprs = preprocess(args) # Whatever you do to create the expression list
    Expr(:block, exprs...) # Create a block expression with all sub-expressions
end

This works very well thank you @albheim
Just one more thing before and after this list of expression i want to put the while and end
so I want to add this while and end as expression - yet I get the error in both cases - so i suppose I need somehow escape while and end phrases but how to do this?

push!(tmp, quote while($offsetIter <32) end)
push…
push!(tmp, quote end end)

So what you want the macro to generate in the end is something like this?

while condition
    expr1
    expr2
    ...
end

I would suggest to continue with the same approach as I hinted to before, i.e. just have a look at how

julia> a = quote
       while 3 < 4
       1+1
       end
       end
quote
    #= REPL[1]:2 =#
    while 3 < 4
        #= REPL[1]:3 =#
        1 + 1
    end
end

julia> dump(a)
Expr
  head: Symbol block
  args: Array{Any}((2,))
    1: LineNumberNode
      line: Int64 2
      file: Symbol REPL[1]
    2: Expr
      head: Symbol while
      args: Array{Any}((2,))
        1: Expr
          head: Symbol call
          args: Array{Any}((3,))
            1: Symbol <
            2: Int64 3
            3: Int64 4
        2: Expr
          head: Symbol block
          args: Array{Any}((2,))
            1: LineNumberNode
              line: Int64 3
              file: Symbol REPL[1]
            2: Expr
              head: Symbol call
              args: Array{Any}((3,))
                1: Symbol +
                2: Int64 1
                3: Int64 1

behaves and generate the same expression. Will probably be something like

Expr(:while, Expr(:call, :<, :offsetIter, 32), Expr(:block, exprs...))

but you might have to think about what scope offsetIter exists and whether it need escaping or similar.

1 Like

I answered this question yesterday on Slack when you asked this there by the way

1 Like

Oh sorry I thought it was so far behind it would not be seen