public override void SurroundWith(Environment environment) { base.SurroundWith(environment); if (DeclaredType is UnknownType unknownType) { unknownType.SurroundWith(Env); DeclaredType = unknownType.Resolve(); } foreach (var variableDeclaration in ParameterList) { variableDeclaration.SurroundWith(Env); } var bodyEnv = new Environment(Env); foreach (var variableDeclaration in ParameterList) { bodyEnv.Declarations.Add(variableDeclaration); } // FEATURE #37 var recur = new VariableDeclaration(MetaData, ReservedWords.Recur, this); // https://github.com/Cm-lang/Cm-Document/issues/12 if (null != DeclaredType) { Type = new LambdaType(MetaData, ( from i in ParameterList select i.Type).ToList(), DeclaredType); } // FEATURE #39 recur.SurroundWith(Env); bodyEnv.Declarations.Add(recur); Body.SurroundWith(bodyEnv); var retTypes = Body.FindReturnStatements().Select(i => { i.WhereToJump = this; return(i.Expression.GetExpressionType()); }).ToList(); // FEATURE #24 if (retTypes.Any(i => !Equals(i, DeclaredType ?? retTypes.First()))) { Errors.Add( $"{MetaData.GetErrorHeader()}ambiguous return types:\n" + (DeclaredType != null ? $"<{DeclaredType}>" : "") + $"[{string.Join(",", from i in retTypes select i.ToString())}]"); } // FEATURE #12 var retType = DeclaredType ?? (retTypes.Count != 0 ? retTypes.First() // FEATURE #19 : new PrimaryType(MetaData, PrimaryType.NullType)); Type = new LambdaType(MetaData, ( from i in ParameterList select i.Type).ToList(), retType); }