<commit_before>package ingraph.relalg2tex.converters.elementconverters

import ingraph.relalg2tex.constants.RelNullConstants
import relalg.AbstractEdgeVariable
import relalg.ArithmeticComparisonExpression
import relalg.AttributeVariable
import relalg.BigIntegerLiteral
import relalg.BinaryArithmeticOperationExpression
import relalg.BinaryLogicalExpression
import relalg.BooleanLiteral
import relalg.Direction
import relalg.DoubleLiteral
import relalg.ElementVariable
import relalg.EmptyListExpression
import relalg.Expression
import relalg.ExpressionVariable
import relalg.FunctionExpression
import relalg.IntegerLiteral
import relalg.ListExpression
import relalg.NavigationDescriptor
import relalg.NullLiteral
import relalg.Parameter
import relalg.ParameterComparableExpression
import relalg.StringLiteral
import relalg.UnaryGraphObjectLogicalExpression
import relalg.UnaryLogicalExpression
import relalg.VariableExpression
import relalg.VertexVariable

class ExpressionConverter {
	
	extension StringEscaper stringEscaper = new StringEscaper
	extension ExpressionOperatorTypeConverter operatorConverter = new ExpressionOperatorTypeConverter
	extension ElementConverter elementConverter = new ElementConverter


	/**
	 * In case of VariableExpression wrapping a VertexVariable or AbstractEdgeVariable,
	 * labelset constraints will also be serialized.
	 *
	 * Otherwise, it falls back to convertExpression.
	 */
	def CharSequence convertExpressionWithLabelSet(Expression exp) {
		// Note: this is not a nice, expression-based Xtend code.
		// It's more like a Java procedural code because of the return's
		if (exp instanceof VariableExpression) {
			val v = exp.variable
			if (v instanceof VertexVariable) {
				return '''\nodevariable{«v.escapedName»}{«convertVertexLabelSet(v.vertexLabelSet)»}'''
			} else if (v instanceof AbstractEdgeVariable) {
				return '''\edgevariable{«v.escapedName»}{«convertEdgeLabelSet(v.edgeLabelSet)»}'''
			}
		}

		return convertExpression(exp)
	}

	def dispatch CharSequence convertExpression(IntegerLiteral integerLiteral) {
		'''\literal{«integerLiteral.value»}'''
	}
	
	def dispatch CharSequence convertExpression(BigIntegerLiteral bigintegerLiteral)	{
		'''\literal{«bigintegerLiteral.value»}'''
	}
	
	def dispatch CharSequence convertExpression(DoubleLiteral doubleLiteral) {
		'''\literal{«doubleLiteral.value»}'''
	}

	def dispatch CharSequence convertExpression(StringLiteral stringLiteral) {
		'''\literal{"«stringLiteral.value.escape»"}'''
	}

	def dispatch CharSequence convertExpression(Parameter parameter) {
		'''\var{\$«parameter.name»}'''
	}

	def dispatch CharSequence convertExpression(ParameterComparableExpression pce) {
		'''«convertExpression(pce.parameter)»'''
	}

	def dispatch CharSequence convertExpression(ElementVariable elementVariable) {
		'''\var{«elementVariable.escapedName»}'''
	}

	def dispatch CharSequence convertExpression(AttributeVariable attributeVariable) {
		'''\var{«IF attributeVariable.element !== null»«attributeVariable.element.escapedName»«ELSE»«attributeVariable.expVar.escapedName»«ENDIF».«attributeVariable.escapedName»}'''
	}

	def dispatch CharSequence convertExpression(ExpressionVariable expVariable) {
		if (expVariable.hasInferredName) {
			convertExpression(expVariable.expression)
		} else {
			'''\var{«expVariable.escapedName»}'''
		}
	}
	
	def dispatch CharSequence convertExpression(VariableExpression ve) {
		convertExpression(ve.variable)
	}

	def dispatch CharSequence convertExpression(FunctionExpression fe) {
		'''\literal{«fe.functor.toString.escape»} \left( «fe.arguments.map[convertExpression].join(", ")» \right)'''
	}

