Add a script that emits a JSON representation of wasm-delegations-fields.def
This is simple to do after #6465 which converted the .def file into a very parse-able format.
The emitted JSON file contains things like
{
id: 'Loop',
fields: [
{
form: 'CHILD',
name: 'body',
},
{
form: 'SCOPE_NAME_DEF',
name: 'name',
},
]
},
Full output: https://gist.github.com/kripken/2e7f681ff7878a6e06bb721327328623
May fix #6460 if this looks like the right style of output. Happy to make changes.
Thanks @kripken! I want to loop in @peblair since he was working to automate the Grain bindings and this might be helpful to him.
Instead of a python script, what if we had a small C++ executable that could emit the JSON? That way we wouldn't be in the business of having to parse the .def file ourselves.
@tlively what do you see as the benefit of not parsing the .def file ourselves? I think the code here shows that doing so is trivial. It's less work than writing C++ that does the same, I think :smile:
For your consideration:
void emitHeader() { std::cout << "[\n"; }
void emitClassStart(std::string name) {
std::cout << " {\n";
std::cout << " id: '" << name << "',\n";
std::cout << " fields: [\n";
}
void emitField(std::string form, std::string name) {
std::cout << " {\n";
std::cout << " form: '" << form << "',\n";
std::cout << " name: '" << name << "',\n";
std::cout << " },\n";
}
void emitClassEnd() {
std::cout << " ]\n";
std::cout << " },\n";
}
void emitFooter() { std::cout << "]\n"; }
void emitJSON() {
#define DELEGATE_FIELD_MAIN_START emitHeader();
#define DELEGATE_FIELD_CASE_START(id) emitClassStart(#id);
#define DELEGATE_FIELD_CHILD(id, field) emitField("CHILD", #field);
#define DELEGATE_FIELD_CHILD_VECTOR(id, field) \
emitField("CHILD_VECTOR", #field);
#define DELEGATE_FIELD_INT(id, field) emitField("INT", #field);
#define DELEGATE_FIELD_INT_ARRAY(id, field) emitField("INT_ARRAY", #field);
#define DELEGATE_FIELD_INT_VECTOR(id, field) emitField("INT_VECTOR", #field);
#define DELEGATE_FIELD_LITERAL(id, field) emitField("LITERAL", #field);
#define DELEGATE_FIELD_NAME(id, field) emitField("NAME", #field);
#define DELEGATE_FIELD_NAME_VECTOR(id, field) emitField("NAME_VECTOR", #field);
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) \
emitField("SCOPE_NAME_DEF", #field);
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) \
emitField("SCOPE_NAME_USE", #field);
#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) \
emitField("SCOPE_NAME_USE_VECTOR", #field);
#define DELEGATE_FIELD_TYPE(id, field) emitField("TYPE", #field);
#define DELEGATE_FIELD_TYPE_VECTOR(id, field) emitField("TYPE_VECTOR", #field);
#define DELEGATE_FIELD_HEAPTYPE(id, field) emitField("HEAPTYPE", #field);
#define DELEGATE_FIELD_ADDRESS(id, field) emitField("ADDRESS", #field);
#define DELEGATE_FIELD_CASE_END(name) emitClassEnd();
#define DELEGATE_FIELD_MAIN_END emitFooter();
#include "wasm-delegations-fields.def"
}
Thanks!
That looks like 53 lines. The Python here is only 49 lines after removing the large comment at the top of the file that explains the JSON format, or only 38 if you remove all comments to match your C++. Also, the C++ would need to define a new executable to be run, or at least a new pass or something like that, which would also add to the size.
So the Python seems smaller and simpler to me - am I looking at this wrong somehow?
The python may be shorter, but the cognitive overhead of all the string munging makes it much more complex than the C++ IMO. If it weren't for the comment at the top of the python script, it would be very difficult to figure out what it would emit just by reading the code. In contrast, it's immediately clear what the C++ code will emit.