Skip to content
On this page

API Reference

Syntax Types

Convenient types for storing analysis results of a given Julia Expr, or for creating certain Julia objects easily. These types define some common syntax one would manipulate in Julia meta programming.

#Expronicon.JLFunctionType.

julia
mutable struct JLFunction <: JLExpr
JLFunction(;kw...)

Type describes a Julia function declaration expression.

Fields and Keyword Arguments

All the following fields are valid as keyword arguments kw in the constructor, and can be access via <object>.<field>.

The only required keyword argument for the constructor is name, the rest are all optional.

  • head: optional, function head, can be :function, :(=) or :(->).
  • name: optional, function name, can has type Nothing, Symbol or Expr, default is nothing.
  • args: optional, function arguments, a list of Expr or Symbol.
  • kwargs: optional, function keyword arguments, a list of Expr(:kw, name, default).
  • rettype: optional, the explicit return type of a function, can be a Type, Symbol, Expr or just nothing, default is nothing.
  • whereparams: optional, type variables, can be a list of Type, Expr or nothing, default is nothing.
  • body: optional, function body, an Expr, default is Expr(:block).
  • line::LineNumberNode: a LineNumberNode to indicate the line information.
  • doc::String: the docstring of this definition.

Example

Construct a function expression

julia
julia> JLFunction(;name=:foo, args=[:(x::T)], body= quote 1+1 end, head=:function, whereparams=[:T])
function foo(x::T) where {T}
    #= REPL[25]:1 =#    
    1 + 1    
end

Decompose a function expression

julia
julia> ex = :(function foo(x::T) where {T}
           #= REPL[25]:1 =#    
           1 + 1    
       end)
:(function foo(x::T) where T
      #= REPL[26]:1 =#
      #= REPL[26]:3 =#
      1 + 1
  end)

julia> jl = JLFunction(ex)
function foo(x::T) where {T}
    #= REPL[26]:1 =#    
    #= REPL[26]:3 =#    
    1 + 1    
end

Generate Expr from JLFunction

julia
julia> codegen_ast(jl)
:(function foo(x::T) where T
      #= REPL[26]:1 =#
      #= REPL[26]:3 =#
      1 + 1
  end)

source

#Expronicon.JLStructType.

julia
mutable struct JLStruct <: JLExpr

Type describes a Julia struct.

JLStruct(;kw...)

Create a JLStruct instance.

Available Fields and Keyword Arguments

All the following fields are valid as keyword arguments kw in the constructor, and can be access via <object>.<field>.

The only required keyword argument for the constructor is name, the rest are all optional.

  • name::Symbol: name of the struct, this is the only required keyword argument.
  • ismutable::Bool: if the struct definition is mutable.
  • typevars::Vector{Any}: type variables of the struct, should be Symbol or Expr.
  • supertype: supertype of the struct definition.
  • fields::Vector{JLField}: field definitions of the struct, should be a JLField.
  • constructors::Vector{JLFunction}: constructors definitions of the struct, should be JLFunction.
  • line::LineNumberNode: a LineNumberNode to indicate the definition position for error report etc.
  • doc::String: documentation string of the struct.
  • misc: other things that happens inside the struct body, by definition this will just fall through and is equivalent to eval them outside the struct body.

Example

Construct a Julia struct.

julia
julia> JLStruct(;name=:Foo, typevars=[:T], fields=[JLField(;name=:x, type=Int)])
struct Foo{T}
    x::Int64
end

Decompose a Julia struct expression

julia
julia> ex = :(struct Foo{T}
           x::Int64
       end)
:(struct Foo{T}
      #= REPL[31]:2 =#
      x::Int64
  end)

julia> jl = JLStruct(ex)
struct Foo{T}
    #= REPL[31]:2 =#
    x::Int64
end

Generate a Julia struct expression

julia
julia> codegen_ast(jl)
:(struct Foo{T}
      #= REPL[31]:2 =#
      x::Int64
  end)

source

#Expronicon.JLKwStructType.

julia
mutable struct JLKwStruct <: JLExpr
JLKwStruct(;kw...)

Type describes a Julia struct that allows keyword definition of defaults. This syntax is similar to JLStruct except the the fields are of type JLKwField.

Fields and Keyword Arguments

All the following fields are valid as keyword arguments kw in the constructor, and can be access via <object>.<field>.

