Exemplo n.º 1
0
        //------------------------------------------------------------------------------------------------------------
        private void ifStatement(string[] tokens, int lineNumber)
        {
            // Assume only one token to the left of the comparator  eg.  20 if x == y goto 50
            // [2] = Left, [3] = Comparator, [4] = Right, [5] = 'goto', [6] = LineNumber
            if (!tokens.Contains("goto"))
            {
                throw new SystemException($"'if' statement missing corresponding 'goto' -on code line {lineNumber}");
            }
            string     left = tokens[2];
            string     comparator = tokens[3];
            string     right = tokens[4];
            string     goTo = tokens[5];
            string     gotoLine = tokens[6];
            TableEntry leftEntry, rightEntry;

            //------------------Begin Validations--------Symbol table update------------
            // Validate left of comparator
            if (Int32.TryParse(left, out int intLeft)) // Third token is a number (constant)
            {
                leftEntry = _symbolTable.FindOrAddConst(intLeft);
                _compiledCode.Add(leftEntry.Symbol(), leftEntry.Location());
            }
            else if (Toolbelt.IsValidVariable(left)) // Third token is a valid variable
            {
                char leftVar = Convert.ToChar(left);
                leftEntry = _symbolTable.FindOrAddVar((int)leftVar);
            }
            else
            {
                throw new SystemException($"{left} not valid following 'if' keyword -on code line {lineNumber}");
            }
            // Validate comparator
            if (!Toolbelt.IsComparator(comparator)) // Fourth token is a valid comparator
            {
                throw new SystemException($"{comparator} is is not a valid comparator in 'if' statement -on code line {lineNumber}");
            }
            // Validate left of comparator
            if (Int32.TryParse(right, out int intRight)) // Third token is a number (constant)
            {
                rightEntry = _symbolTable.FindOrAddConst(intRight);
                _compiledCode.Add(rightEntry.Symbol(), rightEntry.Location());
            }
            else if (Toolbelt.IsValidVariable(right)) // Third token is a valid variable
            {
                char rightVar = Convert.ToChar(right);
                rightEntry = _symbolTable.FindOrAddVar((int)rightVar);
            }
            else
            {
                throw new SystemException($"{right} not valid following comparator in 'if' statement -on code line {lineNumber}");
            }
            // validate that 'goto' is in position 5
            if (goTo != "goto")
            {
                throw new SystemException($"Expected 'goto' after comparison in 'if' statement.  ({goTo}) -on code line {lineNumber}");
            }
            // validate that following the 'goto' is a numeric value
            if (!Int32.TryParse(gotoLine, out int intGotoLine))
            {
                throw new SystemException($"'{gotoLine}' invalid token following 'goto' in 'if' statement.  Integer value expected. -on code line {lineNumber}");
            }
            //-------------End Validations--------------------

            if (leftEntry == null || rightEntry == null)
            {
                throw new SystemException($"Unknown error occurred in 'if/goto' statement -on code line {lineNumber}");
            }

            // lookup goto line number in symbol table
            var  gotoLineEntry  = _symbolTable.FindLineNumber(intGotoLine);
            var  gotoLineNumber = 00;
            bool needsFlag      = false;

            if (gotoLineEntry != null)
            {
                gotoLineNumber = gotoLineEntry.Location();
            }
            else
            {
                needsFlag = true;
            }

            // perform calculations with right operand
            // add appropriate branch command

            switch (comparator)
            {
            case "==":
                _compiledCode.Add(Word.Build((int)EPC.Code.LOAD, leftEntry.Location()), _workingLineNumber++);
                _compiledCode.Add(Word.Build((int)EPC.Code.SUBTRACT, rightEntry.Location()), _workingLineNumber++);
                if (needsFlag)
                {
                    _flags.Add(_workingLineNumber, intGotoLine);
                }
                _compiledCode.Add(Word.Build((int)EPC.Code.BRANCHZERO, gotoLineNumber), _workingLineNumber++);
                break;

            case "!=":
                // check if greater than
                _compiledCode.Add(Word.Build((int)EPC.Code.LOAD, rightEntry.Location()), _workingLineNumber++);
                _compiledCode.Add(Word.Build((int)EPC.Code.SUBTRACT, leftEntry.Location()), _workingLineNumber++);
                if (needsFlag)
                {
                    _flags.Add(_workingLineNumber, intGotoLine);
                }
                _compiledCode.Add(Word.Build((int)EPC.Code.BRANCHNEG, gotoLineNumber), _workingLineNumber++);
                // check if less than
                _compiledCode.Add(Word.Build((int)EPC.Code.LOAD, leftEntry.Location()), _workingLineNumber++);
                _compiledCode.Add(Word.Build((int)EPC.Code.SUBTRACT, rightEntry.Location()), _workingLineNumber++);
                if (needsFlag)
                {
                    _flags.Add(_workingLineNumber, intGotoLine);
                }
                _compiledCode.Add(Word.Build((int)EPC.Code.BRANCHNEG, gotoLineNumber), _workingLineNumber++);
                break;

            case "<":
                _compiledCode.Add(Word.Build((int)EPC.Code.LOAD, leftEntry.Location()), _workingLineNumber++);
                _compiledCode.Add(Word.Build((int)EPC.Code.SUBTRACT, rightEntry.Location()), _workingLineNumber++);
                if (needsFlag)
                {
                    _flags.Add(_workingLineNumber, intGotoLine);
                }
                _compiledCode.Add(Word.Build((int)EPC.Code.BRANCHNEG, gotoLineNumber), _workingLineNumber++);
                break;

            case ">":
                _compiledCode.Add(Word.Build((int)EPC.Code.LOAD, rightEntry.Location()), _workingLineNumber++);
                _compiledCode.Add(Word.Build((int)EPC.Code.SUBTRACT, leftEntry.Location()), _workingLineNumber++);
                if (needsFlag)
                {
                    _flags.Add(_workingLineNumber, intGotoLine);
                }
                _compiledCode.Add(Word.Build((int)EPC.Code.BRANCHNEG, gotoLineNumber), _workingLineNumber++);
                break;

            case "<=":
                _compiledCode.Add(Word.Build((int)EPC.Code.LOAD, leftEntry.Location()), _workingLineNumber++);
                _compiledCode.Add(Word.Build((int)EPC.Code.SUBTRACT, rightEntry.Location()), _workingLineNumber++);
                if (needsFlag)
                {
                    _flags.Add(_workingLineNumber, intGotoLine);
                }
                _compiledCode.Add(Word.Build((int)EPC.Code.BRANCHNEG, gotoLineNumber), _workingLineNumber++);
                if (needsFlag)
                {
                    _flags.Add(_workingLineNumber, intGotoLine);
                }
                _compiledCode.Add(Word.Build((int)EPC.Code.BRANCHZERO, gotoLineNumber), _workingLineNumber++);
                break;

            case ">=":
                _compiledCode.Add(Word.Build((int)EPC.Code.LOAD, rightEntry.Location()), _workingLineNumber++);
                _compiledCode.Add(Word.Build((int)EPC.Code.SUBTRACT, leftEntry.Location()), _workingLineNumber++);
                if (needsFlag)
                {
                    _flags.Add(_workingLineNumber, intGotoLine);
                }
                _compiledCode.Add(Word.Build((int)EPC.Code.BRANCHNEG, gotoLineNumber), _workingLineNumber++);
                if (needsFlag)
                {
                    _flags.Add(_workingLineNumber, intGotoLine);
                }
                _compiledCode.Add(Word.Build((int)EPC.Code.BRANCHZERO, gotoLineNumber), _workingLineNumber++);
                break;
            }
        }