예제 #1
0
        public static CompletionOr <List <IValue>?> EvaluateArgument(Interpreter interpreter, IArgumentItem a)
        {
            List <IValue> ret = new List <IValue>();
            Completion    valueComp;
            IValue        value;

            switch (a)
            {
            case SpreadElement spreadElement:
                valueComp = spreadElement.assignmentExpression.Evaluate(interpreter).GetValue();
                if (valueComp.IsAbrupt())
                {
                    return(valueComp.WithEmpty <List <IValue>?>());
                }
                value = valueComp.value !;
                if (!(value is Object @object))
                {
                    throw new InvalidOperationException($"NewMemberExpression: tried to create an argument list using a spread on a non-object");
                }
                var iteratorRecordComp = @object.GetIterator();
                if (iteratorRecordComp.IsAbrupt())
                {
                    return(iteratorRecordComp.WithEmpty <List <IValue>?>());
                }
                var iteratorRecord = iteratorRecordComp.Other !;
                while (true)
                {
                    var next = iteratorRecord.IteratorStep();
                    if (next.IsAbrupt())
                    {
                        return(next.WithEmpty <List <IValue>?>());
                    }
                    if (next.value == BooleanValue.False)
                    {
                        break;
                    }
                    var nextArg = IteratorRecord.IteratorValue(next.value !);
                    if (nextArg.IsAbrupt())
                    {
                        return(nextArg.WithEmpty <List <IValue>?>());
                    }
                    ret.Add(nextArg.value !);
                }
                break;

            case AbstractAssignmentExpression assignmentExpression:
                valueComp = assignmentExpression.Evaluate(interpreter).GetValue();
                if (valueComp.IsAbrupt())
                {
                    return(valueComp.WithEmpty <List <IValue>?>());
                }
                value = valueComp.value !;
                ret.Add(value);
                break;

            default:
                throw new InvalidOperationException($"NewMemberExpression: unhandled IArgumentItem type {a.GetType()}");
            }
            return(Completion.NormalWith(ret));
        }
예제 #2
0
        public override CompletionOr <PropertyDescriptor?> GetOwnProperty(string P)
        {
            var desc = OrdinaryGetOwnProperty(P);

            if (desc != null)
            {
                return(Completion.NormalWith(desc));
            }
            return(StringGetOwnProperty(P));
        }
예제 #3
0
 private static CompletionOr <BooleanValue?> thisBooleanValue(IValue value)
 {
     if (value is BooleanValue b)
     {
         return(Completion.NormalWith(b));
     }
     if (value is BooleanObject o)
     {
         return(Completion.NormalWith(o.Value));
     }
     return(Completion.ThrowTypeError("Must operate on a Boolean value or object").WithEmpty <BooleanValue?>());
 }
예제 #4
0
 private static CompletionOr <NumberValue?> thisNumberValue(IValue value)
 {
     if (value is NumberValue n)
     {
         return(Completion.NormalWith(n));
     }
     if (value is NumberObject o)
     {
         return(Completion.NormalWith(o.value));
     }
     return(Completion.ThrowTypeError("Must operate on a Number value or object").WithEmpty <NumberValue?>());
 }
예제 #5
0
        public override CompletionOr <PropertyDescriptor?> GetOwnProperty(string P)
        {
            var desc = OrdinaryGetOwnProperty(P);

            if (desc == null)
            {
                return(Completion.NormalWith(desc));
            }
            var isMapped = ParameterMap.HasOwnProperty(P).Other;

            if (isMapped)
            {
                desc.Value = ParameterMap.Get(P).value;
            }
            return(Completion.NormalWith(desc));
        }
예제 #6
0
 private CompletionOr <PropertyDescriptor?> StringGetOwnProperty(string P)
 {
     if (!double.TryParse(P, out double index))
     {
         return(Completion.NormalCompletion().WithEmpty <PropertyDescriptor?>());
     }
     if (index != (int)index)
     {
         return(Completion.NormalCompletion().WithEmpty <PropertyDescriptor?>());
     }
     if (index == 0d && BitConverter.GetBytes(index)[7] == 128) // negative zero
     {
         return(Completion.NormalCompletion().WithEmpty <PropertyDescriptor?>());
     }
     if (index < 0 || [email protected] <= index)
     {
         return(Completion.NormalCompletion().WithEmpty <PropertyDescriptor?>());
     }
     return(Completion.NormalWith(new PropertyDescriptor(new StringValue(value.@string[(int)index].ToString(System.Globalization.CultureInfo.InvariantCulture)), false, true, false)));
 }