The only required keyword argument for the constructor is name, the rest are all optional.

  • name::Symbol: name of the struct, this is the only required keyword argument.
  • typealias::String: an alias of the JLKwStruct, see also the @option macro in Configurations.jl.
  • ismutable::Bool: if the struct definition is mutable.
  • typevars::Vector{Any}: type variables of the struct, should be Symbol or Expr.
  • supertype: supertype of the struct definition.
  • fields::Vector{JLField}: field definitions of the struct, should be a JLField.
  • constructors::Vector{JLFunction}: constructors definitions of the struct, should be JLFunction.
  • line::LineNumberNode: a LineNumberNode to indicate the definition position for error report etc.
  • doc::String: documentation string of the struct.
  • misc: other things that happens inside the struct body, by definition this will just fall through and is equivalent to eval them outside the struct body.

source

#Expronicon.JLIfElseType.

julia
JLIfElse <: JLExpr
JLIfElse(;kw...)

JLIfElse describes a Julia if ... elseif ... else ... end expression. It allows one to easily construct such expression by inserting condition and code block via a map.

Fields and Keyword Arguments

All the following fields are valid as keyword arguments kw in the constructor, and can be access via <object>.<field>.

  • conds::Vector{Any}: expression for the conditions.
  • stmts::Vector{Any}: expression for the statements for corresponding condition.
  • otherwise: the else body.

Example

Construct JLIfElse object

One can construct an ifelse as following

julia
julia> jl = JLIfElse()
nothing

julia> jl[:(foo(x))] = :(x = 1 + 1)
:(x = 1 + 1)

julia> jl[:(goo(x))] = :(y = 1 + 2)
:(y = 1 + 2)

julia> jl.otherwise = :(error("abc"))
:(error("abc"))

julia> jl
if foo(x)
    x = 1 + 1
elseif goo(x)
    y = 1 + 2
else
    error("abc")
end

Generate the Julia Expr object

to generate the corresponding Expr object, one can call codegen_ast.

julia
julia> codegen_ast(jl)
:(if foo(x)
      x = 1 + 1
  elseif goo(x)
      y = 1 + 2
  else
      error("abc")
  end)

source

#Expronicon.JLMatchType.

julia
JLMatch <: JLExpr

JLMatch describes a Julia pattern match expression defined by MLStyle. It allows one to construct such expression by simply assign each code block to the corresponding pattern expression.

!!! tip JLMatch is not available in ExproniconLite since it depends on MLStyle's pattern matching functionality.

Example

One can construct a MLStyle pattern matching expression easily by assigning the corresponding pattern and its result to the map field.

julia
julia> jl = JLMatch(:x)
#= line 0 =#
nothing

julia> jl = JLMatch(:x)
#= line 0 =#
nothing

julia> jl.map[1] = true
true

julia> jl.map[2] = :(sin(x))
:(sin(x))

julia> jl
#= line 0 =#
@match x begin
    1 => true
    2 => sin(x)
    _ =>     nothing
end

to generate the corresponding Julia Expr object, one can call codegen_ast.

julia
julia> codegen_ast(jl)
:(let
      true
      var"##return#263" = nothing
      var"##265" = x
      if var"##265" isa Int64
          #= line 0 =#
          if var"##265" === 1
              var"##return#263" = let
                      true
                  end
              #= unused:1 =# @goto var"####final#264#266"
          end
          #= line 0 =#
          if var"##265" === 2
              var"##return#263" = let
                      sin(x)
                  end
              #= unused:1 =# @goto var"####final#264#266"
          end
      end
      #= line 0 =#
      begin
          var"##return#263" = let
                  nothing
              end
          #= unused:1 =# @goto var"####final#264#266"
      end
      (error)("matching non-exhaustive, at #= line 0 =#")
      #= unused:1 =# @label var"####final#264#266"
      var"##return#263"
  end)

source

#Expronicon.JLForType.

julia
JLFor <: JLExpr

Syntax type for Julia for loop.

source

#Expronicon.JLFieldType.

julia
mutable struct JLField <: JLExpr
JLField(;kw...)

Type describes a Julia field in a Julia struct.

Fields and Keyword Arguments

All the following fields are valid as keyword arguments kw in the constructor, and can be access via <object>.<field>.

