Skip to content
Snippets Groups Projects
Commit ab698d68 authored by xo30xoqa's avatar xo30xoqa
Browse files

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 :-)
parent 28253044
No related branches found
No related tags found
No related merge requests found
...@@ -3,33 +3,33 @@ ...@@ -3,33 +3,33 @@
### This file implements the macros needed for the species DSL. ### 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() ##TODO replace the current registerspecies()
function registerspecies(speciesdict) 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 end
##TODO docstring
macro species(name, body) macro species(name, body)
speciesdict = gensym() speciesfun = gensym()
quote quote
$speciesdict = Dict{String, Any}("name"=>string($(QuoteNode(name)))) Core.@__doc__ $speciesfun = function()
for line in $(body.args) $(esc(:name)) = string($(QuoteNode(name)))
(typeof(line) == LineNumberNode) && continue $(esc(body))
if line.head == :macrocall return Base.@locals
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
end end
registerspecies($speciesdict) registerspecies($speciesfun())
end end
end end
##TODO docstring
macro phase(name, body) macro phase(name, body)
#:($(esc(name)) = function() $body end) #for testing
:($(esc(name)) = function(animal::Animal, model::AgentBasedModel) $body end) :($(esc(name)) = function(animal::Animal, model::AgentBasedModel) $body end)
#:($(esc(name)) = function() $body end) #for testing
end end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment