Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metaprogramming / use macros #5

Open
femtotrader opened this issue May 14, 2016 · 2 comments
Open

Metaprogramming / use macros #5

femtotrader opened this issue May 14, 2016 · 2 comments

Comments

@femtotrader
Copy link
Owner

femtotrader commented May 14, 2016

We might use macros instead of code generation using strings.

see http://docs.julialang.org/en/release-0.5/manual/metaprogramming/

http://stackoverflow.com/questions/37230071/metaprogramming-julia-functions-with-args-and-keyword-args/37230249#37230249

@femtotrader
Copy link
Owner Author

femtotrader commented May 15, 2016

(You) should return an expression from macros. To make code an expression, decorate your code with either :(....) or quote ... end. Also, $ is valid only for expressions and strings. Lastly, there is a hygiene issue with macros. In order to keep $funcname intact you need esc around it. Here is corrected code

julia> macro GEN_FUNC(funcname)  
           fname=esc(funcname)  
           quote  
               function $fname(a, b, x=1, y=2)  
                   return x  
               end  
           end  
       end  

julia> macroexpand(:(@GEN_FUNC testing))  
quote  # none, line 4:  
    function testing(#21#a,#22#b,#23#x=1,#24#y=2) # none, line 5:  
        return #23#x  
    end  
end

Update: Here is how myfunc can be manually constructed (Hint:I made it an expression with quote ... end and cheated from that)

julia> f_body=:(x+y)
:(x + y)

julia> f_parameters=Expr(:parameters, Expr(:kw,:x,Int64(1)), Expr(:kw,:y,Float64(2)))
:($(Expr(:parameters, :(x=1), :(y=2.0))))

julia> f_call=Expr(:call,:myfunc,f_parameters,:(a::Array{Float64,1}),:(b::Array{Float64,1}))
:(myfunc(a::Array{Float64,1},b::Array{Float64,1}; x=1,y=2.0))

julia> f_declare=Expr(:function,f_call,f_body)
:(function myfunc(a::Array{Float64,1},b::Array{Float64,1}; x=1,y=2.0)
        x + y
    end)

julia> eval(f_declare)
myfunc (generic function with 1 method)

julia> myfunc(2,3)
ERROR: MethodError: `myfunc` has no method matching myfunc(::Int64, ::Int64)

julia> myfunc([2.],[3.])
3.0

julia> myfunc([2.],[3.];x=4,y=8.)
12.0

@femtotrader femtotrader changed the title Use macros Metaprogramming / use macros Oct 3, 2016
@femtotrader
Copy link
Owner Author

femtotrader commented Oct 3, 2016

Example of @eval usage

https://github.com/JuliaComputing/ArrayFire.jl/blob/009838ffa6071d904d8622b1988ac69bf85ac349/src/signal.jl#L35

https://github.com/stevengj/DecFP.jl/blob/master/src/DecFP.jl

WIP

using TALib: get_dict_of_ta_func, d_typ_to_c
include("src/tools.jl")
using DataStructures: OrderedDict

d = get_dict_of_ta_func()
d_code = OrderedDict{Symbol,Expr}()

for (symb_func, func_info) in d
    s_doc_Index = ""
    s_doc_RequiredInputArguments = ""
    s_doc_OptionalInputArguments = ""
    s_doc_OutputArguments = ""

    params = String[]
    ctypes = String[]
    for arg = ["startIdx", "endIdx"]
        varname = uncamel(arg)
        vartyp = "Cint"
        push!(params, varname)
        push!(ctypes, vartyp)
        s_doc_Index *= "\n        - $arg::$vartyp"
    end

    for arg = func_info["RequiredInputArguments"]
        varname = replace_var(arg["Name"])
        vartyp = d_typ_to_c[arg["Type"]]
        push!(params, string(varname))
        push!(ctypes, string(vartyp))
        s_doc_RequiredInputArguments *= "\n        - $varname::$vartyp"
    end

    for arg = func_info["OptionalInputArguments"]
        varname = fix_varname(arg["Name"])
        vartyp = d_typ_to_c[arg["Type"]]
        push!(params, varname)
        push!(ctypes, string(vartyp))
        s_doc_OptionalInputArguments *= "\n        - $varname::$vartyp"
    end

    for arg = ["outBegIdx", "outNbElement"]
        varname = arg #uncamel(arg)
        push!(params, varname)
        push!(ctypes, "Ref{Cint}")
    end

    for arg = func_info["OutputArguments"]
        varname = arg["Name"]
        vartyp = d_typ_to_c[arg["Type"]]
        push!(params, varname)
        push!(ctypes, string(vartyp))
        s_doc_OutputArguments *= "\n        - $varname::$vartyp"
    end

    params = join(params, ", ")
    ctypes = join(ctypes, ", ")

    funcname = "_TA_" * string(symb_func)
    symb_func = Symbol(funcname)
    c_funcname = "TA_" * string(symb_func)
    ret_typ = "TA_RetCode"

    expression = quote
        """
            $($funcname)(start_idx, end_idx, price_open, price_high, price_low, price_close, outBegIdx, outNbElement, outInteger)

        Up/Down-gap side-by-side white lines (CdlGapSideSideWhite)

            Pattern Recognition

            Level: 0 - raw

        Arguments:

            Indexes:
                - startIdx::Cint
                - endIdx::Cint

            RequiredInputArguments:$($s_doc_RequiredInputArguments)

            OptionalInputArguments:$($s_doc_OptionalInputArguments)

            OutputArguments:$($s_doc_OutputArguments)

        Returns:
            ::$($ret_typ)
        """        
        function ($symb_func)()
            "..."
        end
    end
    d_code[symb_func] = expression  # save expression to d_code dictionary (to see generated source code)
    #eval(expression)
end


println(d_code)
println(repeat("=", 10))
println(d_code[:_TA_COS])

or

    @eval function ($funcname)()
        "..."
    end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant