コード例 #1
0
        /**
         * Function VisitForStatement : it adds the variable used as a loop counter
         * to the illegalAssigments list and checks that the begin and end value
         * are of type INT. Otherwise it throws an error.
         * Param : for statement to check
         */
        public object VisitForStmt(Stmt.For stmt)
        {
            /* Error when trying to use the var of the main loop in a loop inside it */
            if (illegalAssignments.Contains(stmt.Name.Text))
            {
                throw new TypeError(stmt.Name, "Cannot use '" + stmt.Name.Text + "' as a loop counter since it is already in use as a loop counter.");
            }

            /* Add the loop counter to the illegalAssigments list */
            illegalAssignments.Add(stmt.Name.Text);
            VALTYPE begin = GetType(stmt.BeginValue);
            VALTYPE end   = GetType(stmt.EndValue);

            if (SymbleTypeTable.ContainsKey(stmt.Name.Text))
            {
                VALTYPE loopcounter = SymbleTypeTable[stmt.Name.Text];

                /* The loop counter must be an INT */
                if (loopcounter.Equals(VALTYPE.INT))
                {
                    /* If the begin and end value are INT we check the types of the inside statements */
                    if (begin.Equals(VALTYPE.INT) && end.Equals(VALTYPE.INT))
                    {
                        CheckTypes(stmt.Stmts);
                        illegalAssignments.Remove(stmt.Name.Text);
                        return(null);
                    }
                    /* The begin or the end value were not INT type */
                    else
                    {
                        throw new TypeError(stmt.ForToken, "The begin and end expression should be " + VALTYPE.INT.ToString()
                                            + ", got " + begin.ToString() + " and " + end.ToString() + " instead.");
                    }
                }
                /* Error if the loop counter is not an INT */
                else
                {
                    throw new TypeError(stmt.ForToken, "The loop counter '" + stmt.Name.Text + "' should be " + VALTYPE.INT.ToString()
                                        + ", got " + loopcounter.ToString() + " instead.");
                }
            }
            else
            {
                throw new TypeError(stmt.ForToken, "The loop counter '" + stmt.Name.Text + "' is not previous declared");
            }
        }
コード例 #2
0
ファイル: Interpreter.cs プロジェクト: lurivasm/CompilerMPL
        /**
         * Function VisitForStmt --> "for" <var_ident> "in" <expr> ".." <expr> "do" <stmts> "end" "for"
         * It evaluates the beginning and ending value for the variable and interpret each statement in
         * the list, also it updates the value of the variable used to count in the symble table
         * Also it checks that the loop has at least one statement
         * Param : for statement to evaluate
         */
        public Object VisitForStmt(Stmt.For stmt)
        {
            int    variable;
            string name       = stmt.Name.Text;
            int    beginvalue = (int)Evaluate(stmt.BeginValue).Val;
            int    endvalue   = (int)Evaluate(stmt.EndValue).Val;

            /* At least one statement */
            if (stmt.Stmts.Count == 0)
            {
                throw new RuntimeError(stmt.Name, "For loop must have at least one statement.");
            }
            /* Executing all the statements */
            for (variable = beginvalue; variable <= endvalue; variable++)
            {
                SymbleTable[name] = new Value(VALTYPE.INT, variable);
                foreach (Stmt st in stmt.Stmts)
                {
                    Execute(st);
                }
            }
            return(null);
        }