Example #1
0
        protected string SimpleOperator(Context context, InstructionFunction inst, string glue)
        {
            int num = context.Node.Children.Count;

            bool needsparen = false;

            if (context.Node.Parent != null)
            {
                InstructionFunction op = context.Node.Parent.Instruction as InstructionFunction;

                needsparen = inst == null || (op != null && HasPriority((Cdn.MathFunctionType)op.Id, (Cdn.MathFunctionType)inst.Id));
            }

            if (num == 1)
            {
                return(String.Format("{0}{1}", glue, Translate(context, 0)).Trim());
            }

            string[] args = new string[num];

            for (int i = 0; i < num; ++i)
            {
                args[i] = Translate(context, i);
            }

            if (!needsparen)
            {
                return(String.Join(glue, args).Trim());
            }
            else
            {
                return(String.Format("({0})", String.Join(glue, args).Trim()));
            }
        }
Example #2
0
        /// <summary>
        ///		Transforma las funciones en subprogramas
        /// </summary>
        private Program TransformFunctions(Program sourceProgram)
        {
            Program program = new Program("Main");

            // Añade las funciones originales
            program.Functions.AddRange(sourceProgram.Functions);
            // Transforma las funciones
            foreach (InstructionBase instruction in sourceProgram.Sentences)
            {
                if (instruction is InstructionFunction)
                {
                    InstructionFunction function = instruction as InstructionFunction;

                    if (function != null)
                    {
                        program.Functions.Add(GetFunctionProgram(function, program));
                    }
                }
                else
                {
                    program.Sentences.Add(instruction);
                }
            }
            // Devuelve el programa
            return(program);
        }
Example #3
0
        protected override string TranslateOperator(InstructionFunction instruction, CLike.Context context)
        {
            switch ((Cdn.MathFunctionType)instruction.Id)
            {
            case MathFunctionType.Modulo:
                return(SimpleOperator(context, instruction, " % "));

            default:
                return(base.TranslateOperator(instruction, context));
            }
        }
Example #4
0
        /// <summary>
        ///		Convierte una instrucción de función en un programa
        /// </summary>
        private Program GetFunctionProgram(InstructionFunction function, Program parent)
        {
            Program program = new Program(function.Name, parent);

            // Añade los argumentos a la tabla de símbolos
            foreach (string argument in function.Arguments)
            {
                program.Arguments.Add(argument);
            }
            // Añade las instrucciones
            program.Sentences.AddRange(function.Sentences);
            // Devuelve el programa
            return(program);
        }
Example #5
0
        /* Translate a builtin function which returns a multidimensional value.
         */
        protected virtual string TranslateV(InstructionFunction instruction, Context context)
        {
            Cdn.MathFunctionType type;

            type = (Cdn.MathFunctionType)instruction.Id;

            var    def = context.MathFunctionV(type, context.Node);
            string ret = null;

            if (!context.Node.Dimension.IsOne && !context.SupportsFirstClassArrays)
            {
                ret = context.PeekRet();
            }

            var isp = context.Node.Instruction as Instructions.SparseOperator;

            if (isp != null)
            {
                if (!Context.UsedSparseFunctions.ContainsKey(def))
                {
                    var sf = new Context.SparseFunction()
                    {
                        Name        = def,
                        Type        = (Cdn.MathFunctionType)isp.Original.Id,
                        RetSparsity = isp.RetSparsity,
                        ArgSparsity = isp.ArgSparsity
                    };

                    Context.UsedSparseFunctions[def] = sf;

                    if (sf.Type == MathFunctionType.Pow || sf.Type == MathFunctionType.Power)
                    {
                        Context.UsedMathFunctions.Add("CDN_MATH_POW");
                    }
                }
            }
            else
            {
                Context.UsedMathFunctions.Add(def);
            }

            List <string> args = new List <string>(context.Node.Children.Count + 1);

            int cnt = 0;

            for (int i = 0; i < context.Node.Children.Count; ++i)
            {
                var child = context.Node.Children[i];

                args.Add(TranslateChildV(child, context));

                var s = child.Dimension.Size();

                if (s > cnt)
                {
                    cnt = s;
                }
            }

            // Provide dimension except for sparse functions since they are generated
            // for specific static dimensions already
            if (isp == null)
            {
                context.TranslateFunctionDimensionArguments(instruction, args, cnt);
            }

            if (ret != null)
            {
                return(String.Format("{0}({1}, {2})", def, ret, String.Join(", ", args)));
            }
            else
            {
                return(String.Format("{0}({1})", def, String.Join(", ", args)));
            }
        }
