private void ListaDeIdentificadores(Variable.t tipoVariable) { string variable = getContenido(); Match(c.Identificador); if (!existeVariable(variable)) { string valor = ""; if (getClasificacion() == c.Asignacion) { Variable v = new Variable(variable, tipoVariable, "", false); Match(c.Asignacion); valor = Asignacion(variable); if (v.getTipo() == Variable.t.String && !v.esCadena(valor) && tipoDataExpresion == Variable.t.String) { valor = "\"" + valor + "\""; } validarTipoDato(v, valor); } variables.Add(new Variable(variable, tipoVariable, valor, false)); if (getContenido() == ",") { Match(","); ListaDeIdentificadores(tipoVariable); } } else { try { log.WriteLine(DateTime.Now.ToString("dd/MM/yy HH:mm") + " - Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": La variable " + variable + " está duplicada"); throw new MyException("Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": La variable ### está duplicada", variable); } finally { closeFiles(); } } }
private string evaluaCasteo(string valor, Variable.t tipoD) { int val; switch (tipoD) { case Variable.t.Char: val = (int)Math.Truncate(double.Parse(valor)); if (val < 256) { return(val.ToString()); } return((val % 256).ToString()); case Variable.t.Int: val = (int)Math.Truncate(double.Parse(valor)); if (val < 65536) { return(val.ToString()); } return((val % 65536).ToString()); case Variable.t.Float: double val2 = double.Parse(valor); if (val2 > 3.4E38) { return((val2 % 3.4E38).ToString()); } return(val2.ToString()); case Variable.t.Double: return(valor); default: if (valor[0] == '"') { return(valor); } return('"' + valor + '"'); } }
private void Factor() { if (getClasificacion() == c.Numero) { log.Write(getContenido() + " "); tipoDataExpresion = tipoDataExpresion < tipoDatoValor(getContenido()) ? tipoDatoValor(getContenido()) : tipoDataExpresion; evalua.Push(double.Parse(getContenido())); if (ponerASM) { asm.WriteLine("mov ax," + getContenido()); asm.WriteLine("push ax"); } Match(c.Numero); } else if (getClasificacion() == c.Funcion) { if (funciones.Contains(getContenido())) { string funcion = getContenido(); Match(c.Funcion); Match("("); Expresion(); Match(")"); log.Write(funcion + " "); if (ponerASM) { asm.WriteLine("pop ax"); } double value = Funcion(funcion, evalua.Pop()); Variable.t tipoDatoFunction = tipoDatoValor(value.ToString()); tipoDataExpresion = tipoDatoFunction; evalua.Push(value); if (ponerASM) { asm.WriteLine("mov ax," + value); asm.WriteLine("push ax"); } } else { try { log.WriteLine(DateTime.Now.ToString("dd/MM/yy HH:mm") + " - Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": Función " + getContenido() + " no declarada"); throw new MyException("Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": Función ### no declarada", getContenido()); } finally { closeFiles(); } } } else if (getClasificacion() == c.Identificador) { if (existeVariable(getContenido())) { Variable v = getVariable(getContenido()); tipoDataExpresion = tipoDataExpresion < v.getTipo() ? v.getTipo() : tipoDataExpresion; log.Write(getContenido() + " "); string variableValue = getValor(getContenido()); if (v.esCadena(variableValue)) { pushStringNoQuotes(v, variableValue); } else { evalua.Push(double.Parse(variableValue)); } if (ponerASM) { asm.WriteLine("mov ax," + getContenido()); asm.WriteLine("push ax"); } Match(c.Identificador); } else { try { log.WriteLine(DateTime.Now.ToString("dd/MM/yy HH:mm") + " - Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": Variable " + getContenido() + " no declarada"); throw new MyException("Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": Variable ### no declarada", getContenido()); } finally { closeFiles(); } } } else { Match("("); bool huboCasteo = false; Variable.t casteo = Variable.t.String; if (getClasificacion() == c.TipoDato) { casteo = Variable.stringToT(getContenido()); //if (casteo == Variable.t.String) tipoDataExpresion = casteo; huboCasteo = true; Match(c.TipoDato); Match(")"); Match("("); } Expresion(); Match(")"); if (huboCasteo) { string valor = evalua.Pop().ToString(); string valorCasteado = evaluaCasteo(valor, casteo); pushStringNoQuotes(valorCasteado); tipoDataExpresion = casteo; } } }
private string Asignacion(string variable) { string valor = ""; if (getContenido() == "Console") { tipoDataExpresion = Variable.t.String; Match("Console"); Match("."); if (ponerASM) { asm.WriteLine("call scan_num"); } if (getContenido() == "ReadLine") { Match("ReadLine"); valor = "\"" + Console.ReadLine() + "\""; if (ponerASM) { asm.WriteLine("printn ''"); } } else if (getContenido() == "Read") { Match("Read"); valor = "\"" + Convert.ToChar(Console.Read()).ToString() + "\""; } else { Match("ReadKey"); valor = "\"" + Console.ReadKey().KeyChar.ToString() + "\""; } if (ponerASM) { asm.WriteLine("mov " + variable + ",cx"); } Match("("); Match(")"); } else if (getClasificacion() == c.Cadena) { tipoDataExpresion = Variable.t.String; valor = getContenido(); Match(c.Cadena); } else // Expresión matemática { log.Write(variable + " = "); if (ponerASM) { asm.Write("\n;" + variable + " = \n"); } tipoDataExpresion = Variable.t.Char; Expresion(); if (ponerASM) { asm.WriteLine("pop ax"); asm.WriteLine("mov " + variable + ",ax"); } valor = evalua.Pop().ToString(); log.WriteLine(); log.WriteLine(variable + " = " + valor); } return(valor); }
private void ForEach(bool ejecutar) { log.Write("Foreach: "); Match(c.ForEach); Match("("); Expresion(); int nRep = 0; if (ponerASM) { asm.WriteLine("pop ax"); asm.WriteLine("mov cx,ax"); } double nRepTemp = evalua.Pop(); Variable.t tipoDatoNRep = tipoDatoValor(nRepTemp.ToString()); if (tipoDatoNRep == Variable.t.Int || tipoDatoNRep == Variable.t.Char) { nRep = (int)nRepTemp; } else { try { log.WriteLine(DateTime.Now.ToString("dd/MM/yy HH:mm") + " - Error de semántica en la linea " + this.actRow + " en la columna " + this.actColumn + ": El número de repeticiones en el ciclo no es válido"); throw new MyException("Error de semántica en la linea " + this.actRow + " en la columna " + this.actColumn + ": El número de repeticiones en el ciclo no es válido"); } finally { closeFiles(); } } long position = archivo.Position; int saveActRow = actRow; int saveActCol = actColumn; Match(")"); int contForTmp = contFor; if (ponerASM) { asm.WriteLine("for" + contForTmp + ":"); asm.WriteLine("push cx"); } contFor++; if (getClasificacion() == c.InicioBloque) { BloqueDeInstrucciones(ejecutar, nRep); } else { if (nRep == 0) { Instruccion(false); } ponerASM = true && ponerASM; bool prePonerASM = ponerASM; for (int i = 0; i < nRep; i++) { if (i > 0) { ponerASM = false; } Instruccion(ejecutar); if (i < nRep - 1) { archivo.Seek(position, SeekOrigin.Begin); actRow = saveActRow; actColumn = saveActCol; nextToken(); } } ponerASM = prePonerASM; } if (ponerASM) { asm.WriteLine("pop cx"); asm.WriteLine("loop for" + contForTmp); asm.WriteLine(";regresar a for" + contForTmp); } log.WriteLine(); }
private void Instruccion(bool ejecutar) { if (getContenido() == "Console") { Match(getContenido()); Match("."); switch (getContenido()) { case "WriteLine": case "Write": { string typeOutput = getContenido(); Match(getContenido()); Match("("); if (getClasificacion() == c.Cadena) { if (typeOutput == "Write") { if (ejecutar) { Console.Write(getContenido().Substring(1, getContenido().Length - 2)); } if (ponerASM) { asm.WriteLine("print " + getContenido()); } } else { if (ejecutar) { Console.WriteLine(getContenido().Substring(1, getContenido().Length - 2)); } if (ponerASM) { asm.WriteLine("printn " + getContenido()); } } Match(c.Cadena); } else { if (getContenido() != ")") { if (existeVariable(getContenido())) { Variable v = getVariable(getContenido()); if (typeOutput == "Write") { if (v.getTipo() == Variable.t.String) { if (ejecutar) { Console.Write(v.getValor().Substring(1, v.getValor().Length - 2)); } if (ponerASM) { asm.WriteLine("print " + v.getValor()); } } else { if (ejecutar) { Console.Write(v.getValor()); } if (ponerASM) { asm.WriteLine("mov ax," + v.getNombre()); asm.WriteLine("call print_num"); } } } else { if (v.getTipo() == Variable.t.String) { if (ejecutar) { Console.WriteLine(v.getValor().Substring(1, v.getValor().Length - 2)); } if (ponerASM) { asm.WriteLine("printn " + v.getValor()); } } else { if (ejecutar) { Console.WriteLine(v.getValor()); } if (ponerASM) { asm.WriteLine("mov ax," + v.getNombre()); asm.WriteLine("call print_num"); asm.WriteLine("printn ''"); } } } Match(c.Identificador); } else { try { log.WriteLine(DateTime.Now.ToString("dd/MM/yy HH:mm") + " - Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": Variable referenciada no existente - " + getContenido()); throw new MyException("Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": Variable referenciada no existente - ", getContenido()); } finally { closeFiles(); } } } else { if (typeOutput != "Write") { if (ejecutar) { Console.WriteLine(); } if (ponerASM) { asm.WriteLine("printn ''"); } } } } Match(")"); } break; case "ReadLine": case "Read": case "ReadKey": { string typeInput = getContenido(); Match(getContenido()); if (ponerASM) { asm.WriteLine("call scan_num"); } if (typeInput == "ReadLine") { if (ejecutar) { Console.ReadLine(); } if (ponerASM) { asm.WriteLine("printn ''"); } } else if (typeInput == "Read") { if (ejecutar) { Console.Read(); } } else { if (ejecutar) { Console.ReadKey(); } } Match("("); Match(")"); } break; default: { try { log.WriteLine(DateTime.Now.ToString("dd/MM/yy HH:mm") + " - Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": Se espera una entrada o salida"); throw new MyException("Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": Se espera ###", "una entrada o salida"); } finally { closeFiles(); } } } Match(c.FinSentencia); } else if (getClasificacion() == c.TipoDato) { Variable.t tipoVariable = Variable.stringToT(getContenido()); Match(c.TipoDato); ListaDeIdentificadores(tipoVariable); Match(c.FinSentencia); } else if (getClasificacion() == c.Constante) { Match(c.Constante); Variable.t tipoVariable = Variable.stringToT(getContenido()); Match(c.TipoDato); ListaDeConstantes(tipoVariable); Match(c.FinSentencia); } else if (getClasificacion() == c.If) { IF(ejecutar); } else if (getClasificacion() == c.ForEach) { ForEach(ejecutar); } else // Modificacion de variables { string variable = getContenido(); Match(c.Identificador); if (existeVariable(variable)) { Variable v = getVariable(variable); Match(c.Asignacion); string valor = Asignacion(variable); if (v.getTipo() == Variable.t.String && !v.esCadena(valor) && tipoDataExpresion == Variable.t.String) { valor = "\"" + valor + "\""; } validarTipoDato(v, valor); if (v.esConst) { try { log.WriteLine(DateTime.Now.ToString("dd/MM/yy HH:mm") + " - Error de semántica en la linea " + this.actRow + " en la columna " + this.actColumn + ": La constante " + v.getNombre() + " no se puede modificar"); throw new MyException("Error de semántica en la linea " + this.actRow + " en la columna " + this.actColumn + ": La constante ### no se puede modificar", v.getNombre()); } finally { closeFiles(); } } if (ejecutar) { setValor(variable, valor); } Match(c.FinSentencia); } else { try { log.WriteLine(DateTime.Now.ToString("dd/MM/yy HH:mm") + " - Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": La variable " + variable + " no está declarada"); throw new MyException("Error de sintaxis en la linea " + this.actRow + " en la columna " + this.actColumn + ": La variable ### no está declarada", variable); } finally { closeFiles(); } } } }