Exemplo n.º 1
0
        public override void Evaluate(ComputationContext ctx)
        {
            // in theory we would like to write legal code like
            // (*local_int_ptr) = 1
            // but the problem is dereference can be seen as omitting setter (property or special functions) logic
            // so for now we disable it, and see when for the first time it will be needed in practice
            // note: swap function does not count since we already have parallel assignments
            //
            // and one more small thing, without dereference there is no ambiguity here
            // ref = value
            // does it mean (*ref) = value or ref = &value
            if (!ctx.Env.Options.AllowDereference)
            {
                throw new InvalidOperationException();
            }

            if (this.Evaluation == null)
            {
                if (!ctx.Env.Dereferenced(Expr.Evaluation.Components, out IEntityInstance inner_comp))
                {
                    ctx.AddError(ErrorCode.DereferencingValue, this.Expr);
                }

                ctx.Env.Dereferenced(Expr.Evaluation.Aggregate, out IEntityInstance inner_aggr);

                this.typename = inner_comp.NameOf;
                this.typename.AttachTo(this);
                this.typename.Evaluated(ctx, EvaluationCall.AdHocCrossJump);

                this.Evaluation = EvaluationInfo.Create(inner_comp, inner_aggr.Cast <EntityInstance>());
            }
        }
Exemplo n.º 2
0
 public override void Evaluate(ComputationContext ctx)
 {
     if (this.Evaluation == null)
     {
         this.Evaluation = EvaluationInfo.Create(ctx.Env.BoolType.InstanceOf.Build(Lifetime.Create(this)));
     }
 }
Exemplo n.º 3
0
        public override void Evaluate(ComputationContext ctx)
        {
            if (this.Evaluation == null)
            {
                this.Evaluation = EvaluationInfo.Create(ctx.Env.BoolType.InstanceOf);

                this.DataTransfer(ctx, ref this.lhs, ctx.Env.BoolType.InstanceOf);
                this.DataTransfer(ctx, ref this.rhs, ctx.Env.BoolType.InstanceOf);
            }
        }
