119 lines
2.7 KiB
Text
119 lines
2.7 KiB
Text
|
{!
|
||
|
macro_prefix = '_'.join(namespaces).upper() + '_'
|
||
|
variant_name = root_node_name + 'Type'
|
||
|
!}
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
{% for namespace in namespaces %}
|
||
|
namespace {{namespace}} { {! indent() !}
|
||
|
{% endfor %}
|
||
|
|
||
|
class {{base_node.name}};
|
||
|
|
||
|
class {{root_node_name}} {
|
||
|
|
||
|
unsigned RefCount = 0;
|
||
|
|
||
|
{{root_node_name}}* Parent = nullptr;
|
||
|
|
||
|
public:
|
||
|
|
||
|
inline void ref() {
|
||
|
++RefCount;
|
||
|
}
|
||
|
|
||
|
inline void unref() {
|
||
|
--RefCount;
|
||
|
if (RefCount == 0) {
|
||
|
delete this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const {{variant_name}} Type;
|
||
|
|
||
|
inline {{root_node_name}}({{variant_name}}Type):
|
||
|
Type(Type) {}
|
||
|
|
||
|
{{base_node.name}}* get{{base_node.name}}();
|
||
|
|
||
|
virtual void setParents();
|
||
|
|
||
|
virtual ~Node();
|
||
|
|
||
|
};
|
||
|
|
||
|
{% for node in nodes %}
|
||
|
{!
|
||
|
|
||
|
def gen_cpp_ctor_params(out, node):
|
||
|
visited = set()
|
||
|
queue = deque([ node ])
|
||
|
is_leaf = not graph.has_children(node.name)
|
||
|
first = True
|
||
|
if not is_leaf:
|
||
|
out.write(f"{cpp_root_node_name}Type Type")
|
||
|
first = False
|
||
|
while queue:
|
||
|
node = queue.popleft()
|
||
|
if node.name in visited:
|
||
|
return
|
||
|
visited.add(node.name)
|
||
|
for member in node.members:
|
||
|
if first:
|
||
|
first = False
|
||
|
else:
|
||
|
out.write(', ')
|
||
|
out.write(gen_cpp_type_expr(member.type_expr.type))
|
||
|
out.write(' ')
|
||
|
out.write(camel_case(member.name))
|
||
|
for parent in node.parents:
|
||
|
queue.append(types[parent])
|
||
|
|
||
|
def gen_cpp_ctor_args(out, orig_node: NodeDecl):
|
||
|
first = True
|
||
|
is_leaf = not graph.has_children(orig_node.name)
|
||
|
if orig_node.parents:
|
||
|
for parent in orig_node.parents:
|
||
|
if first:
|
||
|
first = False
|
||
|
else:
|
||
|
out.write(', ')
|
||
|
node = types[parent]
|
||
|
refs = ''
|
||
|
if is_leaf:
|
||
|
refs += f"{cpp_root_node_name}Type::{orig_node.name}"
|
||
|
else:
|
||
|
refs += 'Type'
|
||
|
for member in node.members:
|
||
|
refs += f", {camel_case(member.name)}"
|
||
|
out.write(f"{prefix}{node.name}({refs})")
|
||
|
else:
|
||
|
if is_leaf:
|
||
|
out.write(f"{cpp_root_node_name}({cpp_root_node_name}Type::{orig_node.name})")
|
||
|
else:
|
||
|
out.write(f"{cpp_root_node_name}(Type)")
|
||
|
first = False
|
||
|
for member in orig_node.members:
|
||
|
if first:
|
||
|
first = False
|
||
|
else:
|
||
|
out.write(', ')
|
||
|
out.write(f"{camel_case(member.name)}({camel_case(member.name)})")
|
||
|
|
||
|
!}
|
||
|
class {{node.name}} : public {{node.parent.name}} {
|
||
|
|
||
|
{{node.name}}(
|
||
|
{{cpp_ctor_params}}
|
||
|
): {{node.parent.name}}({{variant_name}}::{{node.name}}{{cpp_ctor_args}} {}
|
||
|
|
||
|
~{{node.name}}();
|
||
|
};
|
||
|
{% endfor %}
|
||
|
|
||
|
{% for namespace in namespaces %}
|
||
|
} {! dedent() !}
|
||
|
{% endfor %}
|
||
|
|