Exemplo n.º 1
0
        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);
        }