private void CreateInstanceOfWrapper(LetExpressionAST let) { string currentFunctionCodeName = let.CurrentScope.CurrentFunction.CodeName; TypeCodeInfo typeCodeInfo = code.GetWrapperAsociatteTo(currentFunctionCodeName); ILGenerator il = code.Method.GetILGenerator(); //crear la instancia del objeto que contiene las variable mias que son usadas por otras funciones il.Emit(OpCodes.Newobj, typeCodeInfo.DefaultConstructor()); il.Emit(OpCodes.Stloc_0); //asignarle la instancia de mi clase a esta objeto para que tenga la referencia a su padre. //locaL_0.parent = this. if (let.CurrentScope.CurrentFunction.FunctionName != "main$") { FieldBuilder parent = typeCodeInfo.GetField("parent"); il.Emit(OpCodes.Ldloc_0); //cargar el this il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Stfld, parent); //darle los valores de las variables a los campos de esta clase. InitilizateFieldFromParameters(let); } //obligo a que se lanze el evento que estan esperando los que inicializa las varialbles code.ThrowEventForFunction(currentFunctionCodeName); }
public override bool VisitLetExpression(LetExpressionAST expr) { var other = _other as LetExpressionAST; if (other == null) { return(false); } return(IsEqualNodes(other.SequenceExpressionList, expr.SequenceExpressionList) && other.DeclarationList.Count == expr.DeclarationList.Count && other.DeclarationList.Zip(expr.DeclarationList, IsEqualNodes).All(x => x)); }
public override Unit VisitLetExpression(LetExpressionAST expr) { //declarar lo que se declarable foreach (var item in expr.DeclarationList) { item.Accept(this); } //crear la instancia del tipo wrapper que esta como variable local en la funcion CreateInstanceOfWrapper(expr); //generar el codigo para el cuerpo ejecutable del let. expr.SequenceExpressionList.Accept(this); return(Unit.Create()); }
/// <summary> /// Este metodo asigna los valores de los parametros que son usados por otra funciones a los campos de la clase que /// tengo como variable local /// </summary> /// <param name="let"></param> private void InitilizateFieldFromParameters(LetExpressionAST let) { ILGenerator il = code.Method.GetILGenerator(); FunctionInfo funInfo = let.CurrentScope.GetFunction(let.CurrentScope.CurrentFunction.FunctionName); for (int i = 0; i < funInfo.ParameterList.Count; i++) { VarInfo varInfo = let.CurrentScope.GetVarInfo(funInfo.ParameterList[0].Key); if (funInfo.VarsUsedForAnotherFunction.Contains(varInfo)) { //se asume que el wrapper siempre esta como primera variable del metodo. il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldarg, i + 1); il.Emit(OpCodes.Stfld, code.DefinedField[varInfo.CodeName]); } } }
public abstract T VisitLetExpression(LetExpressionAST expr);
public override bool VisitLetExpression(LetExpressionAST letExpr) { //First, we process the type declaration in the let. var typeDeclarations = letExpr.DeclarationList.Where(x => x is TypeDeclarationAST).ToList(); //el let abre un nuevo scope var sc = new Scope(_scope, _scope.ContainerLoop); PushScope(sc); letExpr.CurrentScope = sc; foreach (var typeDeclaration in typeDeclarations) { typeDeclaration.Accept(this); } //notify that all types in this scope where proccessed. Then if there was fields with unsolved //types, this is the momemnt to catch errors. sc.NotifyEndTypeScope(); var errorAfterClosingScope = _errorListener.Count != 0; //Declaration List //se asume q no habra problemas letExpr.ReturnType = TigerType.GetType <NoType>(); //Second. We do a first pass over function declarations //to verifies function signatures and then add function signature to the scope. var functionDeclarations = letExpr.DeclarationList.Where(x => (x is FunctionDeclarationAST)).Cast <FunctionDeclarationAST>(); foreach (var fDecl in functionDeclarations) { //se hace el primer chequeo CheckFunctionSignature(fDecl); } //a medida q aparezcan las funciones se incrementa el contador var noTypeDeclarations = letExpr.DeclarationList.Where(x => !(x is TypeDeclarationAST)); foreach (var noTypeDeclaration in noTypeDeclarations) { FunctionDeclarationAST fDecl; //si es una declaracion de funcion if ((fDecl = noTypeDeclaration as FunctionDeclarationAST) != null) { //segundo chequeo para comprobar el cuerpo if (!fDecl.Accept(this)) { letExpr.ReturnType = TigerType.GetType <ErrorType>(); } } else if (!noTypeDeclaration.Accept(this)) { letExpr.ReturnType = TigerType.GetType <ErrorType>(); } } //cierra el scope pq no habran mas declaraciones //checks the body of the let //verifies that there were no errors (eg. that a type was not found after closing the scope) if (letExpr.SequenceExpressionList.Accept(this) && letExpr.ReturnType == TigerType.GetType <NoType>() && !errorAfterClosingScope) { letExpr.AlwaysReturn = letExpr.SequenceExpressionList.AlwaysReturn; letExpr.ReturnType = letExpr.SequenceExpressionList.ReturnType; PopScope(); return(true); } PopScope(); return(false); }