{! 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 %}