public object compilar(Entorno ent, Errores errores) { try { Generator generator = Generator.getInstance(); Retorno value = this.value.compilar(ent); Simbolo newVar = ent.addVar(id, value.type, true, false, linea, columna); if (newVar.isGlobal) { if (newVar.type.tipo == Tipos.BOOLEAN) { if (value.getValue().Equals("1")) { generator.addGoto(value.trueLabel); } else { generator.addGoto(value.falseLabel); } string templabel = generator.newLabel(); generator.addLabel(value.trueLabel); generator.addSetStack("" + newVar.position, "1"); generator.addGoto(templabel); generator.addLabel(value.falseLabel); generator.addSetStack("" + newVar.position, "0"); generator.addLabel(templabel); } else { generator.addSetStack("" + newVar.position, value.getValue()); } } } catch (Error ex) { errores.agregarError(ex); } return(null); }
public Retorno compilar(Entorno ent) { Retorno unario = this.unario.compilar(ent); if (!(unario.type.tipo == Tipos.INTEGER || unario.type.tipo == Tipos.REAL)) { throw new Error("Semántico", "No se puede evaluar una resta unaria con un " + unario.type.tipoToString(), ent.obtenerAmbito(), linea, columna); } Generator generator = Generator.getInstance(); string temp = generator.newTemporal(); //INTEGER, REAL generator.addExpression(temp, "0", unario.getValue(), "-"); return(new Retorno(temp, true, unario.type)); }
public Retorno compilar(Entorno ent) { Retorno left = this.left.compilar(ent); Retorno right = this.right.compilar(ent); Tipos tipoResultado = TablaTipos.obtenerTipo("-", left.type, right.type); if (tipoResultado == Tipos.ERROR) { throw new Error("Semántico", "No se puede evaluar una resta entre un " + left.type.tipoToString() + " y un " + right.type.tipoToString(), ent.obtenerAmbito(), linea, columna); } Tipo tipo = new Tipo(tipoResultado); Generator generator = Generator.getInstance(); string temp = generator.newTemporal(); //INTEGER, REAL generator.addExpression(temp, left.getValue(), right.getValue(), "-"); return(new Retorno(temp, true, tipo)); }
public Retorno compilar(Entorno ent) { Retorno left = this.left.compilar(ent); Retorno right = this.right.compilar(ent); Tipos tipoResultado = TablaTipos.obtenerTipo("mod", left.type, right.type); if (tipoResultado == Tipos.ERROR) { throw new Error("Semántico", "No se puede evaluar un modulo entre un " + left.type.tipoToString() + " y un " + right.type.tipoToString(), ent.obtenerAmbito(), linea, columna); } Tipo tipo = new Tipo(tipoResultado); Generator generator = Generator.getInstance(); string temp = generator.newTemporal(); //INTEGER if (right.valorToString().Equals("0")) { throw new Error("Semántico", "Resultado indefinido, no se puede realizar un modulo entre 0", ent.obtenerAmbito(), linea, columna); } generator.addExpression(temp, left.getValue(), right.getValue(), "%"); return(new Retorno(temp, true, tipo)); }
public Retorno compilar(Entorno ent) { //Mi modificacion if (this.left is AccessId) { AccessId access = (AccessId)this.left; access.vieneDeRelacional = true; } Retorno left = this.left.compilar(ent); Retorno right; Generator generator = Generator.getInstance(); switch (left.type.tipo) { case Tipos.INTEGER: case Tipos.REAL: right = this.right.compilar(ent); switch (right.type.tipo) { case Tipos.INTEGER: case Tipos.REAL: this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; if (this.isLessEqual) { generator.addIf(left.getValue(), right.getValue(), "<=", this.trueLabel); } else { generator.addIf(left.getValue(), right.getValue(), "<", this.trueLabel); } generator.addGoto(this.falseLabel); Retorno retorno = new Retorno("", false, new Tipo(Tipos.BOOLEAN)); retorno.trueLabel = this.trueLabel; retorno.falseLabel = this.falseLabel; return(retorno); default: break; } break; case Tipos.BOOLEAN: //Mi modificacion if (this.right is AccessId) { AccessId access = (AccessId)this.right; access.vieneDeRelacional = true; } right = this.right.compilar(ent); this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; if (isLessEqual) { generator.addIf(left.getValue(), right.getValue(), "<=", trueLabel); } else { generator.addIf(left.getValue(), right.getValue(), "<=", trueLabel); } generator.addGoto(falseLabel); if (right.type.tipo == Tipos.BOOLEAN) { Retorno retorno = new Retorno("", false, new Tipo(Tipos.BOOLEAN)); retorno.trueLabel = this.trueLabel; retorno.falseLabel = this.falseLabel; return(retorno); } break; case Tipos.STRING: right = this.right.compilar(ent); if (right.type.tipo == Tipos.STRING) { string temp = generator.newTemporal(); string tempAux = generator.newTemporal(); generator.freeTemp(tempAux); generator.addExpression(tempAux, "SP", "" + (ent.getSize() + 1), "+"); generator.addSetStack(tempAux, left.getValue()); generator.addExpression(tempAux, tempAux, "1", "+"); generator.addSetStack(tempAux, right.getValue()); generator.addNextEnv(ent.getSize()); if (this.isLessEqual) { generator.addCall("native_lessEq_str"); } else { generator.addCall("native_less_str"); } generator.addGetStack(temp, "SP"); generator.addAntEnv(ent.getSize()); this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; generator.addIf(temp, "1", "==", this.trueLabel); generator.addGoto(this.falseLabel); Retorno retorno = new Retorno("", false, new Tipo(Tipos.BOOLEAN)); retorno.trueLabel = this.trueLabel; retorno.falseLabel = this.falseLabel; return(retorno); } break; default: right = new Retorno("", false, new Tipo(Tipos.ERROR)); break; //ERROR } throw new Error("Semántico", "No se puede evaluar un < o <= entre un " + left.type.tipoToString() + " y un " + right.type.tipoToString(), ent.obtenerAmbito(), linea, columna); }
public object compilar(Entorno ent, Errores errores) { Generator generator = Generator.getInstance(); generator.addComment("Inicia Writeln"); try { foreach (Expresion expresion in expresiones) { Retorno value = expresion.compilar(ent); switch (value.type.tipo) { case Tipos.INTEGER: if (value.isTemp) { generator.addPrint("d", "(int)" + value.getValue()); } else { generator.addPrint("d", value.getValue()); } break; case Tipos.REAL: generator.addPrint("f", value.getValue()); break; case Tipos.BOOLEAN: if (value.vieneDesdeObjeto) { generator.addIf(value.getValue(), "1", "==", value.trueLabel); generator.addGoto(value.falseLabel); } string templabel = generator.newLabel(); generator.addLabel(value.trueLabel); generator.addPrintTrue(); generator.addGoto(templabel); generator.addLabel(value.falseLabel); generator.addPrintFalse(); generator.addLabel(templabel); break; case Tipos.STRING: generator.addNextEnv(ent.getSize()); generator.addSetStack("SP", value.getValue()); generator.addCall("native_print_str"); generator.addAntEnv(ent.getSize()); break; default: throw new Error("Semántico", "Tipo de dato no soportado en un writeln", ent.obtenerAmbito(), linea, columna); } } if (isLine) { generator.addPrint("c", "10"); } } catch (Error ex) { errores.agregarError(ex); } generator.addComment("Finaliza Writeln"); return(null); }
public object compilar(Entorno ent, Errores errores) { try { Generator generator = Generator.getInstance(); generator.addComment("Inicia Asignacion"); if (ent.ambito.Equals("FUNCTION")) { SimboloFunction symFunc = ent.actualFunc; if (symFunc != null) { AsignacionId mytarget = (AsignacionId)this.target; if (mytarget.id.ToLower().Equals(symFunc.id.ToLower())) //Es un Return { Return @return = new Return(this.value, linea, columna); @return.isAsignacion = true; return(@return.compilar(ent, errores)); } } } Retorno target = this.target.compilar(ent); Retorno value = this.value.compilar(ent); Simbolo symbol = target.symbol; if (symbol.isConst) { throw new Error("Semántico", "No se puede cambiar el valor de una constante", ent.obtenerAmbito(), linea, columna); } if (!sameType(target.type, value.type)) { throw new Error("Semántico", "No coincide el tipo de dato de la variable con el tipo de valor a asignar", ent.obtenerAmbito(), linea, columna); } if (symbol.isHeap == false) //ES GLOBAL { if (target.type.tipo == Tipos.BOOLEAN) { //Mi modificacion if (value.getValue().Equals("1")) { generator.addGoto(value.trueLabel); } else { generator.addGoto(value.falseLabel); } string templabel = generator.newLabel(); generator.addLabel(value.trueLabel); generator.addSetStack(target.getValue(), "1"); generator.addGoto(templabel); generator.addLabel(value.falseLabel); generator.addSetStack(target.getValue(), "0"); generator.addLabel(templabel); } else { generator.addSetStack(target.getValue(), value.getValue()); } } else if (symbol.isHeap) { if (target.type.tipo == Tipos.BOOLEAN) { //Mi modificacion if (value.getValue().Equals("1")) { generator.addGoto(value.trueLabel); } else { generator.addGoto(value.falseLabel); } string templabel = generator.newLabel(); generator.addLabel(value.trueLabel); generator.addSetHeap(target.getValue(), "1"); generator.addGoto(templabel); generator.addLabel(value.falseLabel); generator.addSetHeap(target.getValue(), "0"); generator.addLabel(templabel); } else { generator.addSetHeap(target.getValue(), value.getValue()); } } generator.addComment("Finaliza Asignacion"); } catch (Error ex) { errores.agregarError(ex); } return(null); }
public Retorno compilar(Entorno ent) { Generator generator = Generator.getInstance(); generator.addComment("Inicia AsignacionId"); if (this.anterior == null) { Simbolo symbol = ent.getVar(id, linea, columna); if (symbol.isRef) { string tempAux = generator.newTemporal(); string temp = generator.newTemporal(); generator.freeTemp(tempAux); generator.addExpression(tempAux, "SP", "" + symbol.position, "+"); generator.addExpression(temp, tempAux, "1", "+"); generator.addGetStack(temp, temp); this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; generator.addIf(temp, "1", "==", this.trueLabel); generator.addGoto(this.falseLabel); string templabel = generator.newLabel(); generator.addLabel(this.trueLabel); generator.addGetStack(temp, tempAux); generator.addGoto(templabel); generator.addLabel(this.falseLabel); generator.addGetHeap(temp, tempAux); generator.addLabel(templabel); generator.addComment("Finaliza AsignacionId"); return(new Retorno(temp, true, symbol.type, symbol)); //OBTENGO LA COORDENADA DE LA VARIABLE POR REFERENCIA } else if (symbol.isGlobal) { generator.addComment("Finaliza AsignacionId"); return(new Retorno("" + symbol.position, false, symbol.type, symbol)); } else //isHeap { string temp = generator.newTemporal(); generator.addExpression(temp, "SP", "" + symbol.position, "+"); generator.addComment("Finaliza AsignacionId"); return(new Retorno(temp, true, symbol.type, symbol)); } } else { Retorno anterior = this.anterior.compilar(ent); if (anterior.type.tipo != Tipos.STRUCT) { throw new Error("Semántico", "Acceso no valido para el tipo: " + anterior.type.tipo, ent.obtenerAmbito(), linea, columna); } SimboloStruct symStruct = anterior.type.symStruct; Jackson attribute = symStruct.getAttribute(this.id); if (attribute.value == null) { throw new Error("Semántico", "El object " + symStruct.identifier + "no tiene el atributo" + this.id, ent.obtenerAmbito(), linea, columna); } string tempAux = generator.newTemporal(); generator.freeTemp(tempAux); string temp = generator.newTemporal(); if (anterior.symbol != null && !anterior.symbol.isHeap) { //TODO variables por referencia generator.addGetStack(tempAux, anterior.getValue()); } else { generator.addGetHeap(tempAux, anterior.getValue()); } generator.addExpression(temp, tempAux, "" + attribute.index, "+"); generator.addComment("Finaliza AsignacionId"); return(new Retorno(temp, true, attribute.value.type, new Simbolo(attribute.value.type, this.id, attribute.index, false, false, true, linea, columna))); } }
public Retorno compilar(Entorno ent) { Generator generator = Generator.getInstance(); generator.addComment("Inicia AccessId"); if (this.anterior == null) { Simbolo symbol = ent.getVar(this.id, linea, columna); string temp = generator.newTemporal(); if (symbol.isRef) { string tempAux = generator.newTemporal(); generator.freeTemp(tempAux); generator.addExpression(tempAux, "SP", "" + symbol.position, "+"); generator.addExpression(temp, tempAux, "1", "+"); generator.addGetStack(temp, temp); this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; generator.addIf(temp, "1", "==", this.trueLabel); generator.addGoto(this.falseLabel); string templabel = generator.newLabel(); generator.addLabel(this.trueLabel); generator.addGetStack(temp, tempAux); generator.addGoto(templabel); generator.addLabel(this.falseLabel); generator.addGetHeap(temp, tempAux); generator.addLabel(templabel); //TENGO LA DIRECCION DE LA VARIABLE POR REFERENCIA generator.addGetStack(temp, temp); //OBTENGO SU VALOR Y LO GUARDO EN EL MISMO TEMPORAL if (symbol.type.tipo != Tipos.BOOLEAN && symbol.type.tipo != Tipos.STRUCT) { generator.addComment("Finaliza AccessId"); return(new Retorno(temp, true, symbol.type, symbol)); } if (symbol.type.tipo == Tipos.BOOLEAN) { if (vieneDeRelacional) { return(new Retorno(temp, true, symbol.type, symbol)); } Retorno retorno = new Retorno("", false, symbol.type, symbol); this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; generator.addIf(temp, "1", "==", this.trueLabel); generator.addGoto(this.falseLabel); retorno.trueLabel = this.trueLabel; retorno.falseLabel = this.falseLabel; generator.addComment("Finaliza AccessId"); return(retorno); } else //STRUCT { Retorno retorno = new Retorno(temp, true, symbol.type, symbol); this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; retorno.trueLabel = this.trueLabel; retorno.falseLabel = this.falseLabel; generator.addComment("Finaliza AccessId"); return(retorno); } } else if (symbol.isGlobal) { generator.addGetStack(temp, "" + symbol.position); if (symbol.type.tipo != Tipos.BOOLEAN && symbol.type.tipo != Tipos.STRUCT) { generator.addComment("Finaliza AccessId"); return(new Retorno(temp, true, symbol.type, symbol)); } //MI MODIFICACION if (symbol.type.tipo == Tipos.BOOLEAN) { if (vieneDeRelacional) { return(new Retorno(temp, true, symbol.type, symbol)); } Retorno retorno = new Retorno("", false, symbol.type, symbol); this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; generator.addIf(temp, "1", "==", this.trueLabel); generator.addGoto(this.falseLabel); retorno.trueLabel = this.trueLabel; retorno.falseLabel = this.falseLabel; generator.addComment("Finaliza AccessId"); return(retorno); } else //STRUCT { Retorno retorno = new Retorno(temp, true, symbol.type, symbol); this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; retorno.trueLabel = this.trueLabel; retorno.falseLabel = this.falseLabel; generator.addComment("Finaliza AccessId"); return(retorno); } } else //isHeap { string tempAux = generator.newTemporal(); generator.freeTemp(tempAux); generator.addExpression(tempAux, "SP", "" + symbol.position, "+"); generator.addGetStack(temp, tempAux); if (symbol.type.tipo != Tipos.BOOLEAN && symbol.type.tipo != Tipos.STRUCT) { generator.addComment("Finaliza AccessId"); return(new Retorno(temp, true, symbol.type, symbol)); } //MI MODIFICACION if (symbol.type.tipo == Tipos.BOOLEAN) { if (vieneDeRelacional) { return(new Retorno(temp, true, symbol.type, symbol)); } Retorno retorno = new Retorno("", false, symbol.type, symbol); this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; generator.addIf(temp, "1", "==", this.trueLabel); generator.addGoto(this.falseLabel); retorno.trueLabel = this.trueLabel; retorno.falseLabel = this.falseLabel; generator.addComment("Finaliza AccessId"); return(retorno); } else //STRUCT { Retorno retorno = new Retorno(temp, true, symbol.type, symbol); this.trueLabel = this.trueLabel == "" ? generator.newLabel() : this.trueLabel; this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel; retorno.trueLabel = this.trueLabel; retorno.falseLabel = this.falseLabel; generator.addComment("Finaliza AccessId"); return(retorno); } } } else { Retorno anterior = this.anterior.compilar(ent); SimboloStruct symStruct = anterior.type.symStruct; if (anterior.type.tipo != Tipos.STRUCT || symStruct == null) { throw new Error("Semántico", "Acceso no valido para el tipo: " + anterior.type.tipo, ent.obtenerAmbito(), linea, columna); } Jackson attribute = symStruct.getAttribute(this.id); if (attribute.value == null) { throw new Error("Semántico", "El object no tiene el atributo: " + this.id, ent.obtenerAmbito(), linea, columna); } string tempAux = generator.newTemporal(); generator.freeTemp(tempAux); string temp = generator.newTemporal(); generator.addExpression(tempAux, anterior.getValue(), "" + attribute.index, "+"); //Busca la posicion del atributo generator.addGetHeap(temp, tempAux); //Trae el valor del heap Retorno retorno = new Retorno(temp, true, attribute.value.type, null, true); retorno.trueLabel = anterior.trueLabel; retorno.falseLabel = anterior.falseLabel; generator.addComment("Finaliza AccessId"); return(retorno); } }