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); }
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); }
//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); }
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); }
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); }