/** * Function VisitVarStmt --> "var" <var_ident> ":" <type> [ ":=" <expr> ] * It adds the new variable to the SymbleTable * If it already exists throws an error * If it is not initialized we put a default value : 0 for ints, "" for strings * and false for bools * Param : var statement to evaluate */ public Object VisitVarStmt(Stmt.Var stmt) { String name = stmt.Name.Text; VALTYPE type = ExpectedType(stmt); /* Case the variable is already in the symble table */ if (SymbleTable.ContainsKey(name)) { throw new RuntimeError(stmt.Name, "This variable already exists."); } /* Case the variable is not initialized : assign default values */ else if (stmt.Initializer is null) { switch (type) { case VALTYPE.INT: SymbleTable.Add(name, new Value(type, 0)); break; case VALTYPE.STRING: SymbleTable.Add(name, new Value(type, "")); break; case VALTYPE.BOOL: SymbleTable.Add(name, new Value(type, false)); break; } } /* Case the variable is initialized : evaluate the ini expression */ else { SymbleTable.Add(name, Evaluate(stmt.Initializer)); } return(null); }
/** * Function VisitVarStmt : it adds a new variable to the table and checks : * The variable was not previous declared * The variable and the initialized value have the same type * Param : var statement to check */ public object VisitVarStmt(Stmt.Var stmt) { /* Error if the identifier has been initialized before */ if (SymbleTypeTable.ContainsKey(stmt.Name.Text)) { throw new TypeError(stmt.Name, "Cannot initialize " + stmt.Name.Text + " more than once."); } else { /* Check the VALTYPE of the variable and add it to the symble table */ VALTYPE type; switch (stmt.Type) { case TokenKind.Int: type = VALTYPE.INT; break; case TokenKind.String: type = VALTYPE.STRING; break; case TokenKind.Bool: type = VALTYPE.BOOL; break; default: throw new TypeError(stmt.Name, "Expected a type."); } SymbleTypeTable.Add(stmt.Name.Text, type); /* If the variable is gonna be initialized we check the types */ if (stmt.Initializer != null) { VALTYPE right = GetType(stmt.Initializer); if (SymbleTypeTable[stmt.Name.Text].Equals(right)) { return(null); } /* The type of the identifier and the initialized value are not the same */ else { throw new TypeError(stmt.Name, stmt.Name.Text + " is of type " + SymbleTypeTable[stmt.Name.Text] + ", but got " + right.ToString() + " instead."); } } /* The variable is initialized to null so we don't check types */ else { return(null); } } }
/** * Function ExpectedType : it checks the token type of the variable (int, * string or bool) and it returns its corresponding VALTYPE. * Param : var statement to check * Return : the corresponding VALTYPE to each TokenKind or an error */ private VALTYPE ExpectedType(Stmt.Var stmt) { switch (stmt.Type) { case TokenKind.Int: return(VALTYPE.INT); case TokenKind.String: return(VALTYPE.STRING); case TokenKind.Bool: return(VALTYPE.BOOL); default: throw new RuntimeError(stmt.Name, "Cannot declarate " + stmt.Type.ToString() + " as a variable."); } }