public MipsProgram VisitStringConstant(ASTCILStringConstantNode StringConstant)
        {
            var result      = new MipsProgram();
            var stringValue = Regex.Unescape(StringConstant.Value);

            if (!StringConstantGenerated.TryGetValue(StringConstant.Value, out var labelStringConstant))
            {
                result.SectionData.Append(MipsGenerationHelper.NewScript()
                                          .AddData(StringConstant.ObjectLabel,
                                                   new[]
                {
                    MipsGenerationHelper.AddIntData(
                        labelGenerator.GenerateLabelTypeInfo(CompilationUnit.TypeEnvironment.String.Name)),
                    MipsGenerationHelper.AddIntData(StringConstant.ValueLabel),
                    MipsGenerationHelper.AddIntData(stringValue.Length)
                })
                                          .Comment(StringConstant.Value)
                                          .AddData(StringConstant.ValueLabel, new[]
                {
                    MipsGenerationHelper.AddByteData(Regex.Unescape(StringConstant.Value).Select(x => (int)x))
                }));
                StringConstantGenerated.Add(StringConstant.Value, StringConstant.ObjectLabel);
                labelStringConstant = StringConstant.ObjectLabel;
            }

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .LoadFromAddress(MipsRegisterSet.a0, labelStringConstant)
                                      .Add(MipsRegisterSet.a0, 4));
            return(result);
        }
        public MipsProgram VisitAssignment(ASTCILAssignmentNode Assignment)
        {
            var result = Assignment.Expresion.Accept(this);

            var symbolInfo = Assignment.Identifier;

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .Move(MipsRegisterSet.t0, MipsRegisterSet.a0));

            if (symbolInfo.Kind == ObjectKind.Local)
            {
                result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                          .GetLocalAddress(symbolInfo.Offset));
            }
            else
            {
                result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                          .GetParamAddress(symbolInfo.Offset));
            }

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .SaveToMemory(MipsRegisterSet.t0, MipsRegisterSet.a0)
                                      .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0));
            return(result);
        }
        public MipsProgram VisitVoid(ASTCILVoidNode Void)
        {
            var result = new MipsProgram();

            result.SectionCode.Append(MipsGenerationHelper.NewScript().LoadFromAddress(MipsRegisterSet.a0, labelGenerator.GenerateVoid()));
            return(result);
        }
        public MipsProgram VisitStringConcat(ASTCILStringConcatNode stringConcat)
        {
            var tags1  = labelGenerator.GenerateIf();
            var tags2  = labelGenerator.GenerateIf();
            var result = new MipsProgram();

            result.SectionFunctions.Append(MipsGenerationHelper.NewScript()
                                           .Tag(stringConcat.Tag)
                                           .GetParam(MipsRegisterSet.a1, 0)
                                           .GetParam(MipsRegisterSet.a2, 4)
                                           .LoadFromMemory(MipsRegisterSet.t1, MipsRegisterSet.a1, 4)
                                           .LoadFromMemory(MipsRegisterSet.t2, MipsRegisterSet.a2, 4)
                                           .Add(MipsRegisterSet.t2, 1)
                                           .Add(MipsRegisterSet.t1, MipsRegisterSet.t2, MipsRegisterSet.t0)
                                           .Allocate(MipsRegisterSet.t0, MipsRegisterSet.a0)
                                           .LoadFromMemory(MipsRegisterSet.a1, MipsRegisterSet.a1)
                                           .LoadFromMemory(MipsRegisterSet.a2, MipsRegisterSet.a2)
                                           .Copy(MipsRegisterSet.a1, MipsRegisterSet.a0, MipsRegisterSet.t1, tags1.end, tags1.@else)
                                           .Copy(MipsRegisterSet.a2, MipsRegisterSet.a0, MipsRegisterSet.t2, tags2.end, tags2.@else)
                                           .Sub(MipsRegisterSet.a0, MipsRegisterSet.t0)
                                           .Sub(MipsRegisterSet.t0, 1));
            result.SectionFunctions.Append(CreateString(MipsRegisterSet.a0, MipsRegisterSet.t0).SectionCode);
            result.SectionFunctions.Append(MipsGenerationHelper.NewScript()
                                           .Return());
            return(result);
        }
        public MipsProgram VisitFunc(ASTCILFuncNode Func)
        {
            var result = new MipsProgram();
            var body   = new MipsProgram();

            foreach (var item in Func.Body)
            {
                body += item.Accept(this);
            }

            var off = Func.Method.Locals.Count() * 4;

            result.SectionTextGlobals.Append(MipsGenerationHelper.NewScript().GlobalSection(Func.Tag));
            result.SectionFunctions.Append(MipsGenerationHelper.NewScript().Tag(Func.Tag));
            result.SectionFunctions.Append(MipsGenerationHelper.NewScript().Sub(MipsRegisterSet.sp, off, MipsRegisterSet.sp));
            result.SectionFunctions.Append(body.SectionCode);
            if (Func.Boxing)
            {
                var label = labelGenerator.GenerateLabelTypeInfo(Func.BoxingType.Name);
                result.SectionFunctions.Append(MipsGenerationHelper.NewScript().Boxing(label));
            }
            result.SectionFunctions.Append(MipsGenerationHelper.NewScript().Return());

            result.SectionData.Append(body.SectionData);
            return(result);
        }
        public MipsProgram VisitStringSubStr(ASTCILStringSubStrNode stringSubStr)
        {
            var tag1   = labelGenerator.GenerateIf();
            var tag2   = labelGenerator.GenerateIf();
            var tag3   = labelGenerator.GenerateIf();
            var result = new MipsProgram();

            result.SectionFunctions.Append(MipsGenerationHelper.NewScript()
                                           .Tag(stringSubStr.Tag)
                                           .GetParam(MipsRegisterSet.a1, 0)
                                           .LoadFromMemory(MipsRegisterSet.t0, MipsRegisterSet.a1, 4)
                                           .LoadFromMemory(MipsRegisterSet.a1, MipsRegisterSet.a1)
                                           .GetParam(MipsRegisterSet.a2, 4)
                                           .BranchLessThan(MipsRegisterSet.a2, 0, tag1.@else)
                                           .GetParam(MipsRegisterSet.a3, 8)
                                           .BranchLessThan(MipsRegisterSet.a3, 0, tag1.@else)
                                           .Add(MipsRegisterSet.a2, MipsRegisterSet.a3, MipsRegisterSet.t1)
                                           .BranchLessThan(MipsRegisterSet.t0, MipsRegisterSet.t1, tag1.@else)
                                           .Add(MipsRegisterSet.a3, 1, MipsRegisterSet.t1)
                                           .Allocate(MipsRegisterSet.t1, MipsRegisterSet.t0)
                                           .Add(MipsRegisterSet.a1, MipsRegisterSet.a2)
                                           .Copy(MipsRegisterSet.a1, MipsRegisterSet.t0, MipsRegisterSet.a3, tag2.end, tag2.@else)
                                           .SaveByte(MipsRegisterSet.zero, MipsRegisterSet.t0)
                                           .Sub(MipsRegisterSet.t1, 1)
                                           .Sub(MipsRegisterSet.t0, MipsRegisterSet.t1));
            result.SectionFunctions.Append(CreateString(MipsRegisterSet.t0, MipsRegisterSet.t1).SectionCode);
            result.SectionFunctions.Append(MipsGenerationHelper.NewScript()
                                           .Return()
                                           .Tag(tag1.@else)
                                           .ThrowRuntimeError(RuntimeErrors.SubStringOutOfRange, labelGenerator));
            return(result);
        }
        public MipsProgram VisitSelf(ASTCILSelfNode Self)
        {
            var result = new MipsProgram();

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .GetParam(MipsRegisterSet.a0, 0));
            return(result);
        }
        public MipsProgram VisitIntConstant(ASTCILIntConstantNode IntConstant)
        {
            var result = new MipsProgram();

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .LoadConstant(MipsRegisterSet.a0, IntConstant.Value));
            return(result);
        }
        public MipsProgram VisitGoto(ASTCILGotoNode Goto)
        {
            var result = new MipsProgram();

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .JumpToLabel(Goto.Label));
            return(result);
        }
        public MipsProgram VisitBoolNot(ASTCILBoolNotNode BoolNot)
        {
            var result = BoolNot.Expression.Accept(this);

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .Not(MipsRegisterSet.a0));
            return(result);
        }
        public MipsProgram VisitBoolConstant(ASTCILBoolConstantNode BoolConstant)
        {
            var result = new MipsProgram();

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .LoadConstant(MipsRegisterSet.a0,
                                                    BoolConstant.Value ? MipsGenerationHelper.TRUE : MipsGenerationHelper.FALSE));
            return(result);
        }
 public override string ToString()
 {
     return(new StringBuilder().Append(MipsGenerationHelper.NewScript().DataSection())
            .Append(SectionDataGlobals)
            .Append(SectionData)
            .AppendLine()
            .Append(MipsGenerationHelper.NewScript().TextSection()).Append(SectionTextGlobals).Append(SectionCode)
            .Append(SectionFunctions).ToString());
 }
        public MipsProgram VisitBoxing(ASTCILBoxingNode Boxing)
        {
            var result = Boxing.Expression.Accept(this);
            var label  = labelGenerator.GenerateLabelTypeInfo(Boxing.Type.Name);

            result.SectionCode.Append(MipsGenerationHelper.NewScript().Boxing(label));

            return(result);
        }
        public MipsProgram VisitRuntimeError(ASTCILRuntimeErrorNode RuntimeError)
        {
            var result = new MipsProgram();

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .ThrowRuntimeError(RuntimeError.Id, labelGenerator));

            return(result);
        }
        public MipsProgram VisitIOInInt(ASTCILIOInIntNode IOInInt)
        {
            var result = new MipsProgram();

            result.SectionFunctions.Append(MipsGenerationHelper.NewScript()
                                           .Tag(IOInInt.Tag)
                                           .ReadInt(MipsRegisterSet.a0)
                                           .Return());
            return(result);
        }
        public MipsProgram VisitIsVoid(ASTCILIsVoidNode IsVoid)
        {
            var result = IsVoid.Expression.Accept(this);

            var(endLabel, elseLabel, _) = labelGenerator.GenerateIf();
            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .IsVoid(labelGenerator.GenerateVoid(), elseLabel, endLabel));

            return(result);
        }
        public MipsProgram VisitGetAttr(ASTCILGetAttrNode GetAttr)
        {
            var attr_offset = GetAttr.Atribute.Offset;

            var result = new MipsProgram();

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .GetParam(MipsRegisterSet.a0, 0)
                                      .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0, attr_offset));
            return(result);
        }
        public MipsProgram VisitObjectTypeName(ASTCILObjectTypeNameNode objectTypeName)
        {
            var result = new MipsProgram();

            result.SectionFunctions.Append(MipsGenerationHelper.NewScript()
                                           .Tag(objectTypeName.Tag)
                                           .GetParam(MipsRegisterSet.a0, 0)
                                           .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0, MipsGenerationHelper.TypeInfoOffest)
                                           .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0, MipsGenerationHelper.TypeNameOffset)
                                           .Return());
            return(result);
        }
        public MipsProgram VisitIOOutString(ASTCILIOOutStringNode IOOutString)
        {
            var result = new MipsProgram();

            result.SectionFunctions.Append(MipsGenerationHelper.NewScript()
                                           .Tag(IOOutString.Tag)
                                           .GetParam(MipsRegisterSet.a0, 4)
                                           .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0)
                                           .PrintString(MipsRegisterSet.a0)
                                           .GetParam(MipsRegisterSet.a0, 0)
                                           .Return());
            return(result);
        }
        public MipsProgram VisitSetAttribute(ASTCILSetAttributeNode SetAttribute)
        {
            var attr_offset = SetAttribute.Atribute.Offset;

            var result = SetAttribute.Expression.Accept(this);

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .Move(MipsRegisterSet.t0, MipsRegisterSet.a0)
                                      .GetParam(MipsRegisterSet.a0, 0)
                                      .SaveToMemory(MipsRegisterSet.t0, MipsRegisterSet.a0, attr_offset)
                                      .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0, attr_offset));
            return(result);
        }
        public MipsProgram VisitType(ASTCILTypeNode Type)
        {
            var result = new MipsProgram();

            foreach (var method in Type.Methods)
            {
                result += method.Accept(this);
            }

            var typeName        = Type.Type.Name;
            var typeNameParent  = Type.Type.Parent?.Name;
            var label_type_name = labelGenerator.GenerateLabelTypeName(typeName);

            result.SectionData.Append(MipsGenerationHelper.NewScript()
                                      .AddData(label_type_name.value, new[]
            {
                MipsGenerationHelper.AddStringData(typeName)
            }));
            result.SectionData.Append(MipsGenerationHelper.NewScript()
                                      .AddData(label_type_name.@object, new[]
            {
                MipsGenerationHelper.AddIntData(label_type_name.value),
                MipsGenerationHelper.AddIntData(typeName.Length)
            }));

            var label_virtual_table = labelGenerator.GenerateLabelVirtualTable(typeName);

            result.SectionData.Append(MipsGenerationHelper.NewScript()
                                      .AddData(label_virtual_table,
                                               Type.VirtualTable.Select(x =>
                                                                        MipsGenerationHelper.AddIntData(labelGenerator.GenerateFunc(x.Type.Name, x.Name)))));

            var typeInfo_label        = labelGenerator.GenerateLabelTypeInfo(typeName);
            var typeInfo_label_parent = typeNameParent != null?labelGenerator.GenerateLabelTypeInfo(typeNameParent) : labelGenerator.GenerateVoid();

            result.SectionData.Append(MipsGenerationHelper.NewScript()
                                      .AddData(typeInfo_label, new[]
            {
                MipsGenerationHelper.AddIntData(label_type_name.@object),
                MipsGenerationHelper.AddIntData(Type.Type.AllocateSize),
                MipsGenerationHelper.AddIntData(label_virtual_table),
                MipsGenerationHelper.AddIntData(typeInfo_label_parent)
            }));

            result.SectionDataGlobals.Append(MipsGenerationHelper.NewScript().GlobalSection(label_type_name.value)
                                             .GlobalSection(label_type_name.@object)
                                             .GlobalSection(label_virtual_table).GlobalSection(typeInfo_label));

            return(result);
        }
        public MipsProgram VisitMultiplyTwoVariables(ASTCILMultiplyTwoVariablesNode MultiplyTwoVariables)
        {
            var left = MultiplyTwoVariables.Left.Accept(this);

            left.SectionCode.Append(MipsGenerationHelper.NewScript()
                                    .Push(MipsRegisterSet.a0));

            var right = MultiplyTwoVariables.Right.Accept(this);

            right.SectionCode.Append(MipsGenerationHelper.NewScript()
                                     .Pop(MipsRegisterSet.t0)
                                     .Mul(MipsRegisterSet.a0, MipsRegisterSet.t0));

            return(left + right);
        }
        public MipsProgram VisitAllocate(ASTCILAllocateNode Allocate)
        {
            var label = labelGenerator.GenerateLabelTypeInfo(Allocate.Type.Name);

            var result = new MipsProgram();

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .LoadFromAddress(MipsRegisterSet.t0, label)
                                      .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.t0, MipsGenerationHelper.SizeOfOffset)
                                      .Add(MipsRegisterSet.a0, 4)
                                      .Allocate(MipsRegisterSet.a0, MipsRegisterSet.a0)
                                      .SaveToMemory(MipsRegisterSet.t0, MipsRegisterSet.a0)
                                      .Add(MipsRegisterSet.a0, 4));
            return(result);
        }
        public MipsProgram VisitObjectCopy(ASTCILObjectCopyNode objectCopy)
        {
            var result       = new MipsProgram();
            var tags         = labelGenerator.GenerateIf();
            var boolTypeInfo = labelGenerator.GenerateLabelTypeInfo(CompilationUnit.TypeEnvironment.Bool.Name);
            var IntTypeInfo  = labelGenerator.GenerateLabelTypeInfo(CompilationUnit.TypeEnvironment.Int.Name);
            var intLabel     = labelGenerator.GenerateIf();
            var boolLabel    = labelGenerator.GenerateIf();

            result.SectionFunctions.Append(MipsGenerationHelper.NewScript()
                                           .Tag(objectCopy.Tag)
                                           .GetParam(MipsRegisterSet.a0, 0)                      // a0<- self
                                           .LoadFromMemory(MipsRegisterSet.t0, MipsRegisterSet.a0,
                                                           MipsGenerationHelper.TypeInfoOffest)  //t0 <- self.type_info
                                           .LoadFromMemory(MipsRegisterSet.t1, MipsRegisterSet.t0,
                                                           MipsGenerationHelper.SizeOfOffset)    //t1 <- self.size
                                           .Add(MipsRegisterSet.t1, 4)
                                           .Allocate(MipsRegisterSet.t1, MipsRegisterSet.a0)     //a0<- new (allocate does not use t0 or t1)
                                           .SaveToMemory(MipsRegisterSet.t0, MipsRegisterSet.a0) //putting self.typeInfo in a0 typeinfo area
                                           .Add(MipsRegisterSet.a0, 4, MipsRegisterSet.t0)       //to copy in t0
                                           .Sub(MipsRegisterSet.t1, 4)                           //Size Copy in t1
                                           .Move(MipsRegisterSet.a2, MipsRegisterSet.t1)
                                           .GetParam(MipsRegisterSet.a0, 0)                      //From copy (self in a0)
                                           .Copy(MipsRegisterSet.a0, MipsRegisterSet.t0, MipsRegisterSet.t1, tags.end,
                                                 tags.@else)                                     //word to word copy
                                           .Sub(MipsRegisterSet.t0, MipsRegisterSet.a2, MipsRegisterSet.a0)
                                           .Move(MipsRegisterSet.a2, MipsRegisterSet.a0)
                                           .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0, MipsGenerationHelper.TypeInfoOffest)
                                           .LoadFromAddress(MipsRegisterSet.t0, IntTypeInfo)
                                           .BranchOnEquals(MipsRegisterSet.a0, MipsRegisterSet.t0, intLabel.@else)
                                           .JumpToLabel(intLabel.end)
                                           .Tag(intLabel.@else)
                                           .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a2)
                                           .Return()
                                           .Tag(intLabel.end)
                                           .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0, MipsGenerationHelper.TypeInfoOffest)
                                           .LoadFromAddress(MipsRegisterSet.t0, boolTypeInfo)
                                           .BranchOnEquals(MipsRegisterSet.a0, MipsRegisterSet.t0, boolLabel.@else)
                                           .JumpToLabel(boolLabel.end)
                                           .Tag(boolLabel.@else)
                                           .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a2)
                                           .Return()
                                           .Tag(boolLabel.end)
                                           .Move(MipsRegisterSet.a0, MipsRegisterSet.a2)
                                           .Return());
            return(result);
        }
        public MipsProgram VisitEqualString(ASTCILEqualStringNode EqualString)
        {
            var left = EqualString.Left.Accept(this);

            left.SectionCode.Append(MipsGenerationHelper.NewScript()
                                    .Push(MipsRegisterSet.a0));

            var right = EqualString.Right.Accept(this);

            right.SectionCode.Append(MipsGenerationHelper.NewScript()
                                     .Push(MipsRegisterSet.a0)
                                     .LoadFromAddress(MipsRegisterSet.a0, MipsGenerationHelper.StringEqualsLabel)
                                     .Call(MipsRegisterSet.a0)
                                     .Pop(MipsRegisterSet.a1)
                                     .Pop(MipsRegisterSet.a1));

            return(left + right);
        }
        public MipsProgram VisitId(ASTCILIdNode Id)
        {
            var info   = Id.Name;
            var result = new MipsProgram();

            if (info.Kind == ObjectKind.Local)
            {
                result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                          .GetLocal(info.Offset));
            }

            if (info.Kind == ObjectKind.Parameter)
            {
                result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                          .GetParam(MipsRegisterSet.a0, info.Offset));
            }

            return(result);
        }
        public MipsProgram VisitFuncVirtualCall(ASTCILFuncVirtualCallNode FuncVirtualCall)
        {
            var result = new MipsProgram();
            var cant   = FuncVirtualCall.Arguments.Count;

            result.SectionCode.Append(MipsGenerationHelper.NewScript().Sub(MipsRegisterSet.sp, 4 * cant));
            for (int i = 0; i < cant; i++)
            {
                result += FuncVirtualCall.Arguments[i].Accept(this);    // leave in a0 expresion result
                if (i == 0)
                {
                    var(endLabel, elseLabel, _) = labelGenerator.GenerateIf();
                    result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                              .LoadFromAddress(MipsRegisterSet.t0, labelGenerator.GenerateVoid())
                                              .BranchOnEquals(MipsRegisterSet.t0, MipsRegisterSet.a0, elseLabel)
                                              .JumpToLabel(endLabel)
                                              .Tag(elseLabel)
                                              //.LoadConstant(MipsRegisterSet.a0, MipsGenerationHelper.TRUE) TODO: throw void execption dispatch
                                              .Tag(endLabel));
                }
                result.SectionCode.Append(MipsGenerationHelper.NewScript().SaveToMemory(MipsRegisterSet.a0, MipsRegisterSet.sp, 4 * (i)));
            }

            // moving self to a0
            result.SectionCode.Append(MipsGenerationHelper.NewScript().LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.sp));
            //loading self.typeInfo in a0
            result.SectionCode.Append(MipsGenerationHelper.NewScript().LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0, MipsGenerationHelper.TypeInfoOffest));
            //loading typeInfo.virtual_table in a0
            result.SectionCode.Append(MipsGenerationHelper.NewScript().LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0, MipsGenerationHelper.VirtualTableOffset));
            var virtualTable  = CompilationUnit.MethodEnvironment.GetVirtualTable(FuncVirtualCall.Type);
            var virtualMethod = virtualTable.Single(x => x.Name == FuncVirtualCall.MethodName);
            int index         = virtualTable.IndexOf(virtualMethod);
            int offset        = 4 * index;

            // loading virtual_table.f in a0
            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.a0, offset)
                                      .Call(MipsRegisterSet.a0)
                                      .Add(MipsRegisterSet.sp, cant * 4));

            return(result);
        }
        public MipsProgram VisitLessThanTwoVariables(ASTCILLessThanTwoVariablesNode LessThanTwoVariables)
        {
            (string end_label, string else_label, _) = labelGenerator.GenerateIf();

            var left = LessThanTwoVariables.Left.Accept(this);

            left.SectionCode.Append(MipsGenerationHelper.NewScript()
                                    .Push(MipsRegisterSet.a0));

            var right = LessThanTwoVariables.Right.Accept(this);

            right.SectionCode.Append(MipsGenerationHelper.NewScript()
                                     .Pop(MipsRegisterSet.t0)
                                     .BranchLessThan(MipsRegisterSet.t0, MipsRegisterSet.a0, else_label)
                                     .LoadConstant(MipsRegisterSet.a0, 0)
                                     .JumpToLabel(end_label)
                                     .Tag(else_label)
                                     .LoadConstant(MipsRegisterSet.a0, 1)
                                     .Tag(end_label));
            return(left + right);
        }
        private MipsProgram CreateString(Register r1, Register r2)
        {
            string label_info = labelGenerator.GenerateLabelTypeInfo(Types.String);
            var    result     = new MipsProgram();

            if (r2 == MipsRegisterSet.t1)
            {
                if (r1 == MipsRegisterSet.t2)
                {
                    result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                              .Move(MipsRegisterSet.t0, r1)
                                              .Move(MipsRegisterSet.t2, r2)
                                              .Move(MipsRegisterSet.t1, MipsRegisterSet.t0));
                }
                else
                {
                    result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                              .Move(MipsRegisterSet.t2, r2)
                                              .Move(MipsRegisterSet.t1, r1));
                }
            }
            else
            {
                result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                          .Move(MipsRegisterSet.t1, r1)
                                          .Move(MipsRegisterSet.t2, r2));
            }

            result.SectionCode.Append(MipsGenerationHelper.NewScript()
                                      .LoadFromAddress(MipsRegisterSet.t0, label_info)
                                      .LoadFromMemory(MipsRegisterSet.a0, MipsRegisterSet.t0, MipsGenerationHelper.SizeOfOffset)
                                      .Add(MipsRegisterSet.a0, 4)
                                      .Allocate(MipsRegisterSet.a0, MipsRegisterSet.a0)
                                      .SaveToMemory(MipsRegisterSet.t0, MipsRegisterSet.a0)
                                      .Add(MipsRegisterSet.a0, 4)
                                      .SaveToMemory(MipsRegisterSet.t1, MipsRegisterSet.a0)
                                      .SaveToMemory(MipsRegisterSet.t2, MipsRegisterSet.a0, 4));
            return(result);
        }
        public MipsProgram VisitIOInString(ASTCILIOInStringNode IOInString)
        {
            var tags   = labelGenerator.GenerateIf();
            var result = new MipsProgram();

            result.SectionFunctions.Append(MipsGenerationHelper.NewScript()
                                           .Tag(IOInString.Tag)
                                           .ReadString()
                                           .StringLengthMethod()
                                           .Move(MipsRegisterSet.t0, MipsRegisterSet.a0)
                                           .LoadFromAddress(MipsRegisterSet.a1, MipsGenerationHelper.BufferLabel)
                                           .Add(MipsRegisterSet.a0, 1)
                                           .Allocate(MipsRegisterSet.a0, MipsRegisterSet.a2)
                                           .Copy(MipsRegisterSet.a1, MipsRegisterSet.a2, MipsRegisterSet.a0, tags.end, tags.@else)
                                           .Sub(MipsRegisterSet.a2, 1)
                                           .Sub(MipsRegisterSet.a2, MipsRegisterSet.t0));

            result.SectionFunctions.Append(CreateString(MipsRegisterSet.a2, MipsRegisterSet.t0).SectionCode);
            result.SectionFunctions.Append(MipsGenerationHelper.NewScript()
                                           .Return());
            return(result);
        }