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); } }