From ab698d680cf8ea1974ba30756c9fe2f7af56b20d Mon Sep 17 00:00:00 2001 From: Daniel Vedder <daniel.vedder@idiv.de> Date: Wed, 14 Dec 2022 23:59:27 +0100 Subject: [PATCH] Rewrote @species The first version generally did what it was supposed to, but was overly complicated and brittle, because it basically did its own parsing. This version simply wraps the user code in a function and uses @locals to access the ready-parsed variables. This is not only much cleaner, but also gives the user more of what he expects (e.g. the ability to reference previously defined variables). I had actually tried this approach before, but only got it to work once I understood how @locals works under the hood, plus a lot of other Julia internals. So I now not only have more elegant code, I also learnt quite a bit - a good win :-) --- src/nature/species.jl | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/nature/species.jl b/src/nature/species.jl index 433fe31..9cef463 100644 --- a/src/nature/species.jl +++ b/src/nature/species.jl @@ -3,33 +3,33 @@ ### This file implements the macros needed for the species DSL. ### -#TODO configure species traits via a separate TOML file +#XXX configure species traits via a separate TOML file? ##TODO replace the current registerspecies() function registerspecies(speciesdict) - speciesdict["testphase"]() + println(speciesdict) + processeddict = Dict{String,Any}() + for k in keys(speciesdict) + processeddict[string(k)] = speciesdict[k] + end + processeddict["testphase"]() end +##TODO docstring macro species(name, body) - speciesdict = gensym() + speciesfun = gensym() quote - $speciesdict = Dict{String, Any}("name"=>string($(QuoteNode(name)))) - for line in $(body.args) - (typeof(line) == LineNumberNode) && continue - if line.head == :macrocall - line = macroexpand($(__module__), line) - line.args[2] = Core.eval($(__module__), line.args[2]) - end - if line.head == :(=) - $speciesdict[string(line.args[1])] = line.args[2] - end + Core.@__doc__ $speciesfun = function() + $(esc(:name)) = string($(QuoteNode(name))) + $(esc(body)) + return Base.@locals end - registerspecies($speciesdict) + registerspecies($speciesfun()) end end +##TODO docstring macro phase(name, body) - #:($(esc(name)) = function() $body end) #for testing :($(esc(name)) = function(animal::Animal, model::AgentBasedModel) $body end) + #:($(esc(name)) = function() $body end) #for testing end - -- GitLab