Skip to content

Instantly share code, notes, and snippets.

@zmaril
Last active December 23, 2015 22:19

Revisions

  1. zmaril revised this gist Sep 25, 2013. 2 changed files with 14 additions and 15 deletions.
    14 changes: 14 additions & 0 deletions intro.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    I've been messing around with macro compilation and embedded languages in Julia. This is a reverse polish notation compiler built into a macro. Be forewarned, I don't really know julia or how to build a compiler.

    I wanted the compiler to leak, so I could pull in environmental variables.
    `a=1; rpn"a 1 +" #Totally valid and should be 2`

    I wanted the compiler to be able to take in information about the number of arguments to a function.
    N!f tells the compiler what to do. The default for N is 2.
    `rpn"1 2 3 3!+" # should be 6`

    Thanks to being a compiler that is porous (unhygenic?), this means that all the power of julia is available to you, the reverse polish notation programmer.
    `rpn"100 20 fill 1!sum"`
    `rpn"1 2 1 logspace 1!mean"`

    If you are so inclined, you could use DArray with some complex entries to do distributed, complex reverse polish notation computing!
    15 changes: 0 additions & 15 deletions rpn.jl
    Original file line number Diff line number Diff line change
    @@ -1,18 +1,3 @@
    #Messing around with macro compilation and embedded languages in Julia.
    #Below is a reverse polish notation compiler built into a macro.
    #Be forewarned, I don't know julia or how to build a compiler.
    #I wanted the compiler to leak, so I could pull in environmental variables.
    # a=1; rpn"a 1 +" #Totally valid and should be 2
    #I wanted the compiler to be able to take in information about the number of arguments to a function.
    # N!f tells the compiler what to do. The default for N is 2.
    #rpn"1 2 3 3!+" # should be 6
    #Thanks to being a compiler that is porous (unhygenic?), this means that all the power of julia is available.
    #So here is a sum of an array
    #rpn"100 20 fill 1!sum"
    #Finding the average of a logspace
    #rpn"1 2 1 logspace 1!mean"
    #If you are so inclined, you could use DArray with some complex entries to do distributed, complex reverse polish notation computing!

    debug = false
    function tokenize(code)
    tokens = Any[]
  2. zmaril created this gist Sep 25, 2013.
    101 changes: 101 additions & 0 deletions rpn.jl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,101 @@
    #Messing around with macro compilation and embedded languages in Julia.
    #Below is a reverse polish notation compiler built into a macro.
    #Be forewarned, I don't know julia or how to build a compiler.
    #I wanted the compiler to leak, so I could pull in environmental variables.
    # a=1; rpn"a 1 +" #Totally valid and should be 2
    #I wanted the compiler to be able to take in information about the number of arguments to a function.
    # N!f tells the compiler what to do. The default for N is 2.
    #rpn"1 2 3 3!+" # should be 6
    #Thanks to being a compiler that is porous (unhygenic?), this means that all the power of julia is available.
    #So here is a sum of an array
    #rpn"100 20 fill 1!sum"
    #Finding the average of a logspace
    #rpn"1 2 1 logspace 1!mean"
    #If you are so inclined, you could use DArray with some complex entries to do distributed, complex reverse polish notation computing!

    debug = false
    function tokenize(code)
    tokens = Any[]
    for x in split(code," ")
    m = match(r"(\d+)!(.+)",x)
    if m == nothing
    push!(tokens,parse(x))
    else
    numargs, f = m.captures
    push!(tokens,(parse(convert(UTF8String,numargs)),parse(convert(UTF8String,f))))
    end
    end
    return tokens
    end
    macro rpn_str(code)
    tokens = tokenize(code)
    exprs = Any[:block]
    stack = Any[]
    index = 1
    while tokens != []
    token=shift!(tokens)
    evaled = try eval(token) catch e token end
    if debug
    print("TOKEN\n")
    show(token)
    print(" ")
    show(evaled)
    print(" ")
    show(index)
    print(" ")
    show(exprs)
    print(" ")
    show(stack)
    print("\n")
    end

    if typeof(evaled) == Function
    evaled = (2,token)
    end

    if typeof(evaled) <: (Number,Symbol)
    fargs = reverse([pop!(stack) for i in 1:evaled[1]])
    f = evaled[2]
    tmp = symbol("tmp$(index)")
    fcall = Expr(:call)
    fcall.args =unshift!(fargs,f)
    assignment = Expr(:(=))
    assignment.args = [tmp,fcall]
    push!(exprs,assignment)
    push!(stack,tmp)
    index += 1
    else
    push!(stack,evaled)
    end
    end
    push!(exprs,pop!(stack))

    if debug
    print("EXITED\n")
    show(index)
    print(" ")
    show(exprs)
    print(" ")
    show(stack)
    print("\n")
    end

    return apply(Expr,exprs)
    end

    rpn_a = 10
    rpn_b = 20
    rpn_c = [1 2 3]
    print(rpn"1","\n")
    print(rpn"1 2 +","\n")
    print(rpn"1 rpn_a +","\n")
    print(rpn"1 2 + 4 *","\n")
    show(rpn"rpn_c rpn_c +")
    print("\n")
    print(rpn"1 2.5 3 3!+","\n")
    print(rpn"1 2.5 1+2im 3!+","\n")

    function test_compilation(x,y)
    return rpn"x y 1+2im 3!+"
    end
    test_compilation(1,2)