public object compilar(Entorno ent, Errores errores) { Retorno value; if (this.value == null) { value = new Retorno("0", false, new Tipo(Tipos.VOID)); } else { value = this.value.compilar(ent); } SimboloFunction symFunc = ent.actualFunc; Generator generator = Generator.getInstance(); if (symFunc == null) { throw new Error("Semántico", "Exit no esta dentro de una función", ent.obtenerAmbito(), linea, columna); } if (!this.sameType(symFunc.type, value.type)) { throw new Error("Semántico", "Se esperaba en Exit un " + symFunc.type.tipoToString() + " y se obtuvo un " + value.type.tipoToString(), ent.obtenerAmbito(), linea, columna); } if (symFunc.type.tipo == Tipos.BOOLEAN) { string templabel = generator.newLabel(); generator.addLabel(value.trueLabel); generator.addSetStack("SP", "1"); generator.addGoto(templabel); generator.addLabel(value.falseLabel); generator.addSetStack("SP", "0"); generator.addLabel(templabel); } else if (symFunc.type.tipo != Tipos.VOID) { generator.addSetStack("SP", value.getValue()); } if (!isAsignacion) { generator.addGoto(ent.yreturn); } return(null); }
public Retorno compilar(Entorno ent) { if (this.anterior == null) { SimboloFunction symFunc = ent.searchFunc(this.id); if (symFunc == null) { throw new Error("Semántico", "No se encontro la función: " + this.id, ent.obtenerAmbito(), linea, columna); } LinkedList <Retorno> paramsValues = new LinkedList <Retorno>(); Generator generator = Generator.getInstance(); int size = generator.saveTemps(ent); //Guardo temporales foreach (Expresion param in this.parametros) { if (param is AccessId) { AccessId access = (AccessId)param; access.vieneDeRelacional = true; } paramsValues.AddLast(param.compilar(ent)); } //Verifico si viene el mismo numero de parametros if (paramsValues.Count != symFunc.parametros.Count) { throw new Error("Semántico", "Faltan parametros a enviar en la llamada a la funcion:" + this.id, ent.obtenerAmbito(), linea, columna); } //Verifico si coninciden los tipos de los parametros if (!this.validarTipoParametros(paramsValues, symFunc.parametros)) { throw new Error("Semántico", "No coincide un tipo de parametro en la llamada a la funcion:" + this.id, ent.obtenerAmbito(), linea, columna); } string temp = generator.newTemporal(); generator.freeTemp(temp); //Paso de parametros en cambio simulado if (paramsValues.Count != 0) { generator.addExpression(temp, "SP", "" + (ent.size + 1), "+"); //+1 porque la posicion 0 es para el retorno; int index = -1; foreach (Retorno value in paramsValues) { index++; Param param = symFunc.parametros.ElementAt(index); if (param.isRef) { if (value.symbol.isGlobal) { generator.addSetStack(temp, "" + value.symbol.position); generator.addExpression(temp, temp, "1", "+"); generator.addSetStack(temp, "1"); } else if (value.symbol.isHeap) { generator.addSetStack(temp, "" + value.symbol.position); generator.addExpression(temp, temp, "1", "+"); generator.addSetStack(temp, "0"); } else { string temp2 = generator.newTemporal(); generator.freeTemp(temp2); generator.addExpression(temp2, "SP", "" + value.symbol.position, "+"); generator.addSetStack(temp, temp2); generator.addExpression(temp, temp, "1", "+"); generator.addSetStack(temp, "1"); } } else { generator.addSetStack(temp, value.getValue()); } if (index != paramsValues.Count - 1) { generator.addExpression(temp, temp, "1", "+"); } } } generator.addNextEnv(ent.size); generator.addCall(symFunc.uniqueId); if (symFunc.type.tipo != Tipos.VOID) { generator.addGetStack(temp, "SP"); } generator.addAntEnv(ent.size); generator.recoverTemps(ent, size); generator.addTemp(temp); if (symFunc.type.tipo != Tipos.BOOLEAN) { return(new Retorno(temp, true, symFunc.type)); } Retorno retorno = new Retorno("", false, symFunc.type); 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; return(retorno); } else { } throw new Error("Semántico", "Funcion no implementada", ent.obtenerAmbito(), linea, columna); }
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); }