/// <summary> /// Modifica un símbolo existente en la tabla /// </summary> /// <param name="idAmbito">Número identificador del ámbito actual</param> /// <param name="name">Nombre de la variable que se modifica</param> /// <param name="newValue">Nuevo valor para la variable</param> public void Update(string idAmbito, string name, string newValue) { TDSobj aux = Search(idAmbito, name); if (aux != null) { string key = idAmbito + "," + name; aux.value = newValue; string value = aux.type.ToString() + "|" + aux.value + "|" + aux._base + "|"; if (aux.args != null) { foreach (var item in aux.args) { /* Debido a que los id de tipos se identifican con números del 0 al 5 * es posible únicamente concatenarlos y separarlos por caracter para análisis */ value += item.ToString(); } } else { value += "NULL"; } table[key] = value; } else { this.err += "\nNo se pudo encontrar la variable " + name + "en el ámbito actual"; } }
/// <summary> /// Compara los tipos de los parámetros de una función con los parámetros enviados /// </summary> /// <param name="idAmbito">Número identificador del ámbito actual</param> /// <param name="funcName">Nombre de la función</param> /// <param name="sendedArgs">Arreglo de tipos de los parámetros enviados</param> /// <returns>true si los argumentos son del mismo tipo y en la misma cantidad</returns> public bool compareArguments(string idAmbito, string funcName, int[] sendedArgs) { TDSobj var1 = Search(idAmbito, funcName); if (var1 != null) { if (sendedArgs.Length == var1.args.Length) { for (int i = 0; i < sendedArgs.Length; i++) { if (sendedArgs[i] != var1.args[i]) { this.err += "\nUn argumento de la función " + funcName + " es inválido"; return(false); } } return(true); } else { this.err += "\nLa función " + funcName + " no acepta la cantidad de argumentos enviados"; return(false); } } this.err += "\n " + funcName + " no existe en el contexto actual"; return(false); }
/// <summary> /// Traducción de un valor tipo int a una variable o constante double /// </summary> /// <param name="idAmbito">Número identificador del ámbito actual</param> /// <param name="varName">Nombre de la variable o constante</param> /// <param name="intValue">Valor que se le asigna a <paramref name="varName"/></param> public void tradIntToDouble(string idAmbito, string varName, string intValue) { TDSobj var1 = Search(idAmbito, varName); string key = idAmbito + "," + varName; if (var1 != null) { string[] data = table[key].Split('|'); if (var1.type == 2) { if (int.TryParse(intValue, out _)) { data[1] = intValue + ".0"; string newVal = data[0] + "|" + data[1] + "|" + data[2] + "|" + data[3]; // cambio de atributos table[key] = newVal; } else { this.err += "\n " + intValue + " no es de tipo 'double' o 'int'"; } } else { this.err += "\n " + varName + " no es de tipo 'double' o 'int'"; } } else { this.err += "\n " + varName + " no existe en el contexto actual"; } }
/// <summary> /// Compara el tipo de una variable con un valor que se le asigna /// </summary> /// <param name="idAmbito">Número identificador del ámbito actual</param> /// <param name="varName1">Nombre de la varialbe o constante</param> /// <param name="typeOfValue">Identificador del tipo de dato que se le asigna a <paramref name="varName1"/></param> /// <returns></returns> public bool compareTypes(string idAmbito, string varName1, int typeOfValue) { TDSobj var1 = Search(idAmbito, varName1); if (var1 != null) { if (var1.type == typeOfValue) // mismos tipos { return(true); } else if (var1.type == 2 && typeOfValue == 1) // asignacion de entero (type 1) a un double (type 2) { return(true); } else { return(false); } } else { this.err += "\nLa variable o constante con el nombre " + varName1 + " no existe en el contexto actual"; return(false); } }
/// <summary> /// Inserta un registro en el diccionario de la tabla de símbolos /// </summary> /// <param name="symbol">objeto TDSobj</param> public void Insert(TDSobj symbol) { string key = symbol.idAmbito + "," + symbol.name; string value = symbol.type.ToString() + "|" + symbol.value + "|" + symbol._base + "|"; if (symbol.args != null) { foreach (var item in symbol.args) { /* Debido a que los id de tipos se identifican con números del 0 al 5 * es posible únicamente concatenarlos y separarlos por caracter para análisis */ value += item.ToString(); } } else { value += "NULL"; } if (!table.ContainsKey(key)) { table.Add(key, value); } else { this.err += "\nYa se había de clarado una variable o constante con el mismo nombre"; } }
/// <summary> /// Compara tipos de dos variables en un mismo ámbito /// </summary> /// <param name="idAmbito">Número identificador del ámbito actual</param> /// <param name="varName1">Nombre de la primera variable o constante</param> /// <param name="varName2">Nombre de la segunda variable o constante</param> /// <returns>true si ambos tipos son iguales</returns> public bool compareTypes(string idAmbito, string varName1, string varName2) { TDSobj var1 = Search(idAmbito, varName1); TDSobj var2 = Search(idAmbito, varName2); if (var1 != null) { if (var2 != null) { if (var1.type == var2.type) { return(true); } else { return(false); } } else { this.err += "\nLa variable o constante con el nombre " + varName2 + " no existe en el contexto actual"; return(false); } } else { this.err += "\nLa variable o constante con el nombre " + varName1 + " no existe en el contexto actual"; return(false); } }
/// <summary> /// Búsqueda de un registro en el diccionario de la tabla de símbolos /// </summary> /// <param name="idAmbito">Número identificador del ámbito actual</param> /// <returns>TDSobj si encuentra un registro con la misma llave, null si no fue encontrado</returns> public TDSobj Search(string idAmbito, string name) { string key = idAmbito + "," + name; if (table.ContainsKey(key)) { table.TryGetValue(key, out string value); string[] vals = value.Split('|'); List <string> sTypes = vals[3].Split().ToList(); List <int> iTypes = new List <int>(); foreach (var item in sTypes) { if (item == "NULL") { iTypes.Add(0); } else { iTypes.Add(int.Parse(item)); } } TDSobj obj = new TDSobj(idAmbito.ToString(), name, int.Parse(vals[0]), vals[1], int.Parse(vals[2]), iTypes.ToArray()); return(obj); } else { return(null); } }
/// <summary> /// Elimina un registro del diccionario de la tabla de símbolos /// </summary> /// <param name="symbol">objeto TDSobj</param> public void Delete(TDSobj symbol) { string key = symbol.idAmbito + "," + symbol.name; if (table.ContainsKey(key)) { table.Remove(key); } else { this.err += "\nEl objeto que se intentó eliminar no existe en la tabla"; } }
// la posición nula de la lista de tokens indica nueva linea public void Analysis() { List <KeyValuePair <string, string> > line = new List <KeyValuePair <string, string> >(); for (int i = 0; i < tokens.Count; i++) { if (!tokens[i].Key.Equals("")) { line.Add(tokens[i]); } else if (tokens[i].Value == "T_ValueType" && tokens[i + 1].Value == "ident" && tokens[i + 2].Value == "(") // es función { // una nueva función, un nuevo ámbito idAmbito++; int iType = getIdType(tokens[i].Value); int pos = i; i += 2; List <int> argTypes = new List <int>(); while (tokens[i].Key != ")") { if (tokens[i].Value == "T_ValueType") { argTypes.Add(getIdType(tokens[i].Key)); } else if (tokens[i].Value == "ident") { int argType = getIdType(tokens[i - 1].Key); int idBase = 0; if (argType == 1) { idBase = 1; } TDSobj newArg = new TDSobj(idAmbito.ToString(), tokens[i].Key, argTypes[argTypes.Count - 1], "", idBase); Data.Instance.tds.Insert(newArg); } i++; } TDSobj newFunc = new TDSobj("0", tokens[pos + 1].Key, iType, "", argTypes.ToArray()); Data.Instance.tds.Insert(newFunc); } else if (tokens[i].Value == "T_KeyWord") // condiciones o ciclos { if (tokens[i].Key == "while") { Stack <string> parentesis = new Stack <string>(); parentesis.Push("("); i += 2; while (parentesis.Count > 0) { if (tokens[i].Value == "(") // puede haber ((true) == (true)) { parentesis.Push("("); } else if (tokens[i].Value == ")") { parentesis.Pop(); } else if (tokens[i].Value == "ident") { TDSobj obj = Data.Instance.tds.Search(idAmbito.ToString(), tokens[i].Key); if (obj == null) { this.err += "La variable " + tokens[i].Key + " no existe en el contexto actual.\n"; } } else if (type.ContainsKey(tokens[i].Value)) // si es un valor de cierto tipo { } } whileCount++; } else if (tokens[i].Key == "for") { if (tokens[i + 1].Key == "(" && tokens[i + 2].Value == "T_ValueType") { int _base = 0; int iType = getIdType(tokens[i + 2].Key); string value = tokens[i + 4].Key; if (iType == 1) { if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) { _base = 2; } else { _base = 1; } } TDSobj aux = new TDSobj("for" + forCount.ToString(), tokens[i + 3].Key, iType, value); Data.Instance.tds.Insert(aux); if (!Data.Instance.tds.compareTypes("for" + forCount.ToString(), aux.name, 1)) { Data.Instance.tds.Delete(aux); this.err += "No se le pudo asignar " + value + " a " + tokens[i + 3].Key + "\n"; } } forCount++; } else if (tokens[i].Key == "if") { ifCount++; } else if (tokens[i].Key == "else") { elseCount++; } } else // termina la linea { Console.WriteLine("tokens por linea"); declare(line); assign(line, ""); line = new List <KeyValuePair <string, string> >(); } } }
/// <summary> /// Metodo para insertar declaraciones de variables en la tabla de simbolos /// </summary> public void declare(List <KeyValuePair <string, string> > input) { if (input.Count >= 2) { if (input[0].Value.Equals("T_ValueType") && input[1].Value.Equals("ident")) { int iType = 0; int _base = 0; switch (input[0].Key) { case "int": iType = 1; break; case "double": iType = 2; break; case "boolean": iType = 3; break; case "string": iType = 4; break; default: break; } TDSobj aux = new TDSobj(idAmbito.ToString(), input[1].Key, iType, "", _base); if (aux != null) { Data.Instance.tds.Insert(aux); } } if (input[0].Value.Equals("T_KeyWord") && input[1].Value.Equals("T_ValueType") && input[2].Value.Equals("ident")) { int iType = 0; int _base = 0; switch (input[1].Key) { case "int": iType = 1; break; case "double": iType = 2; break; case "boolean": iType = 3; break; case "string": iType = 4; break; default: break; } TDSobj aux = new TDSobj(idAmbito.ToString(), input[2].Key, iType, "", _base); if (aux != null) { Data.Instance.tds.Insert(aux); } } } }
public void assign(List <KeyValuePair <string, string> > input, string ambito) { if (input.Count >= 3) { // declaración y asignación if (input[0].Value.Equals("T_ValueType") && input[1].Value.Equals("ident") && input[2].Value.Equals("=") && (input[3].Value.Equals("ident") || input[3].Value.Equals("int") || input[3].Value.Equals("double") || input[3].Value.Equals("string") || input[3].Value.Equals("boolean"))) // declaracion y asignacion { int iType = 0; int _base = 0; switch (input[3].Value) { case "int": iType = 1; break; case "double": iType = 2; break; case "boolean": iType = 3; break; case "string": iType = 4; break; default: break; } if (iType == 1) { string value = input[3].Key; if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) { _base = 2; } else { _base = 1; } } TDSobj aux = null; // comparar tipos if (input[3].Value.Equals("ident")) { if (Data.Instance.tds.compareTypes(idAmbito.ToString(), input[1].Key, iType)) { aux = new TDSobj(idAmbito.ToString(), input[1].Key, iType, input[3].Key, _base); if (aux != null) { Data.Instance.tds.Update(idAmbito.ToString(), input[1].Key, input[3].Key); } } else { this.err += Data.Instance.tds.err + "\n"; } } else { // la variable no existe y se está declarando e insertando aux = new TDSobj(idAmbito.ToString(), input[1].Key, iType, input[3].Key, _base); if (aux != null) { Data.Instance.tds.Insert(aux); } } } // solo asignación if (input[0].Value.Equals("ident") && input[1].Value.Equals("=") && (input[2].Value.Equals("ident") || input[3].Value.Equals("int") || input[3].Value.Equals("double") || input[3].Value.Equals("string") || input[3].Value.Equals("boolean"))) // declaracion y asignacion { int iType = 0; int _base = 0; switch (input[2].Value) { case "int": iType = 1; break; case "double": iType = 2; break; case "boolean": iType = 3; break; case "string": iType = 4; break; default: break; } if (iType == 1) { string value = input[3].Key; if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) { _base = 2; } else { _base = 1; } } TDSobj aux = null; // comparar tipos if (input[3].Value.Equals("ident")) { if (Data.Instance.tds.compareTypes(idAmbito.ToString(), input[1].Key, input[3].Key)) { aux = new TDSobj(idAmbito.ToString(), input[1].Key, iType, input[3].Key, _base); } else { this.err += Data.Instance.tds.err + "\n"; } } else { if (Data.Instance.tds.compareTypes(idAmbito.ToString(), input[0].Key, iType)) { aux = new TDSobj(idAmbito.ToString(), input[1].Key, iType, input[3].Key, _base); } else { this.err += Data.Instance.tds.err + "\n"; } } if (aux != null) { Data.Instance.tds.Update(idAmbito.ToString(), input[1].Key, input[3].Key); } } } // ASIGNACION ident.ident }
private TDSobj operate(TDSobj var1, TDSobj var2, string operacion, string idAmbito = "0") { TDSobj result = new TDSobj(); switch (operacion) { case "+": // suma o concatenación if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { int iVal = int.Parse(var1.value) + int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, iVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double double dVal = double.Parse(var1.value) + double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, dVal.ToString()); break; case 4: // string concatenación string sVal = var1.value + var2.value; result = new TDSobj(idAmbito, "temp", 1, sVal); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else if ((var1.type == 1 && var2.type == 2) || (var1.type == 2 && var2.type == 1)) { double dVal = double.Parse(var1.value) + double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, dVal.ToString()); } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; case "-": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { int iVal = int.Parse(var1.value) - int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, iVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double double dVal = double.Parse(var1.value) - double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, dVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else if ((var1.type == 1 && var2.type == 2) || (var1.type == 2 && var2.type == 1)) { double dVal = double.Parse(var1.value) - double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, dVal.ToString()); } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; case "*": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { int iVal = int.Parse(var1.value) * int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, iVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double double dVal = double.Parse(var1.value) * double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, dVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else if ((var1.type == 1 && var2.type == 2) || (var1.type == 2 && var2.type == 1)) { double dVal = double.Parse(var1.value) * double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, dVal.ToString()); } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; case "/": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { int iVal = int.Parse(var1.value) / int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, iVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double double dVal = double.Parse(var1.value) / double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, dVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else if ((var1.type == 1 && var2.type == 2) || (var1.type == 2 && var2.type == 1)) { double dVal = double.Parse(var1.value) / double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, dVal.ToString()); } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; case "%": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { int iVal = int.Parse(var1.value) % int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, iVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double double dVal = double.Parse(var1.value) % double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, dVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else if ((var1.type == 1 && var2.type == 2) || (var1.type == 2 && var2.type == 1)) { double dVal = double.Parse(var1.value) % double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, dVal.ToString()); } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; case "&&": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 3: // boolean bool b1 = (var1.value == "true") ? true : false; bool b2 = (var2.value == "true") ? true : false; bool bVal = b1 && b2; result = new TDSobj(idAmbito, "temp", 1, bVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos no booleanos"; break; } } else { this.err += "\nOperación inválida sobre tipos diferentes no booleanos"; } break; case "||": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 3: // boolean bool b1 = (var1.value == "true") ? true : false; bool b2 = (var2.value == "true") ? true : false; bool bVal = b1 || b2; result = new TDSobj(idAmbito, "temp", 1, bVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos no booleanos"; break; } } else { this.err += "\nOperación inválida sobre tipos diferentes no booleanos"; } break; case "==": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { bool biVal = int.Parse(var1.value) == int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, biVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double bool bdVal = double.Parse(var1.value) == double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, bdVal.ToString()); break; case 3: // boolean bool b1 = (var1.value == "true") ? true : false; bool b2 = (var2.value == "true") ? true : false; bool bVal = b1 == b2; result = new TDSobj(idAmbito, "temp", 1, bVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; case "!=": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { bool biVal = int.Parse(var1.value) != int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, biVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double bool bdVal = double.Parse(var1.value) != double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, bdVal.ToString()); break; case 3: // boolean bool b1 = (var1.value == "true") ? true : false; bool b2 = (var2.value == "true") ? true : false; bool bVal = b1 != b2; result = new TDSobj(idAmbito, "temp", 1, bVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; case "<": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { bool biVal = int.Parse(var1.value) < int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, biVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double bool bdVal = double.Parse(var1.value) < double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, bdVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; case ">": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { bool biVal = int.Parse(var1.value) > int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, biVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double bool bdVal = double.Parse(var1.value) > double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, bdVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; case ">=": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { bool biVal = int.Parse(var1.value) >= int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, biVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double bool bdVal = double.Parse(var1.value) >= double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, bdVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; case "<=": if (var1.type == var2.type) { switch (var1.type) { case 0: this.err += "\nError de referencia a valor nulo"; break; case 1: // int if (var1._base == var2._base) { bool biVal = int.Parse(var1.value) <= int.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, biVal.ToString()); } else { this.err += "\nIntento de operación sobre enteros de diferente base"; } break; case 2: // double bool bdVal = double.Parse(var1.value) <= double.Parse(var2.value); result = new TDSobj(idAmbito, "temp", 1, bdVal.ToString()); break; default: this.err += "\nOperación inválida sobre tipos"; break; } } else { this.err += "\nOperación inválida sobre tipos diferentes"; } break; default: this.err += "\nOperador inválido"; break; } return(result); }
/// <summary> /// Realiza la operación entre dos valores /// </summary> /// <param name="signOp">Signo de la operación</param> /// <param name="op1">Valor o nombre de la variable operanda 1</param> /// <param name="op2">Valor o nombre de la variable operanda 1</param> /// <param name="idAmbito">Opcional, número identificador del ámbito actual</param> /// <returns>TDSobj con el atributo value igual a la operación realizada</returns> public TDSobj doOperation(string signOp, string op1, string op2, string idAmbito = "0") { TDSobj var1 = Search(idAmbito, op1); TDSobj var2 = Search(idAmbito, op2); TDSobj result = new TDSobj(); if (var1 != null && var2 != null) // ambos son variables { operate(var1, var2, signOp, idAmbito); } else if (var1 != null) // solo op1 es una variable { if (int.TryParse(op2, out _)) { var2 = new TDSobj(idAmbito, "temp", 1, op2); } else if (double.TryParse(op2, out _)) { var2 = new TDSobj(idAmbito, "temp", 2, op2); } else if (op2 == "true" || op2 == "false") { var2 = new TDSobj(idAmbito, "temp", 3, op2); } else // string type { var2 = new TDSobj(idAmbito, "temp", 4, op2); } result = operate(var1, var2, signOp, idAmbito); } else if (var2 != null) // solo op2 es una variable { if (int.TryParse(op1, out _)) { var1 = new TDSobj(idAmbito, "temp", 1, op1); } else if (double.TryParse(op1, out _)) { var1 = new TDSobj(idAmbito, "temp", 2, op1); } else if (op1 == "true" || op1 == "false") { var1 = new TDSobj(idAmbito, "temp", 3, op1); } else // string type { var1 = new TDSobj(idAmbito, "temp", 4, op1); } result = operate(var1, var2, signOp, idAmbito); } else // ni op1 ni op2 son variables { if (int.TryParse(op1, out _)) { var1 = new TDSobj(idAmbito, "temp", 1, op1); } else if (double.TryParse(op1, out _)) { var1 = new TDSobj(idAmbito, "temp", 2, op1); } else if (op1 == "true" || op1 == "false") { var1 = new TDSobj(idAmbito, "temp", 3, op1); } else // string type { var1 = new TDSobj(idAmbito, "temp", 4, op1); } if (int.TryParse(op2, out _)) { var2 = new TDSobj(idAmbito, "temp", 1, op2); } else if (double.TryParse(op2, out _)) { var2 = new TDSobj(idAmbito, "temp", 2, op2); } else if (op2 == "true" || op2 == "false") { var2 = new TDSobj(idAmbito, "temp", 3, op2); } else // string type { var2 = new TDSobj(idAmbito, "temp", 4, op2); } result = operate(var1, var2, signOp, idAmbito); } return(result); }