The only required keyword argument for the constructor is name, the rest are all optional.

  • name::Symbol: the name of the field.
  • type: the type of the field.
  • isconst: if the field is annotated with const.
  • line::LineNumberNode: a LineNumberNode to indicate the line information.
  • doc::String: the docstring of this definition.

source

#Expronicon.JLKwFieldType.

julia
mutable struct JLKwField <: JLExpr

Type describes a Julia field that can have a default value in a Julia struct.

JLKwField(;kw...)

Create a JLKwField instance.

Fields and Keyword Arguments

All the following fields are valid as keyword arguments kw in the constructor, and can be access via <object>.<field>.

The only required keyword argument for the constructor is name, the rest are all optional.

  • name::Symbol: the name of the field.
  • type: the type of the field.
  • isconst: if the field is annotated with const.
  • default: default value of the field, default is no_default.
  • line::LineNumberNode: a LineNumberNode to indicate the line information.
  • doc::String: the docstring of this definition.

source

#Expronicon.NoDefaultType.

julia
NoDefault

Type describes a field should have no default value.

source

#Expronicon.no_defaultConstant.

julia
const no_default = NoDefault()

Constant instance for NoDefault that describes a field should have no default value.

source

#Expronicon.JLExprType.

julia
abstract type JLExpr end

Abstract type for Julia syntax type.

source

Analysis

Functions for analysing a given Julia Expr, e.g splitting Julia function/struct definitions etc.

Transform

Some common transformations for Julia Expr, these functions takes an Expr and returns an Expr.

#Expronicon.SubstituteType.

julia
Substitute(condition) -> substitute(f(expr), expr)

Returns a function that substitutes expr with f(expr) if condition(expr) is true. Applied recursively to all sub-expressions.

Example

julia
julia> sub = Substitute() do expr
           expr isa Symbol && expr in [:x] && return true
           return false
       end;

julia> sub(_->1, :(x + y))
:(1 + y)

source

#Expronicon.alias_gensymMethod.

julia
alias_gensym(ex)

Replace gensym with <name>_<id>.

!!! note Borrowed from MacroTools.

source

#Expronicon.annotations_onlyMethod.

julia
annotations_only(ex)

Return type annotations only. See also name_only.

source

#Expronicon.eval_interpMethod.

julia
eval_interp(m::Module, ex)

evaluate the interpolation operator in ex inside given module m.

source

#Expronicon.eval_literalMethod.

julia
eval_literal(m::Module, ex)

Evaluate the literal values and insert them back to the expression. The literal value can be checked via is_literal.

source

#Expronicon.expr_mapMethod.

julia
expr_map(f, c...)

Similar to Base.map, but expects f to return an expression, and will concatenate these expression as a Expr(:block, ...) expression.

Example

julia
julia> expr_map(1:10, 2:11) do i,j
           :(1 + $i + $j)
       end
quote
    1 + 1 + 2
    1 + 2 + 3
    1 + 3 + 4
    1 + 4 + 5
    1 + 5 + 6
    1 + 6 + 7
    1 + 7 + 8
    1 + 8 + 9
    1 + 9 + 10
    1 + 10 + 11
end

source

#Expronicon.flatten_blocksMethod.

julia
flatten_blocks(ex)

Remove hierarchical expression blocks.

source

#Expronicon.name_onlyMethod.

julia
name_only(ex)

Remove everything else leaving just names, currently supports function calls, type with type variables, subtype operator <: and type annotation ::.

Example

julia
julia> using Expronicon

julia> name_only(:(sin(2)))
:sin

julia> name_only(:(Foo{Int}))
:Foo

julia> name_only(:(Foo{Int} <: Real))
:Foo

julia> name_only(:(x::Int))
:x

source

#Expronicon.nexprsMethod.

julia
nexprs(f, n::Int)

Create n similar expressions by evaluating f.

Example

julia
julia> nexprs(5) do k
           :(1 + $k)
       end
quote
    1 + 1
    1 + 2
    1 + 3
    1 + 4
    1 + 5
end

source

#Expronicon.prettifyMethod.

julia
prettify(ex; kw...)

Prettify given expression, remove all LineNumberNode and extra code blocks.

Options (Kwargs)

