public override bool CheckHeader(List <Scope> scope_list, List <Error> errors) { int cant = errors.Count();//ver los errores que hay hasta el momento if (Utils.IsStandardFunction(scope_list[0], Name)) { errors.Add(new Error(line, column, "Hay una funcion en la libreria estandar con el nombre '" + Name + "'")); } else if (scope_list[scope_list.Count - 1].Vars.ContainsKey(Name) || scope_list[scope_list.Count - 1].Funcs.ContainsKey(Name)) //ver si no hay una funcion o variable con ese nombre { errors.Add(new Error(line, column, "El nombre de la función '" + Name + "' ya esta en uso")); //añado el error } resul = Utils.FindType(scope_list, Retu); if (resul == null) //ver si el "tipo" existe { errors.Add(new Error(line, column, "El tipo de retorno de la función '" + Name + "' no existe")); //añado el error } Dictionary <string, string> e = new Dictionary <string, string>(); //para saber cuales son los parámetros y no repetir TypeReturn temp = null; foreach (var p in Param) { temp = Utils.FindType(scope_list, p.Item2); if (temp == null) //ver si el "tipo" existe { errors.Add(new Error(line, column, "El tipo del parámetro '" + p.Item1 + "' de la función no existe")); //añado el error } else { types.Add(new Tuple <string, Var_Scope>(p.Item1, new Var_Scope(p.Item1, temp))); } if (Param.Where(x => x.Item1 == p.Item1).Count() > 1 && !e.ContainsKey(p.Item1)) //hay mas de uno con el mismo nombre y si no lo he visto { errors.Add(new Error(line, column, "Existe más de un parámetro con el nombre '" + Name + "'")); //añado el error e.Add(p.Item1, p.Item1); //añado el nombre del parámetro al diccionario } } if (cant == errors.Count)//ver si no hubo error { f = new Fun_Scope(Name, types.Select(x => new Tuple <string, TypeReturn>(x.Item1, x.Item2.Var_type)).ToList(), resul); scope_list[scope_list.Count - 1].Funcs.Add(Name, f);//añadir la función al scope return(false); } return(true); }
/// <summary> /// Chequea si una funcion se ha declarado en un ambito determinado y devuelve el tipo de retorno de la funcion (de encontrarse) /// </summary> /// <param name="scope_list">Lista de todos los ambitos de la funcion</param> /// <param name="name">Nombre de la funcion</param> /// <returns>Devuelve el tipo de retorno de la funcion dado su nombre o null si no se encuentra</returns> public static TypeReturn FindFunction(List <Scope> scope_list, string name, out Fun_Scope function, ref int up) { function = null; up = 0; for (int i = scope_list.Count() - 1; i >= 0; i--) //por cada scope { KeyValuePair <string, Fun_Scope> fun = scope_list[i].Funcs.FirstOrDefault(s => s.Key.Equals(name)); //busco si la funcion ya se declaro if (!fun.Equals(default(KeyValuePair <string, Fun_Scope>))) { function = fun.Value; return(function.Retu); } up++; } return(null); //la funcion no esta definida en este scope }