public ProgramChunkJumpUnconditional(ProgramChunkJumpTarget myTarget)
 {
     Target = myTarget;
 }
Beispiel #2
0
 public void AddOrphanJumpTarget(ProgramChunkJumpTarget target)
 {
     ProgramOrphanJumpTargets.AddLast(((IProgramChunk)target));
 }
Beispiel #3
0
 public void RemoveOrphanJumpTarget(ProgramChunkJumpTarget target)
 {
     ProgramOrphanJumpTargets.Remove(target);
 }
Beispiel #4
0
        /// <summary>
        /// Translates a line of MIPS assembly into the intermediate format and returns
        /// the result.
        /// </summary>
        /// <param name="assembly">MIPS assembly.</param>
        /// <param name="parentBlock">ProgramBlock containing previously translated code
        /// and associated information</param>
        /// <returns>Translated chunk.</returns>
        public IProgramChunk TranslateLine(string assembly, ProgramBlock parentBlock)
        {
            IProgramChunk translatedChunk = null;

            //***LABELS***
            if (assembly.Contains(":"))
            {
                string labelName = assembly.Substring(0, assembly.IndexOf(":"));

                //label does not exist as an orphan
                if(parentBlock.GetOrphanJumpTargetByLabel(labelName) == null)
                    translatedChunk = new ProgramChunkJumpTarget(labelName);
                //label does exist as an orphan.
                else
                {
                    translatedChunk = parentBlock.GetOrphanJumpTargetByLabel(labelName);
                    parentBlock.RemoveOrphanJumpTarget(parentBlock.GetOrphanJumpTargetByLabel(labelName));
                }
            }
            //**KEYWORDS**
            else
            {
                string lineKeyword = assembly.Split(' ')[0];
                string[] lineParameters = assembly.Substring(assembly.IndexOf(' ') + 1).Split(' ');

                switch (lineKeyword)
                {
                    #region J - Unconditional Jump
                    case "j":
                    {
                        ProgramChunkJumpTarget target = parentBlock.GetJumpTargetByLabel(lineParameters[0]);

                        //label does not exist but should be defined later. create an orphan placeholder.
                        if (target == null)
                        {
                            target = new ProgramChunkJumpTarget(lineParameters[0]);
                            parentBlock.AddOrphanJumpTarget(target);
                        }

                        translatedChunk = new ProgramChunkJumpUnconditional(target);
                    }
                    break;
                    #endregion

                    #region Form: (command) product, multiplicand, multiplier

                    case "addi":
                    case "add":
                    case "sllv"://SLL - Shift Left Logical (variable)
                    case "sll": //SLL - Shift Left Logical (constant)
                    case "sub":
                    case "subi":
                        //Form: (command) product, multiplicand, multiplier
                        //see below (or above i guess) to see acceptable commands

                        //Addition: 'add', and 'addi' (default)
                        Operand commandOperand = Operand.ADDITION;

                        //Multiplication: 'sll', and 'sllv'
                        if(lineKeyword.Equals("sll") || lineKeyword.Equals("sllv"))
                            commandOperand = Operand.MULTIPLICATION;

                        //Subtraction: 'sub', and 'subi'
                        if(lineKeyword.Equals("sub") || lineKeyword.Equals("subi"))
                            commandOperand = Operand.SUBTRACTION;

                        BlockVariable termAssignee;  //must be variable
                        ProgramChunkExpressionTerm termMultiplicand;//constant or variable? I think the doc only support var's
                        ProgramChunkExpressionTerm termMultiplier; //constant or variable

                        #region 1) find assignee

                        if (IsVariable(lineParameters[0]))
                        {
                            ProcessVariable(ref lineParameters[0]);

                            BlockVariable variable = parentBlock.GetVariableByNameForced(lineParameters[0]);

                            termAssignee = variable;
                        }
                        else
                            throw new Exception("FrontendMIPS - Detected attempt to assign expression to constant.");

                        #endregion

                        #region 2) find multiplicand

                        if (IsVariable(lineParameters[1]))
                        {
                            ProcessVariable(ref lineParameters[1]);

                            BlockVariable variable = parentBlock.GetVariableByNameForced(lineParameters[1]);

                            termMultiplicand = variable;
                        }
                        else //The first (real) term is a constant
                        {
                            //CHECKME: attempt to parse hex numbers, does it work this way?
                            int term = int.Parse(lineParameters[1], System.Globalization.NumberStyles.HexNumber);

                            termMultiplicand = new BlockConstant(term);
                        }

                        #endregion

                        #region 3) find multiplier

                        if (IsVariable(lineParameters[2]))
                        {
                            ProcessVariable(ref lineParameters[2]);

                            BlockVariable variable = parentBlock.GetVariableByNameForced(lineParameters[2]);

                            termMultiplier = variable;
                        }
                        else//constant
                        {
                            //TODO: support hex numbers
                            if(lineParameters[2].Contains("x"))
                                throw new Exception("FrontendMIPS - Cannot parse hexidecimal numbers.");

                            int term = int.Parse(lineParameters[2]);

                            //deal with bit shifts
                            if (lineKeyword.Equals("sll"))
                                term *= 2;
                            else if (lineKeyword.Equals("sllv"))
                                throw new Exception("FrontendMIPS - Cannot bit shift by variable without subexpression support.");

                            termMultiplier = new BlockConstant(term);
                        }

                        #endregion

                        ProgramChunkExpression expression = new ProgramChunkExpression(termMultiplicand, commandOperand, termMultiplier);

                        translatedChunk = new ProgramChunkAssignment(termAssignee, expression);
                        break;
                    #endregion

                    #region Branchs (BNE, BEQ)

                    //Form: if (var equality var) goto label.
                    //e.g. "beq $a1 0 finish"
                    case "bne":
                    case "beq":
                    {
                        Equality equality;
                        ProgramChunkExpressionTerm first;
                        ProgramChunkExpressionTerm second;
                        ProgramChunkJumpTarget target;

                        #region 1) determine equality

                        if (lineKeyword.Equals("bne"))
                            equality = Equality.NOT_EQUAL;
                        else if (lineKeyword.Equals("beq"))
                            equality = Equality.EQUAL;
                        else
                            throw new Exception("FrontendMIPS - Unimplemented equality found.");

                        #endregion

                        #region 2) find first item to evaluate

                        if (IsVariable(lineParameters[0]))
                        {
                            ProcessVariable(ref lineParameters[0]);
                            first = parentBlock.GetVariableByNameForced(lineParameters[0]);
                        }
                        else //constant
                        {
                            //TODO: support hex numbers
                            if (lineParameters[0].Contains("x"))
                                throw new Exception("FrontendMIPS - Cannot parse hexidecimal numbers.");

                            first = new BlockConstant(int.Parse(lineParameters[0]));
                        }

                        #endregion

                        #region 3) find second item to evaluate

                        if (IsVariable(lineParameters[1]))
                        {
                            ProcessVariable(ref lineParameters[1]);
                            second = parentBlock.GetVariableByNameForced(lineParameters[1]);
                        }
                        else //constant
                        {
                            //TODO: support hex numbers
                            if (lineParameters[1].Contains("x"))
                                throw new Exception("FrontendMIPS - Cannot parse hexidecimal numbers.");

                            second = new BlockConstant(int.Parse(lineParameters[1]));
                        }

                        #endregion

                        #region 4) generate jump for true

                        target = parentBlock.GetJumpTargetByLabel(lineParameters[2]);

                        //label does not exist but should be defined later. create an orphan placeholder.
                        if (target == null)
                        {
                            target = new ProgramChunkJumpTarget(lineParameters[2]);
                            parentBlock.AddOrphanJumpTarget(target);
                        }

                        #endregion

                        translatedChunk = new ProgramChunkBranch(equality, first, new ProgramChunkJumpUnconditional(target), second, new ProgramChunkNoOperation());
                    }
                    break;

                    #endregion
                }
            }

            if (translatedChunk == null)
            {
                translatedChunk = new ProgramChunkNoOperation();
                UtilDebugConsole.AddException(new Exception("FrontendMIPS - Unidentified assembly encountered during translation."));
            }

            return translatedChunk;
        }