All the options are true by default.

  • rm_lineinfo: remove LineNumberNode.
  • flatten_blocks: flatten begin ... end code blocks.
  • rm_nothing: remove nothing in the begin ... end.
  • preserve_last_nothing: preserve the last nothing in the begin ... end.
  • rm_single_block: remove single begin ... end.
  • alias_gensym: replace ##<name>#<num> with <name>_<id>.
  • renumber_gensym: renumber the gensym id.

!!! tips the LineNumberNode inside macro calls won't be removed since the macrocall expression requires a LineNumberNode. See also issues/#9.

source

#Expronicon.renumber_gensymMethod.

julia
renumber_gensym(ex)

Re-number gensym with counter from this expression. Produce a deterministic gensym name for testing etc. See also: alias_gensym

source

#Expronicon.rm_annotationsMethod.

julia
rm_annotations(x)

Remove type annotation of given expression.

source

#Expronicon.rm_lineinfoMethod.

julia
rm_lineinfo(ex)

Remove LineNumberNode in a given expression.

!!! tips the LineNumberNode inside macro calls won't be removed since the macrocall expression requires a LineNumberNode. See also issues/#9.

source

#Expronicon.rm_nothingMethod.

julia
rm_nothing(ex)

Remove the constant value nothing in given expression ex.

Keyword Arguments

  • preserve_last_nothing: if true, the last nothing will be preserved.

source

#Expronicon.substituteMethod.

julia
substitute(ex::Expr, old=>new)

Substitute the old symbol old with new.

source

CodeGen

Code generators, functions that generates Julia Expr from given arguments, Expronicon types.

#Expronicon.codegen_astMethod.

julia
codegen_ast(def)

Generate Julia AST object Expr from a given syntax type.

Example

One can generate the Julia AST object from a JLKwStruct syntax type.

julia
julia> def = @expr JLKwStruct struct Foo{N, T}
                  x::T = 1
              end
#= kw =# struct Foo{N, T}
    #= REPL[19]:2 =#
    x::T = 1
end

julia> codegen_ast(def)|>rm_lineinfo
quote
    struct Foo{N, T}
        x::T
    end
    begin
        function Foo{N, T}(; x = 1) where {N, T}
            Foo{N, T}(x)
        end
        function Foo{N}(; x::T = 1) where {N, T}
            Foo{N, T}(x)
        end
    end
end

source

#Expronicon.codegen_ast_fieldsMethod.

julia
codegen_ast_fields(fields; just_name::Bool=true)

Generate a list of Julia AST object for each field, only generate a list of field names by default, option just_name can be turned off to call codegen_ast on each field object.

source

#Expronicon.codegen_ast_kwfnFunction.

julia
codegen_ast_kwfn(def[, name = nothing])

Generate the keyword function from a Julia struct definition.

Example

julia
julia> def = @expr JLKwStruct struct Foo{N, T}
                  x::T = 1
              end
#= kw =# struct Foo{N, T}
    #= REPL[19]:2 =#
    x::T = 1
end

julia> codegen_ast_kwfn(def)|>prettify
quote
    function Foo{N, T}(; x = 1) where {N, T}
        Foo{N, T}(x)
    end
    function Foo{N}(; x::T = 1) where {N, T}
        Foo{N, T}(x)
    end
end

julia> def = @expr JLKwStruct struct Foo
                  x::Int = 1
              end
#= kw =# struct Foo
    #= REPL[23]:2 =#
    x::Int = 1
end

julia> codegen_ast_kwfn(def)|>prettify
quote
    function Foo(; x = 1)
        Foo(x)
    end
    nothing
end

source

#Expronicon.codegen_ast_kwfn_inferFunction.

julia
codegen_ast_kwfn_infer(def, name = nothing)

Generate the keyword function that infers the type.

source

#Expronicon.codegen_ast_kwfn_plainFunction.

julia
codegen_ast_kwfn_plain(def[, name = nothing])

Generate the plain keyword function that does not infer type variables. So that one can use the type conversions defined by constructors.

source

#Expronicon.codegen_ast_structMethod.

julia
codegen_ast_struct(def)

Generate pure Julia struct Expr from struct definition. This is equivalent to codegen_ast for JLStruct. See also codegen_ast.

Example

julia
julia> def = JLKwStruct(:(struct Foo
           x::Int=1
           
           Foo(x::Int) = new(x)
       end))
struct Foo
    x::Int = 1
end

