public MIPS Visitor(NegCil instance, IFunctionCil function, GenerateToCil cil)
        {
            var lines = new List <string>(Utils.AcomodarVariables(instance.Y, function))
            {
                "neg $t0, $t1"     //Guarda en t0 la suma de t1
            };

            lines.AddRange(Utils.LoadFromRegister(instance.X, function, "t0"));
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(ArgExprCil instance, IFunctionCil function, GenerateToCil cil)
        {
            var lines = new List <string>(Utils.SaveToRegister(instance.X, function, "t0"))
            {
                $"sw $t0, {(CountArgs+2)*(-4)}($sp)"
            };

            CountArgs++;
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(EqualStringCil instance, IFunctionCil function, GenerateToCil cil)
        {
            var lines = new List <string>();

            lines.AddRange(Utils.SaveToRegister(instance.Y, function, "a0"));
            lines.AddRange(Utils.SaveToRegister(instance.Z, function, "a1"));
            lines.Add("jal equalFunctionStart");
            lines.AddRange(Utils.LoadFromRegister(instance.X, function, "v0"));
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(Type_Name instance, IFunctionCil function, GenerateToCil cil)
        {
            var lines = new List <string>(Utils.SaveToRegister(instance.Y, function, "t0"))
            {
                "lw $t0, ($t0)"
            };

            lines.AddRange(Utils.LoadFromRegister(instance.X, function, "t0"));
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(LoadCil instance, IFunctionCil function, GenerateToCil cil)
        {
            List <string> lines = new List <string>()
            {
                $"la $t0, {instance.Y.Name}"
            };

            lines.AddRange(Utils.LoadFromRegister(instance.X, function, "t0"));
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(LenghtCil instance, IFunctionCil function, GenerateToCil cil)
        {
            var lines = new List <string>(Utils.SaveToRegister(instance.Y, function, "t0"))
            {
                "jal lengthFunctionStart"
            };

            lines.AddRange(Utils.LoadFromRegister(instance.X, function, "v0"));
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(In_intCil instance, IFunctionCil function, GenerateToCil cil)
        {
            var lines = new List <string>()
            {
                "li $v0, 5",
                "syscall"
            };

            lines.AddRange(Utils.LoadFromRegister(instance.X, function, "v0"));
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(CallCil instance, IFunctionCil function, GenerateToCil cil)
        {
            CountArgs = 0;
            var lines = new List <string>()
            {
                $"jal {instance.Y.Name}"
            };

            lines.AddRange(Utils.LoadFromRegister(instance.X, function, "v0"));
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(ReturnCil instance, IFunctionCil function, GenerateToCil cil)
        {
            var lines = new List <string>()
            {
                $"lw $ra, {(function.ArgCils.Count+function.LocalCils.Count)*4}($sp)",     //Carga Ra que lo habia guardado en la pila
            };

            lines.AddRange(Utils.SaveToRegister(instance.X, function, "v0"));                          //Coloca el valor de retorno en el registro correspondiente
            lines.Add($"addi $sp, $sp {(function.ArgCils.Count + function.LocalCils.Count + 1) * 4}"); // Setea el SP donde estaba anteriormente
            lines.Add($"jr $ra");                                                                      //Salta para donde estaba
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(IsNotConformCil instance, IFunctionCil function, GenerateToCil cil)
        {
            var lines = new List <string>();

            lines.Add($"la $a0, type_{instance.Z.Name}_name");
            lines.AddRange(Utils.SaveToRegister(instance.Y, function, "t0"));
            lines.Add("lw $t0, ($t0)");
            lines.Add("addi $a1, $t0, -4");
            lines.Add("jal conformFunctionStart");
            lines.AddRange(Utils.LoadFromRegister(instance.X, function, "v0"));
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(Out_intCil instance, IFunctionCil function, GenerateToCil cil)
        {
            var lines = new List <string>(Utils.SaveToRegister(instance.X, function, "a0"))
            {
                "li $v0, 1",
                "syscall",
                "la $a0, newLine",
                "li $v0, 4",
                "syscall"
            };

            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(NotEqualCil instance, IFunctionCil function, GenerateToCil cil)
        {
            var lines = new List <string>(Utils.AcomodarVariables(instance.Y, function));

            if (instance.Z is TypeCil)
            {
                lines.Add("lw $t1, ($t1)");
                lines.Add($"la $t2, type_{instance.Z.Name}_name");
            }
            else
            {
                lines.AddRange(Utils.SaveToRegister(instance.Z, function, "t2"));
            }
            lines.Add("sne $t0, $t1, $t2");
            lines.AddRange(Utils.LoadFromRegister(instance.X, function, "t0"));
            return(new MIPS()
            {
                Functions = lines
            });
        }
        public MIPS Visitor(GetAttrCil instance, IFunctionCil function, GenerateToCil cil)
        {
            var attr     = instance.Z as AttributeCil;
            var typeName = attr.Name.Substring(0, attr.Name.Length - attr.CilName.Length - 1);
            var type     = cil.CilAst.TypeCils.First(x => x.Name == typeName);
            var indexOf  = type.Attributes.ToList().IndexOf(attr);


            var lines = new List <string>(Utils.SaveToRegister((IVarCil)instance.Y, function, "t0"))
            {
                $"addi $t0, $t0, {(indexOf+2)*4}",
                $"lw $t0, ($t0)"
            };

            lines.AddRange(Utils.LoadFromRegister(instance.X, function, "t0"));

            return(new MIPS()
            {
                Functions = lines
            });
        }
 public MIPS Visitor(VCallCil instance, IFunctionCil function, GenerateToCil cil)
 {
     CountArgs = 0;
     if (instance.Y is TypeCil)
     {
         var label = ((FunctionTypeCil)instance.Z).Function.Name;
         var lines = new List <string>()
         {
             $"jal {label}"
         };
         lines.AddRange(Utils.LoadFromRegister(instance.X, function, "v0"));
         return(new MIPS()
         {
             Functions = lines
         });
     }
     else
     {
         var type    = cil.CilAst.TypeCils.First(x => x.Functions.Contains(instance.Z));
         var element = type.Functions.Single(x => x.Name == instance.Z.Name);
         var index   = type.Functions.ToList().IndexOf(element);
         var lines   = new List <string>(Utils.SaveToRegister(instance.Y, function, "t0"))
         {
             $"lw $t0, ($t0)",         //cargo la direccion del puntero (que es donde esta la direccion del nombre)
             $"add $t0,$t0,-8",        //en -4 esta la cantidad de metodos
             $"lw $t1, ($t0)",         //cargo la cantidad de metodos
             $"mul $t1,$t1,-4",        //desplazamiento hasta el primer metodo
             $"add $t0, $t0, $t1",     //la direccion del primer metodo
             $"add $t0,$t0,{index*4}", //aumentar desplazamiento del metodo buscado
             $"lw $t0,($t0)",          //carga la direccion del metodo
             $"jalr $t0"
         };
         lines.AddRange(Utils.LoadFromRegister(instance.X, function, "v0"));
         return(new MIPS()
         {
             Functions = lines
         });
     }
 }
 public MIPS Visitor(StrCil instance, IFunctionCil function, GenerateToCil cil)
 {
     return(null);
 }
 public CilToMips(GenerateToCil cil)
 {
     Cil       = cil;
     CountArgs = 0;
 }
 private MIPS Selector(IThreeDirIns x, IFunctionCil function, GenerateToCil cil)
 {
     #region Operations
     if (x is SumCil)
     {
         return(Visitor(x as SumCil, function, cil));
     }
     else if (x is RestCil)
     {
         return(Visitor(x as RestCil, function, cil));
     }
     else if (x is MultCil)
     {
         return(Visitor(x as MultCil, function, cil));
     }
     else if (x is DivCil)
     {
         return(Visitor(x as DivCil, function, cil));
     }
     else if (x is EqualCil)
     {
         return(Visitor(x as EqualCil, function, cil));
     }
     else if (x is EqualStringCil)
     {
         return(Visitor(x as EqualStringCil, function, cil));
     }
     else if (x is NotEqualCil)
     {
         return(Visitor(x as NotEqualCil, function, cil));
     }
     else if (x is MinorCil)
     {
         return(Visitor(x as MinorCil, function, cil));
     }
     else if (x is Minor_EqualCil)
     {
         return(Visitor(x as Minor_EqualCil, function, cil));
     }
     else if (x is NegCil)
     {
         return(Visitor(x as NegCil, function, cil));
     }
     #endregion
     #region AssigCil
     else if (x is AssigCil)
     {
         return(Visitor(x as AssigCil, function, cil));
     }
     #endregion
     #region Attribute
     else if (x is GetAttrCil)
     {
         return(Visitor(x as GetAttrCil, function, cil));
     }
     else if (x is SetAttrCil)
     {
         return(Visitor(x as SetAttrCil, function, cil));
     }
     #endregion
     #region MemoryManage
     else if (x is Allocate)
     {
         return(Visitor(x as Allocate, function, cil));
     }
     else if (x is TypeOf)
     {
         return(Visitor(x as TypeOf, function, cil));
     }
     #endregion
     #region Call_function
     else if (x is CallCil)
     {
         return(Visitor(x as CallCil, function, cil));
     }
     else if (x is VCallCil)
     {
         return(Visitor(x as VCallCil, function, cil));
     }
     else if (x is ArgExprCil)
     {
         return(Visitor(x as ArgExprCil, function, cil));
     }
     #endregion
     #region Jump
     else if (x is Label)
     {
         return(Visitor(x as Label, function, cil));
     }
     else if (x is IfGoto)
     {
         return(Visitor(x as IfGoto, function, cil));
     }
     else if (x is GotoCil)
     {
         return(Visitor(x as GotoCil, function, cil));
     }
     #endregion
     #region Return
     else if (x is ReturnCil)
     {
         return(Visitor(x as ReturnCil, function, cil));
     }
     #endregion
     #region String_funcions
     else if (x is LoadCil)
     {
         return(Visitor(x as LoadCil, function, cil));
     }
     else if (x is LenghtCil)
     {
         return(Visitor(x as LenghtCil, function, cil));
     }
     else if (x is ConcatCil)
     {
         return(Visitor(x as ConcatCil, function, cil));
     }
     else if (x is SubStringCil)
     {
         return(Visitor(x as SubStringCil, function, cil));
     }
     else if (x is StrCil)
     {
         return(Visitor(x as StrCil, function, cil));
     }
     #endregion
     #region IO
     else if (x is In_strCil)
     {
         return(Visitor(x as In_strCil, function, cil));
     }
     else if (x is In_intCil)
     {
         return(Visitor(x as In_intCil, function, cil));
     }
     else if (x is Out_strCil)
     {
         return(Visitor(x as Out_strCil, function, cil));
     }
     else if (x is Out_intCil)
     {
         return(Visitor(x as Out_intCil, function, cil));
     }
     #endregion
     #region IsConform
     else if (x is IsNotConformCil)
     {
         return(Visitor(x as IsNotConformCil, function, cil));
     }
     #endregion
     #region Object
     else if (x is Halt)
     {
         return(Visitor(x as Halt, function, cil));
     }
     else if (x is Copy)
     {
         return(Visitor(x as Copy, function, cil));
     }
     else if (x is Type_Name)
     {
         return(Visitor(x as Type_Name, function, cil));
     }
     #endregion
     else
     {
         return(null);
     }
 }