Example #6
0
        /*
         * Translates a call to a builtin math function. The InstructionFunction
         * is used both for operators and functions (they are treated equally).
         *
         * If the instruction represents an operator, then we call
         * TranslateOperator which uses language specific available operators
         * to translate the instruction. Otherwise a function call is translated
         * to the language specific builtin math function.
         */
        protected virtual string Translate(InstructionFunction instruction, Context context)
        {
            if (instruction.Id < (uint)Cdn.MathFunctionType.NumOperators)
            {
                return(TranslateOperator(instruction, context));
            }

            string[] args = new string[context.Node.Children.Count];

            // Translate function arguments
            for (int i = 0; i < context.Node.Children.Count; ++i)
            {
                args[i] = Translate(context, i);
            }

            string name = context.MathFunction(context.Node);

            switch ((Cdn.MathFunctionType)instruction.Id)
            {
            case MathFunctionType.Transpose:
            case MathFunctionType.Min:
            case MathFunctionType.Max:
            case MathFunctionType.Sum:
            case MathFunctionType.Product:
            case MathFunctionType.Hypot:
                if (args.Length == 1)
                {
                    // These functions are NOOPs with a single argument
                    return(args[0]);
                }
                break;

            case MathFunctionType.Sqsum:
                if (args.Length == 1)
                {
                    Context.UsedMathFunctions.Add(name);
                    return(String.Format("{0}({1})", name, args[0]));
                }
                break;
            }

            Context.UsedMathFunctions.Add(name);

            if (Math.FunctionIsVariable((Cdn.MathFunctionType)instruction.Id))
            {
                string ret = "";

                // This does not work in the general case, but anyway
                if (args.Length == 1)
                {
                    return(args[0]);
                }

                for (int i = args.Length - 2; i >= 0; --i)
                {
                    if (i != args.Length - 2)
                    {
                        ret = String.Format("{0}({1}, {2})", name, args[i], ret);
                    }
                    else
                    {
                        ret = String.Format("{0}({1}, {2})", name, args[i], args[i + 1]);
                    }
                }

                return(ret);
            }

            return(String.Format("{0}({1})", name, String.Join(", ", args)));
        }
Example #7
0
        protected virtual string TranslateOperator(InstructionFunction instruction, Context context)
        {
            switch ((Cdn.MathFunctionType)instruction.Id)
            {
            case MathFunctionType.And:
                return(SimpleOperator(context, instruction, " && "));

            case MathFunctionType.Divide:
                return(SimpleOperator(context, instruction, " / "));

            case MathFunctionType.Equal:
                return(SimpleOperator(context, instruction, " == "));

            case MathFunctionType.Greater:
                return(SimpleOperator(context, instruction, " > "));

            case MathFunctionType.GreaterOrEqual:
                return(SimpleOperator(context, instruction, " >= "));

            case MathFunctionType.Less:
                return(SimpleOperator(context, instruction, " < "));

            case MathFunctionType.LessOrEqual:
                return(SimpleOperator(context, instruction, " <= "));

            case MathFunctionType.Minus:
                return(SimpleOperator(context, instruction, " - "));

            case MathFunctionType.UnaryMinus:
                return(String.Format("-({0})", Translate(context, 0)));

            case MathFunctionType.Multiply:
            case MathFunctionType.Emultiply:
                return(SimpleOperator(context, instruction, " * "));

            case MathFunctionType.Negate:
                return(SimpleOperator(context, instruction, " !"));

            case MathFunctionType.Or:
                return(SimpleOperator(context, instruction, " || "));

            case MathFunctionType.Plus:
                return(SimpleOperator(context, instruction, " + "));

            case MathFunctionType.Modulo:
            {
                var def = context.MathFunction(Cdn.MathFunctionType.Modulo, context.Node.Children.Count);
                Context.UsedMathFunctions.Add(def);

                return(String.Format("{0}({1}, {2})",
                                     def,
                                     Translate(context, 0),
                                     Translate(context, 1)));
            }

            case MathFunctionType.Power:
            {
                var def = context.MathFunction(Cdn.MathFunctionType.Pow, context.Node.Children.Count);
                Context.UsedMathFunctions.Add(def);

                return(String.Format("{0}({1}, {2})",
                                     def,
                                     Translate(context, 0),
                                     Translate(context, 1)));
            }

            case MathFunctionType.Ternary:
                return(String.Format("(({0}) ? ({1}) : ({2}))",
                                     Translate(context, 0),
                                     Translate(context, 1),
                                     Translate(context, 2)));
            }

            throw new NotImplementedException(String.Format("The operator `{0}' is not implemented", instruction.Name));
        }
