Search code examples
macrosjuliasyntax-errormetaprogramming

error: "struct" expression not at top level


function check(str,arg;type=DataType,max=nothing,min=nothing,description="")
    @argcheck typeof(arg)==type
    @argcheck arg>min
    @argcheck arg<max
    @argcheck typeof(description)==String
   return arg
end


 function constr(name,arg,field)
        return :(function $name($arg,$field)
            new(check($name,$arg,$field))
        end)
    end
    
macro creatStruct(name,arg)
   code = Base.remove_linenums!(quote
     struct $name
        end
     end)
     print(arg)
   append!(code.args[1].args[3].args,[constr(name,arg.args[1].args[1],arg.args[1].args[2])])
   code 
end 

macro myStruct(name,arg)
    @creatStruct name arg
  end 





@myStruct test12 (
  (arg1,(max=10))
)

In my code above I'm trying to build a macro that Creates a struct, and within the struct, you can define an argument with boundaries (max, min) and description, etc. I'm getting this error: syntax: "#141#max = 10" is not a valid function argument name

and every time I'm trying to solve it, I get another error like: LoadError: syntax: "struct" expression not at top level

So, I think my Code/Approach is not that cohesive. Anybody can suggest tips and/or another Approche.


Solution

    1. You're attempting to make an argument name max with a default value of 10. The error is about max=10 not being a valid name (Symbol), while max is. The bigger issue is you're trying to put this in the struct expression instead of a constructor method:
    struct Foo
      bar::Float64
      max::Int64
    end
    
    # constructor
    Foo(bar, max=10) = Foo(bar, max)
    

    So you have to figure out how to make an expression for a method with default values, too.

    1. Your second error means that structs must be defined in the top-level. "Top-level" is like global scope but stricter in some contexts; I don't know the exact difference, but it definitely excludes local scopes (macro, function, etc). It looks like the issue is the expression returned by creatStruct being evaluated as code in myStruct, but the LoadError I'm getting has a different message. In any case, the error goes away if I make sure things stay as expressions:
    macro myStruct(name,arg)
        :(@creatStruct $name $arg)
    end