Пример #1
0
        private List <string> isNumaricAssigment(List <string> AssemblyList, AssignmentStatement aSimple)
        {
            NumericExpression Num = (NumericExpression)(aSimple.Value);
            int value             = Num.Value;

            AssemblyList.Add("@" + value);
            AssemblyList.Add("D = A");
            AssemblyList.Add("@RETURN");
            AssemblyList.Add("M = D");
            computeVariabletoR0(AssemblyList, aSimple.Variable.Name);
            updateDestinationWithResult(AssemblyList);
            return(AssemblyList);
        }
Пример #2
0
 private Expression BinaryExpressionCreate(BinaryOperationExpression exp, ref Stack <Token> sTokens)
 {
     if (sTokens.Peek().Name == "-" || sTokens.Peek().Name == "+")
     {
         exp.Operator = sTokens.Pop().Name;
     }
     else
     {
         throw new SyntaxErrorException("Operator '+' or '-' expected", sTokens.Pop());
     }
     if (sTokens.Peek().Name == "(")
     {
         sTokens.Pop();
         exp.Operand1 = BinaryExpressionCreate(new BinaryOperationExpression(), ref sTokens);
         if (sTokens.Pop().Name != ")")
         {
             throw new SyntaxErrorException("Missing ')' symbol", sTokens.Pop());
         }
     }
     else
     {
         if (Char.IsDigit(sTokens.Peek().Name, 0))
         {
             bool success          = false;
             NumericExpression num = new NumericExpression();
             success = Int32.TryParse(sTokens.Pop().Name, out num.Value);
             if (!success)
             {
                 throw new SyntaxErrorException("Invalid number", sTokens.Pop());
             }
             exp.Operand1 = num;
         }
         else if (Char.IsLetter(sTokens.Peek().Name, 0))
         {
             VariableExpression var2 = new VariableExpression();
             var2.Name    = sTokens.Pop().Name;
             exp.Operand1 = var2;
         }
         else
         {
             throw new SyntaxErrorException("Invalid variable or const", sTokens.Pop());
         }
     }
     if (sTokens.Peek().Name == "(")
     {
         sTokens.Pop();
         exp.Operand2 = BinaryExpressionCreate(new BinaryOperationExpression(), ref sTokens);
         if (sTokens.Pop().Name != ")")
         {
             throw new SyntaxErrorException("Missing ')' symbol", sTokens.Pop());
         }
     }
     else
     {
         if (Char.IsDigit(sTokens.Peek().Name, 0))
         {
             bool success          = false;
             NumericExpression num = new NumericExpression();
             success = Int32.TryParse(sTokens.Pop().Name, out num.Value);
             if (!success)
             {
                 throw new SyntaxErrorException("Invalid number", sTokens.Pop());
             }
             exp.Operand2 = num;
         }
         else if (Char.IsLetter(sTokens.Peek().Name, 0))
         {
             VariableExpression var2 = new VariableExpression();
             var2.Name    = sTokens.Pop().Name;
             exp.Operand2 = var2;
         }
         else
         {
             throw new SyntaxErrorException("Invalid variable or const", sTokens.Pop());
         }
     }
     return(exp);
 }
