public Tipo(Tipos tipo, string tipoId = "", SimboloStruct symStruct = null, int dimension = 0) { this.tipo = tipo; this.tipoId = tipoId; this.symStruct = symStruct; this.dimension = dimension; }
public void validateType(Entorno ent) { if (this.type.tipo == Tipos.STRUCT) { SimboloStruct @struct = ent.searchStruct(this.type.tipoId); if (@struct == null) { throw new Error("Semántico", "No existe el object: " + this.type.tipoId, ent.obtenerAmbito(), linea, columna); } this.type.symStruct = @struct; } }
public Retorno compilar(Entorno ent) { SimboloStruct symStruct = ent.searchStruct(this.id); Generator generator = Generator.getInstance(); if (symStruct == null) { throw new Error("Semántico", "No existe el object " + this.id + " en este entorno", ent.obtenerAmbito(), linea, columna); } string temp = generator.newTemporal(); generator.addExpression(temp, "HP", "", ""); //Llenamos de valores por defecto foreach (Param attribute in symStruct.attributes) { switch (attribute.type.tipo) { case Tipos.INTEGER: case Tipos.REAL: case Tipos.BOOLEAN: generator.addSetHeap("HP", "0"); generator.nextHeap(); break; case Tipos.STRING: generator.addSetHeap("HP", "-1"); generator.nextHeap(); break; case Tipos.STRUCT: generator.addComment("Inicia substruct"); compilarSubStruct(attribute); generator.addComment("Finaliza substruct"); break; default: generator.addSetHeap("HP", "-1"); generator.nextHeap(); break; } } return(new Retorno(temp, true, new Tipo(Tipos.STRUCT, symStruct.identifier, symStruct))); }
private void validateParams(Entorno ent) { LinkedList <string> set = new LinkedList <string>(); foreach (Param param in attributes) { if (set.Contains(param.id.ToLower())) { throw new Error("Semántico", "Ya existe un atributo con el nombre: " + param.id + " en el object: " + this.id, ent.obtenerAmbito(), linea, columna); } if (param.type.tipo == Tipos.STRUCT) { SimboloStruct @struct = ent.structExists(param.type.tipoId); if (@struct == null) { throw new Error("Semántico", "No existe el object: " + param.type.tipoId + "para el atributo: " + param.id, ent.obtenerAmbito(), linea, columna); } param.type.symStruct = @struct; } set.AddLast(param.id.ToLower()); } }
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); } }