Exemplo n.º 4
0
        public void Evaluate(ComputationContext ctx)
        {
            if (this.Evaluation == null)
            {
                // trap only lambdas, name reference is a call, not passing function around
                // for example here trapping lambda into closure is necessary
                // ((x) => x*x)()
                // and here is not (regular call)
                // f()
                if (this.TrapLambdaClosure(ctx, ref this.callee))
                {
                    ConvertToExplicitInvoke(ctx);
                }

                {
                    EntityInstance eval = this.Callee.Evaluation.Components.Cast <EntityInstance>();

                    this.Callee.DereferencedCount_LEGACY = ctx.Env.DereferencedOnce(eval, out IEntityInstance __eval, out bool via_pointer) ? 1 : 0;
                    this.DereferencingCount = this.Callee.DereferencedCount_LEGACY;
                    if (this.Callee.DereferencedCount_LEGACY > 0)
                    {
                        eval = __eval.Cast <EntityInstance>();
                    }

                    if (!(this.Name.Binding.Match.Instance.Target is FunctionDefinition) &&
                        eval.Target.Cast <TypeDefinition>().InvokeFunctions().Any())
                    {
                        // if we call a "closure", like my_closure() it is implicit calling "invoke"
                        // so make it explicit on the fly
                        ConvertToExplicitInvoke(ctx);
                    }
                }

                IEnumerable <EntityInstance> matches = this.Name.Binding.Matches
                                                       .Select(it =>
                {
                    if (it.Instance.Target.IsFunction())
                    {
                        return(it.Instance);
                    }
                    else if (it.Instance.Target is Property prop)
                    {
                        return(prop.Getter?.InstanceOf?.TranslateThrough(it.Instance));
                    }
                    else
                    {
                        return(null);
                    }
                })
                                                       .Where(it => it != null);

                if (!matches.Any())
                {
                    this.resolution = new Option <CallResolution>(null);
                    if (!this.Callee.Evaluation.Components.IsJoker) // do not cascade errors
                    {
                        ctx.AddError(ErrorCode.NotFunctionType, this.Callee);
                    }
                }
                else
                {
                    IEnumerable <CallResolution> targets = matches
                                                           .Select(it => CallResolution.Create(ctx, this.Name.TemplateArguments, this,
                                                                                               createCallContext(ctx, this.Name, it.TargetFunction), targetFunctionInstance: it))
                                                           .Where(it => it != null)
                                                           .StoreReadOnly();
                    targets = targets.Where(it => it.RequiredParametersUsed()).StoreReadOnly();
                    targets = targets.Where(it => it.CorrectlyFormedArguments()).StoreReadOnly();
                    targets = targets.Where(it => it.ArgumentTypesMatchParameters(ctx)).StoreReadOnly();
                    if (this.RequestedOutcomeTypeName != null)
                    {
                        targets = targets.Where(it => it.OutcomeMatchesRequest(ctx)).StoreReadOnly();
                    }

                    targets = resolveOverloading(targets).StoreReadOnly();

                    this.resolution = new Option <CallResolution>(targets.FirstOrDefault());

                    if (!targets.Any())
                    {
                        ctx.AddError(ErrorCode.TargetFunctionNotFound, this);
                    }
                    else
                    {
                        if (targets.Count() > 1)
                        {
                            ctx.ErrorManager.AddError(ErrorCode.NOTEST_AmbiguousOverloadedCall, this,
                                                      targets.Select(it => it.TargetFunctionInstance.Target));
                        }

                        foreach (var group in this.Resolution.GetArgumentsMultipleTargeted())
                        {
                            // we only report second "override" because if there are more
                            // it is more likely user forgot to mark parameter variadic
                            ctx.ErrorManager.AddError(ErrorCode.ArgumentForFunctionAlreadyGiven, group.Skip(1).FirstOrDefault());
                        }

                        foreach (FunctionParameter param in this.Resolution.GetUnfulfilledVariadicParameters())
                        {
                            ctx.ErrorManager.AddError(ErrorCode.InvalidNumberVariadicArguments, this, param);
                        }


                        if (targets.Count() == 1)
                        {
                            this.Resolution.EnhanceArguments(ctx);
                        }

                        this.Resolution.SetMappings(ctx);

                        // filtering here is a bit shaky -- if we don't use type inference
                        // we have to filter by what we bind to, but if we use inference
                        // we use target instance (functor or function, not a variable) because only it
                        // is altered by type inference

                        if (this.Resolution.InferredTemplateArguments == null)
                        {
                            // leave only binding which was used for mapping
                            this.Name.Binding.Filter(it => it.IsIdentical(this.Resolution.TargetFunctionInstance));
                        }
                        else
                        {
                            NameReference this_name = this.Name;
                            this_name.DetachFrom(this);
                            this.callee = this_name.Recreate(this.Resolution.InferredTemplateArguments
                                                             .Select(it => new TemplateArgument(it)),
                                                             this.Resolution.TargetFunctionInstance, this_name.Binding.Match.IsLocal);
                            this.callee.AttachTo(this);

                            this.Callee.Evaluated(ctx, EvaluationCall.AdHocCrossJump);

                            if (!this.Name.Binding.HasMatch)
                            {
                                throw new Exception("We've just lost our binding, probably something wrong with template translations");
                            }
                        }

                        this.Evaluation = this.Resolution.Evaluation;

                        if (ctx.Env.IsReferenceOfType(this.Evaluation.Aggregate))
                        {
                            // basically we are saying that the outcome of the function has the lifetime
                            // equal to the shortest lifetime of arguments
                            // or local if the function has not arguments at all
                            Lifetime lifetime = null;
                            foreach (FunctionArgument arg in this.Resolution.ActualArguments)
                            {
                                // todo: we should check if the expression is not passed implictly by reference
                                if (arg == this.Resolution.MetaThisArgument || ctx.Env.IsReferenceOfType(arg.Evaluation.Aggregate))
                                {
                                    lifetime = arg.Evaluation.Aggregate.Lifetime.Shorter(lifetime);
                                }
                            }

                            if (lifetime == null)
                            {
                                lifetime = Lifetime.Create(this);
                            }

                            if (this.Evaluation.Aggregate.Lifetime != lifetime)
                            {
                                this.Evaluation = EvaluationInfo.Create(
                                    this.Evaluation.Components.Rebuild(ctx, lifetime, deep: false),
                                    this.Evaluation.Aggregate.Build(lifetime));
                            }
                        }
                    }
                }


                if (this.Evaluation == null)
                {
                    this.Evaluation = Environment.JokerEval;
                }

                foreach (IExpression arg in UserArguments)
                {
                    arg.ValidateValueExpression(ctx);
                }
            }
        }