Example #8
0
        public virtual void TranslateFunctionDimensionArguments(InstructionFunction instruction,
                                                                List <string> args,
                                                                int cnt)
        {
            var type = (Cdn.MathFunctionType)instruction.Id;

            switch (type)
            {
            case MathFunctionType.Transpose:
            {
                var dim = Node.Children[0].Dimension;

                args.Add(dim.Rows.ToString());
                args.Add(dim.Columns.ToString());
            }
            break;

            case MathFunctionType.Vcat:
            {
                var dim1 = Node.Children[0].Dimension;
                var dim2 = Node.Children[1].Dimension;

                args.Add(dim1.Rows.ToString());
                args.Add(dim2.Rows.ToString());
                args.Add(dim1.Columns.ToString());
            }
            break;

            case MathFunctionType.Diag:
            {
                var dim1 = Node.Children[0].Dimension;

                if (dim1.Rows == 1 || dim1.Columns == 1)
                {
                    args.Add(dim1.Size().ToString());
                }
                else
                {
                    args.Add(dim1.Rows.ToString());
                }
            }
            break;

            case MathFunctionType.Triu:
            case MathFunctionType.Tril:
            {
                var dim1 = Node.Children[0].Dimension;
                args.Add(dim1.Rows.ToString());
                args.Add(dim1.Columns.ToString());
            }
            break;

            case MathFunctionType.Multiply:
            {
                var d1 = Node.Children[0].Dimension;
                var d2 = Node.Children[1].Dimension;

                if (d1.Columns == d2.Rows && !(d1.IsOne || d2.IsOne))
                {
                    // Matrix multiply
                    args.Add(d1.Rows.ToString());
                    args.Add(d1.Columns.ToString());
                    args.Add(d2.Columns.ToString());
                }
                else
                {
                    args.Add(cnt.ToString());
                }
            }
            break;

            case MathFunctionType.Csum:
            case MathFunctionType.Rsum:
            {
                var d = Node.Children[0].Dimension;
                args.Add(d.Rows.ToString());
                args.Add(d.Columns.ToString());
            }
            break;

            case MathFunctionType.Index:
                break;

            default:
                if (Node.Children.Count == 2)
                {
                    var d1 = Node.Children[0].Dimension;
                    var d2 = Node.Children[1].Dimension;

                    if ((d1.Columns == 1 || d2.Columns == 1) && d1.Rows == d2.Rows && d1.Rows != 1 && d1.Columns != d2.Columns)
                    {
                        args.Add(d1.Rows.ToString());
                        args.Add((d1.Columns == 1 ? d2.Columns : d1.Columns).ToString());
                        break;
                    }
                    else if ((d1.Rows == 1 || d2.Rows == 1) && d1.Columns == d2.Columns && d1.Columns != 1 && d1.Rows != d2.Rows)
                    {
                        args.Add((d1.Rows == 1 ? d2.Rows : d1.Rows).ToString());
                        args.Add(d1.Columns.ToString());
                        break;
                    }
                }

                args.Add(cnt.ToString());
                break;
            }
        }
Example #9
0
        /// <summary>
        ///		Crea la instrucción de definición de un Mixin
        /// </summary>
        private InstructionBase CreateInstructionMixinDefinition()
        {
            InstructionFunction instruction = new InstructionFunction(GetToken());
            TokenSmallCss       token       = GetToken();

            // Obtiene la función
            if (token.Row == instruction.Token.Row && token.TypeCss == TokenSmallCss.TokenCssType.Literal)
            {
                // Asigna el nombre de la función
                instruction.Name = token.Value;
                // Obtiene los argumentos
                if (ActualToken.Row == instruction.Token.Row)
                {
                    bool end = false;

                    while (!end && !IsEof)
                    {
                        // Comprueba si es un argumento
                        if (ActualToken.Row == instruction.Token.Row)
                        {
                            if (ActualToken.TypeCss == TokenSmallCss.TokenCssType.Literal ||
                                ActualToken.TypeCss == TokenSmallCss.TokenCssType.Variable)
                            {
                                string argument = ActualToken.Value;

                                // Normaliza el argumento
                                if (!argument.StartsWith("$"))
                                {
                                    argument = "$" + argument;
                                }
                                // Añade el nombre del argumento
                                instruction.Arguments.Add(argument);
                                // Obtiene el siguiente token
                                GetToken();
                            }
                            else if (ActualToken.TypeCss == TokenSmallCss.TokenCssType.Comment)
                            {
                                instruction.Sentences.Add(CreateInstructionComment());
                            }
                            else
                            {
                                instruction.Error = ParseError($"No se reconoce el token entre los argumentos de la función '{instruction.Name}'");
                            }
                        }
                        else
                        {
                            end = true;
                        }
                    }
                }
                if (!instruction.IsError)
                {
                    if (CheckIsBlock(instruction.Token))
                    {
                        instruction.Sentences.AddRange(GetBlock(instruction.Token.Indent));
                    }
                    else
                    {
                        instruction.Error = ParseError("No se han definido las instrucciones de la función");
                    }
                }
            }
            else
            {
                instruction.Error = ParseError("No se encuentra el nombre de la función");
            }
            // Devuelve la instrucción
            return(instruction);
        }
