public override List <string> ExecuteSemanticAction(Stack <SemanticRecord> semanticRecordTable, Stack <SymbolTable> symbolTable, IToken lastToken, MoonCodeResult moonCode) { List <string> errors = new List <string>(); if (!semanticRecordTable.Any()) { errors.Add(string.Format("Grammar error at line {0}, semantic stack empty with creating a put command", lastToken.getLine())); return(errors); } ExpressionRecord expr = semanticRecordTable.Pop() as ExpressionRecord; if (expr == null) { errors.Add(string.Format("Grammar error at line {0}, can only put expressions", lastToken.getLine())); return(errors); } if (!symbolTable.Any() || symbolTable.Peek().getParent() == null) { errors.Add(string.Format("Cannot place put command in empty scope")); return(errors); } moonCode.AddLine(symbolTable.Peek().getParent().getAddress(), string.Format(@" lw r2, {0}(r0) putc r2 ", expr.GetAddress())); return(errors); }
public override List <string> ExecuteSemanticAction(Stack <SemanticRecord> semanticRecordTable, Stack <SymbolTable> symbolTable, IToken lastToken, MoonCodeResult moonCode) { LinkedList <ExpressionRecord> expressions = new LinkedList <ExpressionRecord>(); List <string> errors = new List <string>(); // Accumulate the last two expressions on the semantic stack while (expressions.Count < 2) { if (!semanticRecordTable.Any()) { errors.Add(string.Format("Grammar error: Not enough expressions to validate assignment at line {0}", lastToken.getLine())); return(errors); } SemanticRecord lastRecord = semanticRecordTable.Pop(); if (lastRecord.recordType != RecordTypes.ExpressionType) { errors.Add(string.Format("Grammar error, expression validation at line {0} encountered an illegal record: \"{1}\"", lastToken.getLine(), lastRecord.recordType.ToString())); continue; } expressions.AddLast((ExpressionRecord)lastRecord); } // The first expression is the value we are reading // while the second one is the expression we are writing to ExpressionRecord type1 = expressions.First.Value; ExpressionRecord type2 = expressions.Last.Value; if (type1.GetExpressionType() != type2.GetExpressionType()) { errors.Add(string.Format("Cannot equate at line {0} a value of type {1} to {2}", lastToken.getLine(), type1.GetExpressionType().getName(), type2.GetExpressionType().getName())); } SymbolTable currentScope = symbolTable.Peek(); string outAddress = string.Empty; if (currentScope.getParent() == null) { errors.Add(string.Format("Cannot perform an assignment operation outside of a function")); } else { // Generate the code to read and store the value moonCode.AddLine(currentScope.getParent().getAddress(), string.Format(@" lw r2, {0}(r0) sw {1}(r0), r2 ", type1.GetAddress(), type2.GetAddress())); } return(errors); }
public override List <string> ExecuteSemanticAction(Stack <SemanticRecord> semanticRecordTable, Stack <SymbolTable> symbolTable, IToken lastToken, MoonCodeResult moonCode) { List <string> errors = new List <string>(); if (symbolTable.Any() && symbolTable.Peek().getParent() != null) { moonCode.AddLine(symbolTable.Peek().getParent().getAddress(), line); } else { errors.Add(string.Format("Grammar error: Could not generate the requested code \"{0}\" at line {1}", line, lastToken.getLine())); } return(new List <string>()); }
public override List <string> ExecuteSemanticAction(Stack <SemanticRecord> semanticRecordTable, Stack <SymbolTable> symbolTable, IToken lastToken, MoonCodeResult moonCode) { Token op = null; LinkedList <ExpressionRecord> expressions = new LinkedList <ExpressionRecord>(); List <string> errors = new List <string>(); // Accumulate the two last expressions on the semantic stack while (expressions.Count < 2) { if (!semanticRecordTable.Any()) { errors.Add(string.Format("Grammar error: Not enough expressions to validate arithmetic operation at line {0}", lastToken.getLine())); return(errors); } SemanticRecord record = semanticRecordTable.Pop(); BasicTokenRecord tokenRec = record as BasicTokenRecord; if (tokenRec != null) { // Save the token representing the operation op = tokenRec.getToken(); continue; } if (record is ExpressionRecord) { expressions.AddLast(record as ExpressionRecord); } else { errors.Add(string.Format("Grammar error: record {0} at line {1} is not allowed during an arithmetic expression validation", record.recordType.ToString(), lastToken.getLine())); } } ExpressionRecord type1 = expressions.Last.Value; ExpressionRecord type2 = expressions.First.Value; // Ensure that both expressions are integers if (type1.GetExpressionType() != AddTypeToList.intClass || type2.GetExpressionType() != AddTypeToList.intClass) { errors.Add(string.Format("Cannot perform arithmetic operation at line {0} between factors of type {1} and {2}" , lastToken.getLine(), type1.GetExpressionType().getName(), type2.GetExpressionType().getName())); } SymbolTable currentScope = symbolTable.Peek(); string outAddress = string.Empty; if (currentScope.getParent() == null) { errors.Add(string.Format("Cannot perform an arithemetic operation outside of a function")); } else if (op == TokenList.And || op == TokenList.Or) { // Generate an address for the result of this sub-expression outAddress = Entry.MakeAddressForEntry(currentScope.getParent(), "arithmExpr"); // Get a unique id for the jump label string jumpId = IDGenerator.GetNext(); // Generate the code to perform a logic "and" or "or" instead of bitwise moonCode.AddGlobal(string.Format("{0} dw 0", outAddress)); moonCode.AddLine(currentScope.getParent().getAddress(), string.Format(@" lw r3, {0}(r0) lw r4, {1}(r0) {2} r2, r3, r4 bz r2, zero_{4} addi r2, r0, 1 sw {3}(r0), r2 j endop_{4} zero_{4} sw {3}(r0), r0 endop_{4} ", type1.GetAddress(), type2.GetAddress(), opLists[op], outAddress, jumpId)); } else { // Generate an address for the result of this sub-expression outAddress = Entry.MakeAddressForEntry(currentScope.getParent(), "arithmExpr"); // Generate code for a mathematical or relational expression moonCode.AddGlobal(string.Format("{0} dw 0", outAddress)); moonCode.AddLine(currentScope.getParent().getAddress(), string.Format(@" lw r3, {0}(r0) lw r4, {1}(r0) {2} r2, r3, r4 sw {3}(r0), r2 ", type1.GetAddress(), type2.GetAddress(), opLists[op], outAddress)); } // Place the resulting expression on the semantic stack semanticRecordTable.Push(new ExpressionRecord(AddTypeToList.intClass, outAddress)); return(errors); }