<commit_before>﻿using System;
using Oberon0.Compiler.Definitions;
using Oberon0.Compiler.Expressions;

namespace Oberon0.Compiler.Solver
{
    using Oberon0.Compiler.Expressions.Constant;

    /// <summary>
    /// Solve constant expressions
    /// </summary>
    static class ConstantSolver
    {
        public static Expression Solve(Expression expression, Block block)
        {
            if (expression == null) throw new ArgumentNullException(nameof(expression));

            return Calculate(expression, block);
        }

        private static Expression Calculate(Expression expression, Block block)
        {
            if (expression is VariableReferenceExpression) return expression;
            var bin = expression as BinaryExpression;
            if (bin != null)
            {
                if (!bin.LeftHandSide.IsConst)
                    bin.LeftHandSide = Calculate(bin.LeftHandSide, block);
                if (!bin.RightHandSide?.IsConst ?? false)
                    bin.RightHandSide = Calculate(bin.RightHandSide, block);
                return bin.Operation.Operation.Operate(bin, block, bin.Operation.Metadata);
            }
            var c = expression as ConstantExpression;
            if (c != null) return c;
            // ignore string expressions
            if (expression is StringExpression) return expression;
            if (expression is FunctionCallExpression) return expression;
            throw new InvalidOperationException($"Calculate does not support operation on {expression.GetType().Name}");
        }
    }
}<commit_msg>Fix SQ issue<commit_after>﻿#region copyright
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ConstantSolver.cs" company="<NAME>">
// Copyright (c) <NAME>. All rights reserved.
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
// </copyright>
// <summary>
//     Part of oberon0 - Oberon0Compiler/ConstantSolver.cs
// </summary>
// --------------------------------------------------------------------------------------------------------------------
#endregion

namespace Oberon0.Compiler.Solver
{
    using System;

    using Oberon0.Compiler.Definitions;
    using Oberon0.Compiler.Expressions;
    using Oberon0.Compiler.Expressions.Constant;

    /// <summary>
    /// Solve constant expressions
    /// </summary>
    internal static class ConstantSolver
    {
        /// <summary>
        /// Initialize a constant solver.
        /// </summary>
        /// <param name="expression">
        /// The expression.
        /// </param>
        /// <param name="block">
        /// The block.
        /// </param>
        /// <returns>
        /// The <see cref="Expression"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">The expression is missing.
        /// </exception>
        public static Expression Solve(Expression expression, Block block)
        {
            if (expression == null) throw new ArgumentNullException(nameof(expression));

            return Calculate(expression, block);
        }

        private static Expression Calculate(Expression expression, Block block)
        {
            if (expression is VariableReferenceExpression) return expression;

            if (expression is BinaryExpression bin)
            {
                if (!bin.LeftHandSide.IsConst)
                    bin.LeftHandSide = Calculate(bin.LeftHandSide, block);
                if (!(bin.RightHandSide?.IsConst ?? false))
                    bin.RightHandSide = Calculate(bin.RightHandSide, block);
                return bin.Operation.Operation.Operate(bin, block, bin.Operation.Metadata);
            }

            if (expression is ConstantExpression c) return c;

            // ignore string expressions
            if (expression is StringExpression) return expression;
            if (expression is FunctionCallExpression) return expression;
            throw new InvalidOperationException($"Calculate does not support operation on {expression.GetType().Name}");
        }
    }
}
{'fraction_non_alphanumeric': 0.15162454873646208, 'fraction_numerical': 0.0024067388688327317, 'mean_word_length': 1.819538670284939, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 24, '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': '3723913', 'n_tokens_mistral': 957, 'n_tokens_neox': 915, 'n_words': 267}