Example #10
0
        private int[] InstructionSparsity(InstructionFunction instr, SparsityInfo[] children, Dictionary <Variable, SparsityInfo> mapping)
        {
            switch ((Cdn.MathFunctionType)instr.Id)
            {
            case MathFunctionType.Diag:
                return(DiagSparsity(children));

            case MathFunctionType.Divide:
            case MathFunctionType.Pow:
            case MathFunctionType.Power:
                return(DividePowerSparsity(children));

            case MathFunctionType.Emultiply:
            case MathFunctionType.Product:
                return(UnionSparsity(children));

            case MathFunctionType.Minus:
            case MathFunctionType.Plus:
            case MathFunctionType.Sqsum:
            case MathFunctionType.Sum:
            case MathFunctionType.UnaryMinus:
                return(IntersectSparsity(children));

            case MathFunctionType.Multiply:
                return(MultiplySparsity(children));

            case MathFunctionType.Csum:
                return(CSumSparsity(children));

            case MathFunctionType.Rsum:
                return(RSumSparsity(children));

            case MathFunctionType.Transpose:
                return(TransposeSparsity(children));

            case MathFunctionType.Vcat:
                return(VcatSparsity(instr.GetStackManipulation().Push.Dimension, children));

            case MathFunctionType.Sltdl:
                // The LTDL factorization has the same sparsity pattern as its
                // first argument
                return(CopySparsity(children[0].Sparsity));

            case MathFunctionType.SltdlDinv:
                return(SltdlDinvSparsity(children));

            case MathFunctionType.SltdlDinvLinvt:
                return(SltdlDinvLinvtSparsity(children));

            case MathFunctionType.SltdlLinv:
                return(SltdlLinvSparsity(children));

            case MathFunctionType.SltdlLinvt:
                return(SltdlLinvtSparsity(children));

            case MathFunctionType.Slinsolve:
                return(SlinsolveSparsity(children));

            case MathFunctionType.PseudoInverse:
                return(PseudoInverseSparsity(children));

            default:
                break;
            }

            return(new int[0]);
        }
Example #11
0
        public override void TranslateFunctionDimensionArguments(InstructionFunction instruction, List <string> args, int cnt)
        {
            switch ((Cdn.MathFunctionType)instruction.Id)
            {
            case MathFunctionType.Linsolve:
            {
                // Add rows of A and columns of B arguments
                var dim1 = Node.Children[1].Dimension;
                var dim2 = Node.Children[0].Dimension;

                // Here we also reorder the arguments A and b. In codyn these
                // are on the stack in reversed order to make it more efficient
                // but here we really don't need that and it's more logical
                // the other way around
                var tmp = args[0];

                args[0] = args[1];
                args[1] = tmp;

                args.Add(dim1.Rows.ToString());
                args.Add(dim2.Columns.ToString());
            }
            break;

            case MathFunctionType.Slinsolve:
            {
                // Add columns of B argument

                // Here we also reorder the arguments.
                var b = args[0];
                var L = args[1];
                var A = args[2];

                args[0] = A;
                args[1] = b;
                args[2] = Node.Children[0].Dimension.Columns.ToString();
                args.Add(L);
            }
            break;

            case MathFunctionType.Sltdl:
            {
                var A = args[0];
                var L = args[1];

                args[0] = A;
                args[1] = Node.Children[1].Dimension.Rows.ToString();
                args.Add(L);
            }
            break;

            case MathFunctionType.SltdlDinvLinvt:
            case MathFunctionType.SltdlLinvt:
            case MathFunctionType.SltdlLinv:
            {
                var b = args[0];
                var L = args[1];
                var A = args[2];

                args[0] = A;
                args[1] = Node.Children[2].Dimension.Rows.ToString();
                args[2] = b;
                args.Add(Node.Children[0].Dimension.Columns.ToString());
                args.Add(L);
            }
            break;

            case MathFunctionType.SltdlDinv:
            {
                var b = args[0];
                var A = args[1];

                args[0] = A;
                args[1] = Node.Children[1].Dimension.Rows.ToString();
                args.Add(b);
                args.Add(Node.Children[0].Dimension.Columns.ToString());
            }
            break;

            case MathFunctionType.Inverse:
            case MathFunctionType.PseudoInverse:
            case MathFunctionType.Qr:
                break;

            default:
                base.TranslateFunctionDimensionArguments(instruction, args, cnt);
                break;
            }
        }