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);
        }
Exemplo n.º 3
0
        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>());
        }
Exemplo n.º 4
0
        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);
        }