<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JSIL;
using JSIL.Ast;
using JSIL.Compiler.Extensibility;
using JSIL.Internal;
using Mono.Cecil;

namespace WasmSExprEmitter {
    public class FunctionTransformer : IFunctionTransformer {
        internal FunctionTransformer () {
        }

        public void InitializeTransformPipeline (AssemblyTranslator translator, FunctionTransformPipeline transformPipeline) {
        }

        private static bool ExtractLiteral<T> (JSExpression expr, out T result) {
            result = default(T);

            var literal = expr as JSLiteral;
            if (literal == null)
                return false;

            if (!(literal.Literal is T))
                return false;

            result = (T)literal.Literal;
            return true;
        }

        private static JSExpression Add (TypeSystem typeSystem, JSExpression lhs, JSExpression rhs) {
            long iLhs, iRhs;
            if (ExtractLiteral(lhs, out iLhs) && ExtractLiteral(rhs, out iRhs))
                return JSLiteral.New((int)(iLhs + iRhs));

            var type = lhs.GetActualType(typeSystem);
            return new JSBinaryOperatorExpression(JSOperator.Add, lhs, rhs, type);
        }

        private static JSExpression Mul (TypeSystem typeSystem, JSExpression lhs, JSExpression rhs) {
            long iLhs, iRhs;
            if (ExtractLiteral(lhs, out iLhs) && ExtractLiteral(rhs, out iRhs))
                return JSLiteral.New((int)(iLhs * iRhs));

            return new JSBinaryOperatorExpression(JSOperator.Multiply, lhs, rhs, typeSystem.Int32);
        }

        private JSExpression[] UnpackArgsArray (JSExpression expr) {
            JSExpression[] result;

            var argumentsLiteral = (JSNewArrayExpression)expr;
            var initializer = argumentsLiteral.SizeOrArrayInitializer;
            if (initializer is JSLiteral) {
                // HACK: Is this right?
                long size;
                if (ExtractLiteral<long>(initializer, out size))
                    result = new JSExpression[(int)size];
                else
                    result = new JSExpression[0];
            } else if (!(initializer is JSArrayExpression)) {
                throw new Exception("Expected either size literal or array expression");
            } else {
                var argumentsArray = (JSArrayExpression)initializer;

                // HACK: Values used as initializers may be references for no particularly good reason.<commit_msg>Handle MS C# compiler's representation of empty arrays<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JSIL;
using JSIL.Ast;
using JSIL.Compiler.Extensibility;
using JSIL.Internal;
using Mono.Cecil;

namespace WasmSExprEmitter {
    public class FunctionTransformer : IFunctionTransformer {
        internal FunctionTransformer () {
        }

        public void InitializeTransformPipeline (AssemblyTranslator translator, FunctionTransformPipeline transformPipeline) {
        }

        private static bool ExtractLiteral<T> (JSExpression expr, out T result) {
            result = default(T);

            var literal = expr as JSLiteral;
            if (literal == null)
                return false;

            if (!(literal.Literal is T))
                return false;

            result = (T)literal.Literal;
            return true;
        }

        private static JSExpression Add (TypeSystem typeSystem, JSExpression lhs, JSExpression rhs) {
            long iLhs, iRhs;
            if (ExtractLiteral(lhs, out iLhs) && ExtractLiteral(rhs, out iRhs))
                return JSLiteral.New((int)(iLhs + iRhs));

            var type = lhs.GetActualType(typeSystem);
            return new JSBinaryOperatorExpression(JSOperator.Add, lhs, rhs, type);
        }

        private static JSExpression Mul (TypeSystem typeSystem, JSExpression lhs, JSExpression rhs) {
            long iLhs, iRhs;
            if (ExtractLiteral(lhs, out iLhs) && ExtractLiteral(rhs, out iRhs))
                return JSLiteral.New((int)(iLhs * iRhs));

            return new JSBinaryOperatorExpression(JSOperator.Multiply, lhs, rhs, typeSystem.Int32);
        }

        private JSExpression[] UnpackArgsArray (JSExpression expr) {
            JSExpression[] result;

            var invoke = expr as JSInvocationExpression;
            if (invoke != null) {
                var m = invoke.JSMethod.Reference;
                if ((m.Name == "Empty") && (m.DeclaringType.FullName == "System.Array"))
                    return new JSExpression[0];

                throw new Exception("Unhandled invocation as args array: " + invoke);
            }

            var argumentsLiteral = expr as JSNewArrayExpression;
            if (argumentsLiteral == null)
                throw new Exception("Expected arguments array but got " + expr.GetType().Name);

            var initializer = argumentsLiteral.SizeOrArrayInitializer;
            if (initializer is JSLiteral) {
                // HACK: Is this right?
                long size;
                if (ExtractLiteral<long>(initializer, out size))
                    result = new JSExpression[(int)size];
                else
                    result = new JSExpression[0];
            } else if (!(initializer is JSArrayExpression)) {
                throw new Exception("Expected either size literal or array expression");
            } else {
                var argumentsArray = (JSArrayExpression)initializer;

                // HACK: Values used as initializers may be references for no particularly good reason.
{'fraction_non_alphanumeric': 0.08076588337684944, 'fraction_numerical': 0.0012184508268059183, 'mean_word_length': 2.1816168327796235, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '2542812', 'n_tokens_mistral': 1471, 'n_tokens_neox': 1428, 'n_words': 430}