Пример #3
0
        //Parses a stack of tokens, containing a single assignment statement.
        //The structure must be "let <var> = <expression>;" where expression can be of an arbitrary complexity, i.e., any complex expression is allowed.
        //Parsing must detect syntax problems (e.g. "let" or "=" are missing, opened parantheses are not closed, sentence does not end with a ;, and so forth).
        //When syntax errors are detected, a SyntaxErrorException must be thrown, with an appropriate message explaining the problem.
        public AssignmentStatement Parse(Stack <Token> sTokens)
        {
            Token popedToken = new Token();

            popedToken = sTokens.Pop();
            AssignmentStatement StatmentToReturn  = new AssignmentStatement();
            VariableExpression  variableWorkingOn = new VariableExpression(),
                                SecondVariable    = new VariableExpression();
            NumericExpression num = new NumericExpression();

            if (popedToken.Type != Token.TokenType.Keyword)
            {
                throw new SyntaxErrorException("We accept only LL(0) type, Unrecogmized KeyWord", popedToken);
            }
            popedToken = sTokens.Pop();
            if ((popedToken.Type == Token.TokenType.ID) && (popedToken.Name.ElementAt(0) >= '0') && (popedToken.Name.ElementAt(0) <= '9'))
            {
                throw new SyntaxErrorException("All variables can not start with a number", popedToken);
            }
            else if (popedToken.Name.Contains("?") || popedToken.Name.Contains("#") || popedToken.Name.Contains("@"))
            {
                throw new SyntaxErrorException("Variable can not contain the '?,#,@' signs", popedToken);
            }
            else if ((popedToken.Type != Token.TokenType.ID))
            {
                throw new SyntaxErrorException("Expecting a variable name", popedToken);
            }
            else
            {
                variableWorkingOn.Name    = popedToken.Name;
                StatmentToReturn.Variable = variableWorkingOn;
            }
            popedToken = sTokens.Pop();
            if (!popedToken.Name.Equals("="))
            {
                throw new SyntaxErrorException("Expecting a '=' sign", popedToken);
            }
            popedToken = sTokens.Pop();
            if (Char.IsDigit(popedToken.Name, 0))
            {
                bool success = false;
                success = Int32.TryParse(popedToken.Name, out num.Value);
                if (!success)
                {
                    throw new SyntaxErrorException("Invalid number", popedToken);
                }
                StatmentToReturn.Value = num;
            }
            else if (Char.IsLetter(popedToken.Name, 0))
            {
                SecondVariable.Name    = popedToken.Name;
                StatmentToReturn.Value = SecondVariable;
            }
            else if (popedToken.Name == "(")
            {
                StatmentToReturn.Value = BinaryExpressionCreate(new BinaryOperationExpression(), ref sTokens);
                if ((sTokens.Count > 0))
                {
                    if (sTokens.Pop().Name != ")")
                    {
                        throw new SyntaxErrorException("Missing ')' symbol", popedToken);
                    }
                }
            }
            else
            {
                throw new SyntaxErrorException("Invalid value", popedToken);
            }
            if (sTokens.Count > 1)
            {
                throw new SyntaxErrorException("Invalid value", popedToken);
            }
            if (sTokens.Count == 0 || (sTokens.Count == 1 && (sTokens.Pop().Name != ";")))
            {
                throw new SyntaxErrorException("Expecting ';' at the end of the statement", popedToken);
            }
            if (sTokens.Count > 0)
            {
                throw new SyntaxErrorException("No code after ';'", popedToken);
            }
            return(StatmentToReturn);
        }
