L
Luke Graham
Hi list,
I was wondering if anyone would have some insight into a problem Ive got.
Im taking an xml document (looks very much like a w3c schema with some
extra attributes) and transforming it into c++ code. The method I use looks
something like...
def recurse(file, func, element)
case func
when "declare"
file << element.attributes["type"] << element.attributes["name"]
when "instantiate"
file << element.attributes["name"] << " = new " << element.attributes["type"]
do wierd stuff based on type and state
end
element.each_child { |c|
recurse file, func, c
}
end
headerfile << "some template"
doc.each_child { |c|
recurse headerfile, "declare", c
}
headerfile << "some more template"
cppfile << "some template"
doc.each_child { |c|
recurse cppfile, "instantiate", c
}
cppfile << "some more template"
(I know doc can only have one child but I use the xpath bit of rexml,
like doc.elements.each("/*/foo"), just couldnt be bothered typing it)
Needless to say, recurse is now ~500 lines, and has more than a few
oddities like a begin-ensure block, special cases that dont recurse,
about 4 places where it calls itself, some of which dont use the
same function they were passed, lots of places that do strange things
to the state and so on.
Id like to get the logic out of the recurse statement for three reasons.
First of all, Im starting recurse up more times than Ive shown
above, because I have four separate sets of header/cpp templates,
not to mention I would like to add other templates that arent c++ code.
It would be good to know that each case could be handled safely
without interfering with each others output and special cases.
Secondly, someone else would like to write their own templated
code, and their required output would be different. Thirdly, recurse is
simply becoming scary.
Can anyone suggest a good way to get the c++-producing code out
of recurse and into some sort of template language, or into functions
that get passed into simplified recurse? I figured those functions
would need to return functions (usually themselves) to simulate
some state changes, ala...
def recurse(file, func, element)
file << func.call "pre", element
element.each_child { |c|
recurse file, func.call("getfunc",element), c
}
file << func.call "post", element
end
Or would I be better doing this...
def sampleDeclare(file, element)
...
end
def startDeclare(file, element)
file << "pre declare"
element.each_child { |c|
sampleDeclare.call file, c # choose different funcs based on state
}
file << "post declare"
end
startDeclare headerfile, doc.root
I think that dragging state around might get hard after a while tho and
the recursion would be specified many times.
Sorry for the long post and thanks for reading this far!
I was wondering if anyone would have some insight into a problem Ive got.
Im taking an xml document (looks very much like a w3c schema with some
extra attributes) and transforming it into c++ code. The method I use looks
something like...
def recurse(file, func, element)
case func
when "declare"
file << element.attributes["type"] << element.attributes["name"]
when "instantiate"
file << element.attributes["name"] << " = new " << element.attributes["type"]
do wierd stuff based on type and state
end
element.each_child { |c|
recurse file, func, c
}
end
headerfile << "some template"
doc.each_child { |c|
recurse headerfile, "declare", c
}
headerfile << "some more template"
cppfile << "some template"
doc.each_child { |c|
recurse cppfile, "instantiate", c
}
cppfile << "some more template"
(I know doc can only have one child but I use the xpath bit of rexml,
like doc.elements.each("/*/foo"), just couldnt be bothered typing it)
Needless to say, recurse is now ~500 lines, and has more than a few
oddities like a begin-ensure block, special cases that dont recurse,
about 4 places where it calls itself, some of which dont use the
same function they were passed, lots of places that do strange things
to the state and so on.
Id like to get the logic out of the recurse statement for three reasons.
First of all, Im starting recurse up more times than Ive shown
above, because I have four separate sets of header/cpp templates,
not to mention I would like to add other templates that arent c++ code.
It would be good to know that each case could be handled safely
without interfering with each others output and special cases.
Secondly, someone else would like to write their own templated
code, and their required output would be different. Thirdly, recurse is
simply becoming scary.
Can anyone suggest a good way to get the c++-producing code out
of recurse and into some sort of template language, or into functions
that get passed into simplified recurse? I figured those functions
would need to return functions (usually themselves) to simulate
some state changes, ala...
def recurse(file, func, element)
file << func.call "pre", element
element.each_child { |c|
recurse file, func.call("getfunc",element), c
}
file << func.call "post", element
end
Or would I be better doing this...
def sampleDeclare(file, element)
...
end
def startDeclare(file, element)
file << "pre declare"
element.each_child { |c|
sampleDeclare.call file, c # choose different funcs based on state
}
file << "post declare"
end
startDeclare headerfile, doc.root
I think that dragging state around might get hard after a while tho and
the recursion would be specified many times.
Sorry for the long post and thanks for reading this far!