public override bool VisitVarDeclaration(VarDeclarationAST expr) { var other = _other as VarDeclarationAST; if (other == null) { return(false); } return(IsEqualNodes(other.ExpressionValue, expr.ExpressionValue) && other.TypeId == expr.TypeId && other.Id == expr.Id); }
public override Unit VisitVarDeclaration(VarDeclarationAST expr) { VarInfo varInfo = expr.CurrentScope.GetVarInfo(expr.Id); //nombre de la variable generado string varCodeName = varInfo.CodeName; // necesito el tipo de la variable. string typeCodeName = varInfo.TypeInfo.CodeName; Type varType = code.DefinedType[typeCodeName]; //aca hay que tener en cuenta que las variable que son usadas por otras funciones se declaran en la declaracion de //la funcion a la que pertenecen if (!varInfo.IsUsedForAnotherFunction) { if (!varInfo.IsParameterFunction) //no tengo en cuenta los parametro de funcion porque esos los declara la funcion { //generar la variable como local a la funcion ILGenerator il = code.Method.GetILGenerator(); LocalBuilder local = il.DeclareLocal(varType); // local.SetLocalSymInfo(varCodeName); //adicionarla a las varibles locales code.DefinedLocal.Add(varCodeName, local); } } else { if (!varInfo.IsParameterFunction) { string currentFunction = expr.CurrentScope.CurrentFunction.CodeName; TypeCodeInfo wrapper = code.GetWrapperAsociatteTo(currentFunction); FieldBuilder field = wrapper.Type.DefineField(varInfo.CodeName, varType, FieldAttributes.Public); //añadir el field a la clase ILCode code.DefinedField.Add(varInfo.CodeName, field); //añadida al wrapper wrapper.AddField(varCodeName, field); } } //generar la inicializacion de la variable code.OnBeginMethod += (theCode, e) => code_OnBeginMethod_var(expr, theCode, e); return(Unit.Create()); }
private void code_OnBeginMethod_var(VarDeclarationAST varDecl, ILCode theCode, BeginMethodEventArgs e) { VarInfo varInfo = varDecl.CurrentScope.GetVarInfo(varDecl.Id); var isMyFunction = varDecl.CurrentScope.GetFunction(varInfo.FunctionNameParent).CodeName == e.FunctionCodeName; //it is true if the funcion (e.FunctionCodeName) is the same that the function that declares this variable. if (isMyFunction) { ILGenerator il = code.Method.GetILGenerator(); //---> bool pushOnStack = code.PushOnStack; code.PushOnStack = true; string varCodeName = varInfo.CodeName; if (!varInfo.IsUsedForAnotherFunction) { if (!varInfo.IsParameterFunction) //significa que es una variable local { varDecl.ExpressionValue.Accept(this); il.Emit(OpCodes.Stloc, code.DefinedLocal[varCodeName].LocalIndex); } } else { if (!varInfo.IsParameterFunction) //significa que es un campo de la clase { //cargar la instancia de la clase contenedora que tengo como variable local il.Emit(OpCodes.Ldloc_0); varDecl.ExpressionValue.Accept(this); il.Emit(OpCodes.Stfld, code.DefinedField[varCodeName]); } } //<--- code.PushOnStack = pushOnStack; } }
public abstract T VisitVarDeclaration(VarDeclarationAST expr);
public override bool VisitVarDeclaration(VarDeclarationAST expr) { expr.CurrentScope = _scope; ScopeLocation idLocation = _scope.HasVar(expr.Id); if (idLocation == ScopeLocation.DeclaredLocal) { _errorListener.Add(new AnalysisError(string.Format(AnalysisError.LoadMessage("VarDecl"), expr.Id), expr.Line, expr.Columns)); expr.ReturnType = TigerType.GetType <ErrorType>(); return(false); } if (idLocation != ScopeLocation.NotDeclared) { _errorListener.Add(AnalysisError.VariableHidesAnotherOne(expr)); } //TODO: Rename ExpressionValue to NamedExpression expr.ExpressionValue.Accept(this); //se asume q no habran problemas de compatibilidad expr.ReturnType = TigerType.GetType <NoType>(); // si se expecifico de forma explicita el tipo de la variable... if (!string.IsNullOrEmpty(expr.TypeId)) { TigerType tt; //existe el tipo if (_scope.HasType(expr.TypeId, out tt) != ScopeLocation.NotDeclared) { //el tipo de la variable no machea con el de la expression if (!expr.ExpressionValue.ReturnType.CanConvertTo(tt)) { _errorListener.Add( new AnalysisError( string.Format(AnalysisError.LoadMessage("Match"), expr.TypeId, expr.ExpressionValue.ReturnType.TypeID), expr.Line, expr.Columns)); expr.ReturnType = TigerType.GetType <ErrorType>(); _scope.AddVar(expr.Id, TigerType.GetType <ErrorType>().TypeID); return(false); } expr.ReturnType = expr.ExpressionValue.ReturnType; //si me especifica el tipo explicitamente . _scope.AddVar(expr.Id, tt.TypeID); return(true); } // no existe el tipo de la variable _errorListener.Add(AnalysisError.TypeIsNotDefined(expr, expr.TypeId)); expr.ReturnType = TigerType.GetType <ErrorType>(); _scope.AddVar(expr.Id, TigerType.GetType <ErrorType>().TypeID); return(false); } if (!expr.ExpressionValue.ReturnType.IsLegalType) { _errorListener.Add(AnalysisError.TypeCannotBeInferred(expr, expr.Id)); expr.ReturnType = TigerType.GetType <ErrorType>(); _scope.AddVar(expr.Id, TigerType.GetType <ErrorType>().TypeID); return(false); } _scope.AddVar(expr.Id, expr.ExpressionValue.ReturnType.TypeID); return(true); }