Пример #4
0
        private List <string> GenerateCodeForUnaryAssignment(LetStatement aSimple, Dictionary <string, int> dSymbolTable)
        {
            List <string> lAssembly = new List <string>();
            //add here code for computing a single let statement containing only a simple expression
            Expression value = aSimple.Value;

            if (value is NumericExpression)
            {
                lAssembly.Add("//Numeric Value " + aSimple);

                NumericExpression numExp = (NumericExpression)value;

                //next 8 lines rep @var
                lAssembly.Add("@LCL");
                lAssembly.Add("D=M");
                lAssembly.Add("@" + dSymbolTable[aSimple.Variable]);
                lAssembly.Add("D=A+D");//D=a's address
                lAssembly.Add("@_a");
                lAssembly.Add("M=D");
                lAssembly.Add("@" + RESULT);
                lAssembly.Add("M=D");

                lAssembly.Add("@" + numExp.Value);
                lAssembly.Add("D=A");
                lAssembly.Add("@_a");
                lAssembly.Add("A=M");
                lAssembly.Add("M=D");
                lAssembly.Add("@" + RESULT);
                lAssembly.Add("M=D");
            }
            else if (value is VariableExpression)
            {
                lAssembly.Add("//Variable value" + aSimple);

                //Example: let a = b;
                //LCL[a]=LCL[b]
                VariableExpression valExp = (VariableExpression)value;
                int valuesIndex           = dSymbolTable[valExp.ToString()];

                //first store value of LCL[b] in RESULT
                lAssembly.Add("@LCL");
                lAssembly.Add("D=M");
                lAssembly.Add("@" + dSymbolTable[valExp.ToString()]);
                lAssembly.Add("A=D+A");
                lAssembly.Add("D=M");
                lAssembly.Add("@" + RESULT);
                lAssembly.Add("M=D");

                //next store a's address in virtual register "_a"
                lAssembly.Add("@LCL");
                lAssembly.Add("D=M");
                lAssembly.Add("@" + dSymbolTable[valExp.ToString()]);
                lAssembly.Add("D=D+A");
                lAssembly.Add("@_a");
                lAssembly.Add("M=D");

                //update "a"
                lAssembly.Add("@" + RESULT);
                lAssembly.Add("D=M");
                lAssembly.Add("@_a");
                lAssembly.Add("A=M");
                lAssembly.Add("M=D");
            }

            return(lAssembly);
        }
Пример #5
0
        public List <string> GenerateCode(LetStatement aSimple, Dictionary <string, int> dSymbolTable)
        {
            List <string> lAssembly = new List <string>();

            lAssembly.Add("//generation started" + aSimple);

            //add here code for computing a single let statement containing only a simple expression
            Expression value    = aSimple.Value;
            string     variable = aSimple.Variable;

            if (value is NumericExpression | value is VariableExpression)
            {
                lAssembly.AddRange(GenerateCodeForUnaryAssignment(aSimple, dSymbolTable));
            }
            else if (value is BinaryOperationExpression)
            {
                lAssembly.Add("//Binary Expression" + aSimple);
                //
                //Example: a = b <op> c
                //first let a=b
                //next  let a=a <op> c
                //
                BinaryOperationExpression binExp = (BinaryOperationExpression)value;
                Expression   operand1            = binExp.Operand1;
                Expression   operand2            = binExp.Operand2;
                LetStatement letAEqualB          = makeLetStatement(variable, operand1);

                //let a=b
                lAssembly.AddRange(GenerateCodeForUnaryAssignment(letAEqualB, dSymbolTable));
                lAssembly.Add("@" + RESULT);
                lAssembly.Add("D=M");
                lAssembly.Add("@" + OPERAND1);
                lAssembly.Add("M=D");


                //let a = a <op> c
                if (operand2 is NumericExpression)
                {
                    lAssembly.Add("//Opearand 2 is Numeric " + aSimple);

                    NumericExpression num = (NumericExpression)operand2;
                    lAssembly.Add("@" + num.Value);
                    lAssembly.Add("D=A");
                    lAssembly.Add("@_a");
                    lAssembly.Add("M=M" + binExp.Operator + "D");
                    lAssembly.Add("D=M");
                    lAssembly.Add("@" + RESULT);
                    lAssembly.Add("M=D");
                }
                else if (operand2 is VariableExpression)
                {
                    lAssembly.Add("//Opearand 2 is a Variable " + aSimple);

                    VariableExpression c = (VariableExpression)operand2;
                    lAssembly.Add("@LCL");
                    lAssembly.Add("D=M");
                    lAssembly.Add("@" + dSymbolTable[c.Name]);
                    lAssembly.Add("D=M");
                    lAssembly.Add("@" + dSymbolTable[variable]);
                    lAssembly.Add("M=M" + binExp.Operator + "D");
                    lAssembly.Add("D=M");

                    lAssembly.Add("@" + RESULT);
                    lAssembly.Add("M=D");
                }
            }


            return(lAssembly);
        }