diff --git a/src/nature/nature.jl b/src/nature/nature.jl
index 3d6db6f2beb347436624ec460f6dd0636173e072..6610e6206f6160355224d78174f038e4bd7d75eb 100644
--- a/src/nature/nature.jl
+++ b/src/nature/nature.jl
@@ -18,6 +18,7 @@ struct Species
     update!::Function # takes two arguments: animal, model
     traits::Dict{String,Any} # a collection of species-specific traits
 end
+#TODO convert species into dicts
 
 """
     Animal
@@ -35,6 +36,7 @@ end
 
 # This dict stores the definitions for all species that can be simulated.
 # (The definitions are created in separate files and registered here.)
+##TODO this needs to be rewritten to deal with the new @species macro
 let specieslist = Dict{String, Species}()
     """
         registerspecies(species)
diff --git a/src/nature/species.jl b/src/nature/species.jl
new file mode 100644
index 0000000000000000000000000000000000000000..433fe3124c1423c67196f8496beed69dc6ee35da
--- /dev/null
+++ b/src/nature/species.jl
@@ -0,0 +1,35 @@
+### Persephone - a socio-economic-ecological model of European agricultural landscapes.
+###
+### This file implements the macros needed for the species DSL.
+###
+
+#TODO configure species traits via a separate TOML file
+
+##TODO replace the current registerspecies()
+function registerspecies(speciesdict)
+    speciesdict["testphase"]()
+end
+
+macro species(name, body)
+    speciesdict = 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
+        end
+        registerspecies($speciesdict)
+    end
+end
+
+macro phase(name, body)
+    #:($(esc(name)) = function() $body end) #for testing
+    :($(esc(name)) = function(animal::Animal, model::AgentBasedModel) $body end)
+end
+
diff --git a/src/nature/species/skylark.jl b/src/nature/species/skylark.jl
new file mode 100644
index 0000000000000000000000000000000000000000..9a478c8d769fe54b97b0da0e1cadcf79b7d93d2d
--- /dev/null
+++ b/src/nature/species/skylark.jl
@@ -0,0 +1,28 @@
+### Persephone - a socio-economic-ecological model of European agricultural landscapes.
+###
+### This file holds the code for the Eurasian Skylark (Alauda arvensis).
+###
+
+##XXX At the moment, this is just a skeleton to show what I want to be able to interpret
+## with the @species and @phase macros
+
+@species Skylark begin
+
+    lifeexpectancy = 365*5
+    phase = "egg"
+    
+    @phase egg begin
+        if !parentsalive(animal)
+            killanimal(animal)
+        end
+        if animal.age == 14
+            changephase("nestling")
+        end
+    end
+
+    @phase nestling begin
+        #TODO
+    end
+
+    #TODO
+end