<commit_before>#include <yuni/yuni.h>
#include "details/pass/build-ast-to-ir/scope.h"
#include "details/ast/ast.h"
#include "details/grammar/nany.h"

using namespace Yuni;




namespace Nany
{
namespace IR
{
namespace Producer
{


	bool Scope::visitASTExprObject(AST::Node& node, LVID& localvar)
	{
		assert(node.rule == AST::rgObject);
		// Converting the object into an anonymous class
		//
		// expr-group
		// |   expr-value
		// |       new
		// |           type-decl
		// |               class
		// |                   class-body [reuse]
		// |                       expr
		// |                       |   expr-value
		// |                       |       var (+3)
		// |                       |           var-by-value
		// |                       |           identifier: x
		// |                       |           var-property
		// |                       |               expr
		// |                       |                  ...
		// |                       expr
		// |                       |   expr-value
		// |                       |       function (+3)
		// |                       |           function-kind
		// |                       |           |   function-kind-function (+2)
		// |                       |           |       tk-func
		// |                       |           |       symbol-name
		// |                       |           |           identifier: foo
		// |                       |           func-params (+2)
		// |                       |           |   tk-parenthese-open, (
		// |                       |           |   tk-parenthese-close, )
		// |                       |           func-body
		// |                       |               return-inline
		// |                       |                  ...

		if (!context.reuse.object.node)
			context.prepareReuseForAnonymObjects();
		auto& classbody = *context.reuse.object.classbody;

		for (auto& child: node.children)
		{
			switch (child.rule)
			{
				case AST::rgObjectEntry:
				{
					AST::Node* identifier = nullptr;
					AST::Node* expr = nullptr;
					for (auto& entry: child.children)
					{
						switch (entry.rule)
						{
							case AST::rgIdentifier: identifier = &entry; break;
							case AST::rgExpr: expr = &entry; break;
							default: return unexpectedNode(entry, "[ir/object/entry]");
						}
					}
					assert(identifier != nullptr); // invalid ast
					assert(expr != nullptr);

					auto& grandChild = expr->firstChild().firstChild();
					bool isFunc = grandChild.rule == AST::rgFunction;

					if (not isFunc)
					{
						AST::Node::Ptr var = new AST::Node{AST::rgVar};
						var->append(AST::rgVarByValue);
						var->children.push_back(identifier);
						(var->append(AST::rgVarProperty)).children.push_back(expr);
						classbody.children.push_back(var);
					}
					else
					{
						bool found = not grandChild.each(AST::rgFunctionKind, [&](AST::Node& subnode) -> bool
						{
							subnode.each(AST::rgFunctionKindFunction, [&](AST::Node& kind) -> bool {
								kind.children.clear();
								kind.append(AST::rgSymbolName).children.push_back(identifier);
								found = true;
								return false;
							});
							return false;
						});
						if (found)
							classbody.children.push_back(&grandChild);
						else
							error(child) << "failed to update function name";
					}
					break;
				}
				default:
					return unexpectedNode(child, "[ir/object]");
			}
		}

		bool success = visitASTExpr(*context.reuse.object.node, localvar);

		classbody.clear();
		return success;
	}




} // namespace Producer
} // namespace IR
} // namespace Nany<commit_msg>ast2ir: fix invalid tree cleanup<commit_after>#include <yuni/yuni.h>
#include "details/pass/build-ast-to-ir/scope.h"
#include "details/ast/ast.h"
#include "details/grammar/nany.h"

using namespace Yuni;




namespace Nany
{
namespace IR
{
namespace Producer
{


	bool Scope::visitASTExprObject(AST::Node& node, LVID& localvar)
	{
		assert(node.rule == AST::rgObject);
		// Converting the object into an anonymous class
		//
		// expr-group
		// |   expr-value
		// |       new
		// |           type-decl
		// |               class
		// |                   class-body [reuse]
		// |                       expr
		// |                       |   expr-value
		// |                       |       var (+3)
		// |                       |           var-by-value
		// |                       |           identifier: x
		// |                       |           var-property
		// |                       |               expr
		// |                       |                  ...
		// |                       expr
		// |                       |   expr-value
		// |                       |       function (+3)
		// |                       |           function-kind
		// |                       |           |   function-kind-function (+2)
		// |                       |           |       tk-func
		// |                       |           |       symbol-name
		// |                       |           |           identifier: foo
		// |                       |           func-params (+2)
		// |                       |           |   tk-parenthese-open, (
		// |                       |           |   tk-parenthese-close, )
		// |                       |           func-body
		// |                       |               return-inline
		// |                       |                  ...

		if (!context.reuse.object.node)
			context.prepareReuseForAnonymObjects();
		auto& classbody = *context.reuse.object.classbody;

		for (auto& child: node.children)
		{
			switch (child.rule)
			{
				case AST::rgObjectEntry:
				{
					AST::Node* identifier = nullptr;
					AST::Node* expr = nullptr;
					for (auto& entry: child.children)
					{
						switch (entry.rule)
						{
							case AST::rgIdentifier: identifier = &entry; break;
							case AST::rgExpr: expr = &entry; break;
							default: return unexpectedNode(entry, "[ir/object/entry]");
						}
					}
					assert(identifier != nullptr); // invalid ast
					assert(expr != nullptr);

					auto& grandChild = expr->firstChild().firstChild();
					bool isFunc = grandChild.rule == AST::rgFunction;

					if (not isFunc)
					{
						AST::Node::Ptr var = new AST::Node{AST::rgVar};
						var->append(AST::rgVarByValue);
						var->children.push_back(identifier);
						(var->append(AST::rgVarProperty)).children.push_back(expr);
						classbody.children.push_back(var);
					}
					else
					{
						bool found = not grandChild.each(AST::rgFunctionKind, [&](AST::Node& subnode) -> bool
						{
							subnode.each(AST::rgFunctionKindFunction, [&](AST::Node& kind) -> bool {
								kind.children.clear();
								kind.append(AST::rgSymbolName).children.push_back(identifier);
								found = true;
								return false;
							});
							return false;
						});
						if (found)
							classbody.children.push_back(&grandChild);
						else
							error(child) << "failed to update function name";
					}
					break;
				}
				default:
					return unexpectedNode(child, "[ir/object]");
			}
		}

		bool success = visitASTExpr(*context.reuse.object.node, localvar);
		classbody.children.clear();
		return success;
	}




} // namespace Producer
} // namespace IR
} // namespace Nany
{'fraction_non_alphanumeric': 0.1334630891144168, 'fraction_numerical': 0.0012512164604476575, 'mean_word_length': 1.2474226804123711, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 46, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '258958', 'n_tokens_mistral': 2629, 'n_tokens_neox': 1995, 'n_words': 355}