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