	def dispatch CharSequence convertExpression(EmptyListExpression fe) {
		'''\left[ \right]'''
	}
<commit_msg>Do not add extra parentheses for count(*) function<commit_after>package ingraph.relalg2tex.converters.elementconverters

import ingraph.relalg2tex.constants.RelNullConstants
import relalg.AbstractEdgeVariable
import relalg.ArithmeticComparisonExpression
import relalg.AttributeVariable
import relalg.BigIntegerLiteral
import relalg.BinaryArithmeticOperationExpression
import relalg.BinaryLogicalExpression
import relalg.BooleanLiteral
import relalg.Direction
import relalg.DoubleLiteral
import relalg.ElementVariable
import relalg.EmptyListExpression
import relalg.Expression
import relalg.ExpressionVariable
import relalg.FunctionExpression
import relalg.IntegerLiteral
import relalg.ListExpression
import relalg.NavigationDescriptor
import relalg.NullLiteral
import relalg.Parameter
import relalg.ParameterComparableExpression
import relalg.StringLiteral
import relalg.UnaryGraphObjectLogicalExpression
import relalg.UnaryLogicalExpression
import relalg.VariableExpression
import relalg.VertexVariable

class ExpressionConverter {
	
	extension StringEscaper stringEscaper = new StringEscaper
	extension ExpressionOperatorTypeConverter operatorConverter = new ExpressionOperatorTypeConverter
	extension ElementConverter elementConverter = new ElementConverter


	/**
	 * In case of VariableExpression wrapping a VertexVariable or AbstractEdgeVariable,
	 * labelset constraints will also be serialized.
	 *
	 * Otherwise, it falls back to convertExpression.
	 */
	def CharSequence convertExpressionWithLabelSet(Expression exp) {
		// Note: this is not a nice, expression-based Xtend code.
		// It's more like a Java procedural code because of the return's
		if (exp instanceof VariableExpression) {
			val v = exp.variable
			if (v instanceof VertexVariable) {
				return '''\nodevariable{«v.escapedName»}{«convertVertexLabelSet(v.vertexLabelSet)»}'''
			} else if (v instanceof AbstractEdgeVariable) {
				return '''\edgevariable{«v.escapedName»}{«convertEdgeLabelSet(v.edgeLabelSet)»}'''
			}
		}

		return convertExpression(exp)
	}

	def dispatch CharSequence convertExpression(IntegerLiteral integerLiteral) {
		'''\literal{«integerLiteral.value»}'''
	}
	
	def dispatch CharSequence convertExpression(BigIntegerLiteral bigintegerLiteral)	{
		'''\literal{«bigintegerLiteral.value»}'''
	}
	
	def dispatch CharSequence convertExpression(DoubleLiteral doubleLiteral) {
		'''\literal{«doubleLiteral.value»}'''
	}

	def dispatch CharSequence convertExpression(StringLiteral stringLiteral) {
		'''\literal{"«stringLiteral.value.escape»"}'''
	}

	def dispatch CharSequence convertExpression(Parameter parameter) {
		'''\var{\$«parameter.name»}'''
	}

	def dispatch CharSequence convertExpression(ParameterComparableExpression pce) {
		'''«convertExpression(pce.parameter)»'''
	}

	def dispatch CharSequence convertExpression(ElementVariable elementVariable) {
		'''\var{«elementVariable.escapedName»}'''
	}

	def dispatch CharSequence convertExpression(AttributeVariable attributeVariable) {
		'''\var{«IF attributeVariable.element !== null»«attributeVariable.element.escapedName»«ELSE»«attributeVariable.expVar.escapedName»«ENDIF».«attributeVariable.escapedName»}'''
	}

	def dispatch CharSequence convertExpression(ExpressionVariable expVariable) {
		if (expVariable.hasInferredName) {
			convertExpression(expVariable.expression)
		} else {
			'''\var{«expVariable.escapedName»}'''
		}
	}
	
	def dispatch CharSequence convertExpression(VariableExpression ve) {
		convertExpression(ve.variable)
	}

	def dispatch CharSequence convertExpression(FunctionExpression fe) {
		'''
			\literal{«fe.functor.toString.escape»}
			«IF !fe.arguments.empty»\left( «fe.arguments.map[convertExpression].join(", ")» \right)«ENDIF»
		'''
	}

	def dispatch CharSequence convertExpression(EmptyListExpression fe) {
		'''\left[ \right]'''
	}

{'fraction_non_alphanumeric': 0.09415498545358371, 'fraction_numerical': 0.0005289605924358636, 'mean_word_length': 6.6471183013144595, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5941683', 'n_tokens_mistral': 2147, 'n_tokens_neox': 1982, 'n_words': 570}