julia> codegen_ast_struct(def)
:(struct Foo
      #= REPL[21]:2 =#
      x::Int
      Foo(x::Int) = begin
              #= REPL[21]:4 =#
              new(x)
          end
  end)

source

#Expronicon.codegen_ast_struct_bodyMethod.

julia
codegen_ast_struct_body(def)

Generate the struct body.

Example

julia
julia> def = JLStruct(:(struct Foo
           x::Int
           
           Foo(x::Int) = new(x)
       end))
struct Foo
    x::Int
end

julia> codegen_ast_struct_body(def)
quote
    #= REPL[15]:2 =#
    x::Int
    Foo(x::Int) = begin
            #= REPL[15]:4 =#
            new(x)
        end
end

source

#Expronicon.codegen_ast_struct_headMethod.

julia
codegen_ast_struct_head(def)

Generate the struct head.

Example

julia
julia> using Expronicon

julia> def = JLStruct(:(struct Foo{T} end))
struct Foo{T}
end

julia> codegen_ast_struct_head(def)
:(Foo{T})

julia> def = JLStruct(:(struct Foo{T} <: AbstractArray end))
struct Foo{T} <: AbstractArray
end

julia> codegen_ast_struct_head(def)
:(Foo{T} <: AbstractArray)

source

#Expronicon.struct_name_plainMethod.

julia
struct_name_plain(def)

Plain constructor name. See also struct_name_without_inferable.

Example

julia
julia> def = @expr JLKwStruct struct Foo{N, Inferable}
    x::Inferable = 1
end

julia> struct_name_plain(def)
:(Foo{N, Inferable})

source

#Expronicon.struct_name_without_inferableMethod.

julia
struct_name_without_inferable(def; leading_inferable::Bool=true)

Constructor name that assume some of the type variables is inferred. See also struct_name_plain. The kwarg leading_inferable can be used to configure whether to preserve the leading inferable type variables, the default is true to be consistent with the default julia constructors.

Example

julia
julia> def = @expr JLKwStruct struct Foo{N, Inferable}
    x::Inferable = 1
end

julia> struct_name_without_inferable(def)
:(Foo{N})

julia> def = @expr JLKwStruct struct Foo{Inferable, NotInferable}
    x::Inferable
end

julia> struct_name_without_inferable(def; leading_inferable=true)
:(Foo{Inferable, NotInferable})

julia> struct_name_without_inferable(def; leading_inferable=false)
:(Foo{NotInferable})

source

#Expronicon.xcallMethod.

julia
xcall(name, args...; kw...)

Create a function call to name.

source

#Expronicon.xcallMethod.

julia
xcall(m::Module, name::Symbol, args...; kw...)

Create a function call to GlobalRef(m, name).

!!! tip due to Revise/#616, to make your macro work with Revise, we use the dot expression Expr(:., <module>, QuoteNode(<name>)) instead of GlobalRef here.

source

#Expronicon.xfirstMethod.

julia
xfirst(collection)

Create a function call expression to Base.first.

source

#Expronicon.xgetindexMethod.

julia
xgetindex(collection, key...)

Create a function call expression to Base.getindex.

source

#Expronicon.xiterateMethod.

julia
xiterate(it, st)

Create a function call expression to Base.iterate.

source

#Expronicon.xiterateMethod.

julia
xiterate(it)

Create a function call expression to Base.iterate.

source

#Expronicon.xlastMethod.

julia
xlast(collection)

Create a function call expression to Base.last.

source

#Expronicon.xmapMethod.

julia
xmap(f, xs...)

Create a function call expression to Base.map.

source

#Expronicon.xmapreduceMethod.

julia
xmapreduce(f, op, xs...)

Create a function call expression to Base.mapreduce.

source

#Expronicon.xnamedtupleMethod.

julia
xnamedtuple(;kw...)

Create a NamedTuple expression.

source

#Expronicon.xprintMethod.

julia
xprint(xs...)

Create a function call expression to Base.print.

source

#Expronicon.xprintlnMethod.

julia
xprintln(xs...)

Create a function call expression to Base.println.

source

#Expronicon.xpushMethod.

julia
xpush(collection, items...)

Create a function call expression to Base.push!.

source

#Expronicon.xtupleMethod.

julia
xtuple(xs...)

Create a Tuple expression.

source

Printings

Pretty printing functions.

Algebra Data Type

Algebra data type

Released under the MIT License.