예제 #7
0
        public static CompletionOr <PropertyDescriptor?> FromObject(Object Obj)
        {
            var desc = new PropertyDescriptor();

            var hasEnumerable = Obj.HasProperty("enumerable");

            if (hasEnumerable.IsAbrupt())
            {
                return(hasEnumerable.WithEmpty <PropertyDescriptor?>());
            }
            if (hasEnumerable.Other)
            {
                var enumerable = Obj.Get("enumerable");
                if (enumerable.IsAbrupt())
                {
                    return(enumerable.WithEmpty <PropertyDescriptor?>());
                }
                desc.Enumerable = enumerable.value !.ToBoolean().boolean;
            }

            var hasConfigurable = Obj.HasProperty("configurable");

            if (hasConfigurable.IsAbrupt())
            {
                return(hasConfigurable.WithEmpty <PropertyDescriptor?>());
            }
            if (hasConfigurable.Other)
            {
                var configurable = Obj.Get("configurable");
                if (configurable.IsAbrupt())
                {
                    return(configurable.WithEmpty <PropertyDescriptor?>());
                }
                desc.Configurable = configurable.value !.ToBoolean().boolean;
            }

            var hasValue = Obj.HasProperty("value");

            if (hasValue.IsAbrupt())
            {
                return(hasValue.WithEmpty <PropertyDescriptor?>());
            }
            if (hasValue.Other)
            {
                var value = Obj.Get("value");
                if (value.IsAbrupt())
                {
                    return(value.WithEmpty <PropertyDescriptor?>());
                }
                desc.Value = value.value !;
            }

            var hasWritable = Obj.HasProperty("writable");

            if (hasWritable.IsAbrupt())
            {
                return(hasWritable.WithEmpty <PropertyDescriptor?>());
            }
            if (hasWritable.Other)
            {
                var writable = Obj.Get("writable");
                if (writable.IsAbrupt())
                {
                    return(writable.WithEmpty <PropertyDescriptor?>());
                }
                desc.Writable = writable.value !.ToBoolean().boolean;
            }

            var hasGet = Obj.HasProperty("get");

            if (hasGet.IsAbrupt())
            {
                return(hasGet.WithEmpty <PropertyDescriptor?>());
            }
            if (hasGet.Other)
            {
                var get = Obj.Get("get");
                if (get.IsAbrupt())
                {
                    return(get.WithEmpty <PropertyDescriptor?>());
                }
                if (get.value != UndefinedValue.Instance)
                {
                    if (!(get.value is Callable callable))
                    {
                        return(Completion.ThrowTypeError("get property is not callable").WithEmpty <PropertyDescriptor?>());
                    }
                    desc.Get = callable;
                }
            }

            var hasSet = Obj.HasProperty("set");

            if (hasSet.IsAbrupt())
            {
                return(hasSet.WithEmpty <PropertyDescriptor?>());
            }
            if (hasSet.Other)
            {
                var set = Obj.Get("set");
                if (set.IsAbrupt())
                {
                    return(set.WithEmpty <PropertyDescriptor?>());
                }
                if (set.value != UndefinedValue.Instance)
                {
                    if (!(set.value is Callable callable))
                    {
                        return(Completion.ThrowTypeError("set property is not callable").WithEmpty <PropertyDescriptor?>());
                    }
                    desc.Set = callable;
                }
            }

            if ((desc.Get != null || desc.Set != null) && (desc.Value != null || desc.Writable.HasValue))
            {
                return(Completion.ThrowTypeError("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute").WithEmpty <PropertyDescriptor?>());
            }

            return(Completion.NormalWith(desc));
        }
예제 #8
0
 public virtual CompletionOr <PropertyDescriptor?> GetOwnProperty(string P)
 {
     return(Completion.NormalWith(OrdinaryGetOwnProperty(P)));
 }