<commit_before>﻿using BefunCompile.Graph.Expression;
using BefunCompile.Graph.Optimizations.Unstackify;
using BefunCompile.Math;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BefunCompile.Graph.Vertex
{
	public class BCVertexExprSet : BCVertex, MemoryAccess
	{
		public BCExpression X;
		public BCExpression Y;
		public BCExpression Value;

		public BCVertexExprSet(BCDirection d, Vec2i pos, BCExpression xx, BCExpression yy, BCExpression val)
			: base(d, new Vec2i[] { pos })
		{
			this.X = xx;
			this.Y = yy;
			this.Value = val;
		}

		public BCVertexExprSet(BCDirection d, Vec2i[] pos, BCExpression xx, BCExpression yy, BCExpression val)
			: base(d, pos)
		{
			this.X = xx;
			this.Y = yy;
			this.Value = val;
		}

		public override string ToString()
		{
			return string.Format("SET({0}, {1}) = {2}", X, Y, Value);
		}

		public override BCVertex Duplicate()
		{
			return new BCVertexExprSet(Direction, Positions, X, Y, Value);
		}

		public override IEnumerable<MemoryAccess> ListConstantVariableAccess()
		{

			if (X is ExpressionConstant && Y is ExpressionConstant)
				return new MemoryAccess[] { this }
					.Concat(X.ListConstantVariableAccess())
					.Concat(Y.ListConstantVariableAccess())
					.Concat(Value.ListConstantVariableAccess());
			else
				return X.ListConstantVariableAccess()
					.Concat(Y.ListConstantVariableAccess())
					.Concat(Value.ListConstantVariableAccess());
		}

		public override IEnumerable<MemoryAccess> ListDynamicVariableAccess()
		{

			if (X is ExpressionConstant && Y is ExpressionConstant)
				return X.ListDynamicVariableAccess()
					.Concat(Y.ListDynamicVariableAccess())
					.Concat(Value.ListDynamicVariableAccess());
			else
				return new MemoryAccess[] { this }
					.Concat(X.ListDynamicVariableAccess())
					.Concat(Y.ListDynamicVariableAccess())
					.Concat(Value.ListDynamicVariableAccess());
		}

		public override BCVertex Execute(StringBuilder outbuilder, GraphRunnerStack stackbuilder, ICalculateInterface ci)
		{
			ci.SetGridValue(X.Calculate(ci), Y.Calculate(ci), Value.Calculate(ci));

			if (Children.Count > 1)
				throw new ArgumentException("#");
			return Children.FirstOrDefault();
		}

		public BCExpression getX()
		{
			return X;
		}

		public BCExpression getY()
		{
			return Y;
		}

		public Vec2l getConstantPos()
		{
			BCExpression xx = getX();
			BCExpression yy = getY();

			if (xx == null || yy == null || !(xx is ExpressionConstant) || !(yy is ExpressionConstant))
				return null;
			else
				return new Vec2l(getX().Calculate(null), getY().Calculate(null));
		}

		public override bool SubsituteExpression(Func<BCExpression, bool> prerequisite, Func<BCExpression, BCExpression> replacement)
		{
			bool found = false;

			if (prerequisite(X))
			{
				X = replacement(X);
				found = true;
			}
			if (X.Subsitute(prerequisite, replacement))
			{
				found = true;
			}

			if (prerequisite(Y))
			{
				Y = replacement(Y);
				found = true;
			}
			if (Y.Subsitute(prerequisite, replacement))
			{
				found = true;
			}

			if (prerequisite(Value))
			{
				Value = replacement(Value);
				found = true;
			}
			if (Value.Subsitute(prerequisite, replacement))
			{
				found = true;
			}

			return found;
		}

		public override bool IsOutput()
		{
			return false;
		}

		public override bool IsNotGridAccess()
		{
			return false;
		}

		public override bool IsNotStackAccess()
		{
			return X.IsNotStackAccess() && Y.IsNotStackAccess() && Value.IsNotStackAccess();
		}

		public override bool IsNotVariableAccess()
		{
			return X.IsNotVariableAccess() && Y.IsNotVariableAccess() && Value.IsNotVariableAccess();
		}

		public override bool IsCodePathSplit()
		{
			return false;
		}

		public override bool IsBlock()
		{
			return false;
		}

		public override bool IsRandom()
		{
			return false;
		}

		public override IEnumerable<ExpressionVariable> GetVariables()
		{
			return X.GetVariables().Concat(Y.GetVariables()).Concat(Value.GetVariables());
		}

		public override IEnumerable<int> GetAllJumps(BCGraph g)
		{
			return Enumerable.Empty<int>();
		}

		public override string GenerateCodeCSharp(BCGraph g)
		{
			return string.Format("gw({0},{1},{2});", X.GenerateCodeCSharp(g, false), Y.GenerateCodeCSharp(g, false), Value.GenerateCodeCSharp(g, false));
		}

		public override string GenerateCodeC(BCGraph g)
		{
			return string.Format("gw({0},{1},{2});", X.GenerateCodeCSharp(g, false), Y.GenerateCodeCSharp(g, false), Value.GenerateCodeCSharp(g, false));
		}

		public override string GenerateCodePython(BCGraph g)
		{
			return string.Format("gw({0},{1},{2})", X.GenerateCodePython(g, false), Y.GenerateCodePython(g, false), Value.GenerateCodePython(g, false));
		}

		public override UnstackifyState WalkUnstackify(UnstackifyStateHistory history, UnstackifyState state)
		{
			state = state.Clone();

			if (X.IsNotStackAccess() && Y.IsNotStackAccess() && Value.IsNotStackAccess())
			{
				// all is good
			}
			else
			{
				if (!X.IsNotStackAccess())
					state.Peek().AddAccess(new UnstackifyValueAccess(this, UnstackifyValueAccessType.READ, UnstackifyValueAccessModifier.EXPR_GRIDX));

				if (!Y.IsNotStackAccess())
					state.Peek().AddAccess(new UnstackifyValueAccess(this, UnstackifyValueAccessType.READ, UnstackifyValueAccessModifier.EXPR_GRIDY));

				if (!Value.IsNotStackAccess())
					state.Peek().AddAccess(new UnstackifyValueAccess(this, UnstackifyValueAccessType.READ, UnstackifyValueAccessModifier.EXPR_VALUE));
			}

			return state;
		}

		public override BCVertex ReplaceUnstackify(List<UnstackifyValueAccess> access)<commit_msg>Fixed wrong GenerateCode call in BCVertexExprSet (C --> CS)<commit_after>﻿using BefunCompile.Graph.Expression;
using BefunCompile.Graph.Optimizations.Unstackify;
using BefunCompile.Math;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BefunCompile.Graph.Vertex
{
	public class BCVertexExprSet : BCVertex, MemoryAccess
	{
		public BCExpression X;
		public BCExpression Y;
		public BCExpression Value;

		public BCVertexExprSet(BCDirection d, Vec2i pos, BCExpression xx, BCExpression yy, BCExpression val)
			: base(d, new Vec2i[] { pos })
		{
			this.X = xx;
			this.Y = yy;
			this.Value = val;
		}

		public BCVertexExprSet(BCDirection d, Vec2i[] pos, BCExpression xx, BCExpression yy, BCExpression val)
			: base(d, pos)
		{
			this.X = xx;
			this.Y = yy;
			this.Value = val;
		}

		public override string ToString()
		{
			return string.Format("SET({0}, {1}) = {2}", X, Y, Value);
		}

		public override BCVertex Duplicate()
		{
			return new BCVertexExprSet(Direction, Positions, X, Y, Value);
		}

		public override IEnumerable<MemoryAccess> ListConstantVariableAccess()
		{

			if (X is ExpressionConstant && Y is ExpressionConstant)
				return new MemoryAccess[] { this }
					.Concat(X.ListConstantVariableAccess())
					.Concat(Y.ListConstantVariableAccess())
					.Concat(Value.ListConstantVariableAccess());
			else
				return X.ListConstantVariableAccess()
					.Concat(Y.ListConstantVariableAccess())
					.Concat(Value.ListConstantVariableAccess());
		}

		public override IEnumerable<MemoryAccess> ListDynamicVariableAccess()
		{

			if (X is ExpressionConstant && Y is ExpressionConstant)
				return X.ListDynamicVariableAccess()
					.Concat(Y.ListDynamicVariableAccess())
					.Concat(Value.ListDynamicVariableAccess());
			else
				return new MemoryAccess[] { this }
					.Concat(X.ListDynamicVariableAccess())
					.Concat(Y.ListDynamicVariableAccess())
					.Concat(Value.ListDynamicVariableAccess());
		}

		public override BCVertex Execute(StringBuilder outbuilder, GraphRunnerStack stackbuilder, ICalculateInterface ci)
		{
			ci.SetGridValue(X.Calculate(ci), Y.Calculate(ci), Value.Calculate(ci));

			if (Children.Count > 1)
				throw new ArgumentException("#");
			return Children.FirstOrDefault();
		}

		public BCExpression getX()
		{
			return X;
		}

		public BCExpression getY()
		{
			return Y;
		}

		public Vec2l getConstantPos()
		{
			BCExpression xx = getX();
			BCExpression yy = getY();

			if (xx == null || yy == null || !(xx is ExpressionConstant) || !(yy is ExpressionConstant))
				return null;
			else
				return new Vec2l(getX().Calculate(null), getY().Calculate(null));
		}

		public override bool SubsituteExpression(Func<BCExpression, bool> prerequisite, Func<BCExpression, BCExpression> replacement)
		{
			bool found = false;

			if (prerequisite(X))
			{
				X = replacement(X);
				found = true;
			}
			if (X.Subsitute(prerequisite, replacement))
			{
				found = true;
			}

			if (prerequisite(Y))
			{
				Y = replacement(Y);
				found = true;
			}
			if (Y.Subsitute(prerequisite, replacement))
			{
				found = true;
			}

			if (prerequisite(Value))
			{
				Value = replacement(Value);
				found = true;
			}
			if (Value.Subsitute(prerequisite, replacement))
			{
				found = true;
			}

			return found;
		}

		public override bool IsOutput()
		{
			return false;
		}

		public override bool IsNotGridAccess()
		{
			return false;
		}

		public override bool IsNotStackAccess()
		{
			return X.IsNotStackAccess() && Y.IsNotStackAccess() && Value.IsNotStackAccess();
		}

		public override bool IsNotVariableAccess()
		{
			return X.IsNotVariableAccess() && Y.IsNotVariableAccess() && Value.IsNotVariableAccess();
		}

		public override bool IsCodePathSplit()
		{
			return false;
		}

		public override bool IsBlock()
		{
			return false;
		}

		public override bool IsRandom()
		{
			return false;
		}

		public override IEnumerable<ExpressionVariable> GetVariables()
		{
			return X.GetVariables().Concat(Y.GetVariables()).Concat(Value.GetVariables());
		}

		public override IEnumerable<int> GetAllJumps(BCGraph g)
		{
			return Enumerable.Empty<int>();
		}

		public override string GenerateCodeCSharp(BCGraph g)
		{
			return string.Format("gw({0},{1},{2});", X.GenerateCodeCSharp(g, false), Y.GenerateCodeCSharp(g, false), Value.GenerateCodeCSharp(g, false));
		}

		public override string GenerateCodeC(BCGraph g)
		{
			return string.Format("gw({0},{1},{2});", X.GenerateCodeCSharp(g, false), Y.GenerateCodeC(g, false), Value.GenerateCodeC(g, false));
		}

		public override string GenerateCodePython(BCGraph g)
		{
			return string.Format("gw({0},{1},{2})", X.GenerateCodePython(g, false), Y.GenerateCodePython(g, false), Value.GenerateCodePython(g, false));
		}

		public override UnstackifyState WalkUnstackify(UnstackifyStateHistory history, UnstackifyState state)
		{
			state = state.Clone();

			if (X.IsNotStackAccess() && Y.IsNotStackAccess() && Value.IsNotStackAccess())
			{
				// all is good
			}
			else
			{
				if (!X.IsNotStackAccess())
					state.Peek().AddAccess(new UnstackifyValueAccess(this, UnstackifyValueAccessType.READ, UnstackifyValueAccessModifier.EXPR_GRIDX));

				if (!Y.IsNotStackAccess())
					state.Peek().AddAccess(new UnstackifyValueAccess(this, UnstackifyValueAccessType.READ, UnstackifyValueAccessModifier.EXPR_GRIDY));

				if (!Value.IsNotStackAccess())
					state.Peek().AddAccess(new UnstackifyValueAccess(this, UnstackifyValueAccessType.READ, UnstackifyValueAccessModifier.EXPR_VALUE));
			}

			return state;
		}

		public override BCVertex ReplaceUnstackify(List<UnstackifyValueAccess> access)
{'fraction_non_alphanumeric': 0.120060251639199, 'fraction_numerical': 0.003189792663476874, 'mean_word_length': 4.041089772219741, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 22, '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': '2622654', 'n_tokens_mistral': 4291, 'n_tokens_neox': 3576, 'n_words': 770}