public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors) { countOfClicles++; bool problem = false; //para no meter una variable que esta mal en el Scope //hay que ver que no exista una variable ni una funcion con el mismo nombre que la del for foreach (Scope scope in scope_list) { if (scope.Vars.Any(s => s.Key.Equals(this.Name))) //pregunto por las variables { errors.Add(new Error(line, column, "Ya existe una variable con el nombre: " + Name)); problem = true; //no puedo anadirla porque ya existe } else if (scope.Funcs.Any(s => s.Key.Equals(this.Name))) //pregunto por las funciones { errors.Add(new Error(line, column, "Ya existe una funcion con el nombre: " + Name)); problem = true; //no puedo anadirla porque ya existe } } TypeReturn typeOfAsign = Asig.CheckSemantics(scope_list, errors); if (!(typeOfAsign is ReturnInt)) { errors.Add(new Error(line, column, "La expresion de asignacion debe retonar un entero")); problem = true; //no puedo anadirla porque la variable no es un entero } TypeReturn typeOfTo = To.CheckSemantics(scope_list, errors); if (!(typeOfTo is ReturnInt)) { errors.Add(new Error(line, column, "La expresion del To debe retornar un entero")); } if (!problem) //si no preguntara esto podria estar anadiendo una variable con problemas al Scope (en el Scope no hay nada con errores!) { varFor = new Var_Scope(Name, typeOfAsign, true); Dictionary <string, Var_Scope> param = new Dictionary <string, Var_Scope>(); param.Add(Name, varFor); Scope scopeBodyFor = new Scope(param, new Dictionary <string, TypeReturn>(), new Dictionary <string, Fun_Scope>()); //el scope para la variable del for scope_list.Add(scopeBodyFor); //agrego la variable del for a la lista de scope para que el body del for pueda verla //if(Body!=null) TypeReturn typeOfBody = Body.CheckSemantics(scope_list, errors); if (!(typeOfBody is ReturnNotValue)) { errors.Add(new Error(line, column, "La expresion del body del for no debe devolver nada")); } scope_list.Remove(scopeBodyFor); //remuevo la variable del for } countOfClicles--; return(new ReturnNotValue()); }
public override TypeReturn CheckSemantics(List <Scope> scope_list, List <Error> errors) { int cant = errors.Count;//me da la cant de errores que hay hasta el momento TypeReturn typeOfAsign = Asig.CheckSemantics(scope_list, errors); TypeReturn typeVar; if (typeOfAsign == null) //cuando no existe la asignación { return(new ReturnNotValue()); } if (VarType == null) //no tiene tipo la variable { if ((typeOfAsign is ReturnNil) || (typeOfAsign is ReturnNotValue)) //si es nil o no retorna valor no se puede inferir el tipo { errors.Add(new Error(line, column, "No se puede inferir el tipo")); return(new ReturnNotValue()); } //Var_type = typeOfAsign.ToString(); //se infiere el tipo typeVar = typeOfAsign; } //tiene tipo la variable (VarType!=null) else { typeVar = Utils.FindType(scope_list, VarType); //busco el tipo de la variable if (typeVar == null) { errors.Add(new Error(line, column, "El tipo de la variable '" + Name + "' no existe")); //añado el error return(null); } // el tipo de la variable existe if (typeOfAsign is ReturnNil) //pregunto si la asignacion es nil y el Lvalue permite nil { if (typeVar is ReturnInt) { errors.Add(new Error(line, column, "No se le puede asignar un '" + typeOfAsign.ToString() + "' a un '" + typeVar + "'")); //añado el error } } else if (!typeVar.Equals(typeOfAsign)) { errors.Add(new Error(line, column, "No se le puede asignar un '" + typeOfAsign.ToString() + "' a un '" + typeVar + "'")); //añado el error } } if (scope_list[scope_list.Count - 1].Vars.ContainsKey(Name) || scope_list[scope_list.Count - 1].Funcs.ContainsKey(Name)) //ver si hay una funcion o una variable con ese nombre { errors.Add(new Error(line, column, "El nombre de la variable '" + Name + "' ya esta en uso")); //añado el error } if (cant == errors.Count) //si no hubo errores { v = new Var_Scope(Name, typeVar); scope_list[scope_list.Count - 1].Vars.Add(Name, v); //añado la variable al scope } return(new ReturnNotValue()); }