Ejemplo n.º 1
0
        private async Task <ExecValue> assignedNativeString(ExecutionContext ctx, ObjectData thisValue, string s)
        {
            ObjectData obj = await ObjectData.CreateInstanceAsync(ctx, ctx.Env.Utf8StringType.InstanceOf, s).ConfigureAwait(false);

            thisValue.Assign(obj);
            return(ExecValue.CreateReturn(null));
        }
Ejemplo n.º 2
0
        private async Task <ExecValue> executeNativeChannelFunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData this_value)
        {
            if (func.IsDefaultInitConstructor())
            {
                Channels.IChannel <ObjectData> channel = Channels.Channel.Create <ObjectData>();
                ctx.Heap.TryAddDisposable(channel);
                ObjectData channel_obj = await ObjectData.CreateInstanceAsync(ctx, this_value.RunTimeTypeInstance, channel).ConfigureAwait(false);

                this_value.Assign(channel_obj);
                return(ExecValue.CreateReturn(null));
            }
            else if (func.Name.Name == NameFactory.ChannelSend)
            {
                ObjectData arg = ctx.FunctionArguments.Single();
                if (!ctx.Env.IsPointerOfType(arg.RunTimeTypeInstance))
                {
                    arg = arg.Copy();
                }

                Channels.IChannel <ObjectData> channel = this_value.PlainValue.Cast <Channels.IChannel <ObjectData> >();
                bool result = await channel.SendAsync(arg).ConfigureAwait(false);

                return(ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx, this_value.RunTimeTypeInstance, result).ConfigureAwait(false)));
            }
            else if (func.Name.Name == NameFactory.ChannelReceive)
            {
                Channels.IChannel <ObjectData> channel = this_value.PlainValue.Cast <Channels.IChannel <ObjectData> >();
                EntityInstance  channel_type           = this_value.RunTimeTypeInstance;
                IEntityInstance value_type             = channel_type.TemplateArguments.Single();

                Option <ObjectData> received = await channel.ReceiveAsync().ConfigureAwait(false);

                // we have to compute Skila Option type (not C# one we use for C# channel type)
                EntityInstance option_type = ctx.Env.OptionType.GetInstance(
                    TypeMutability.None,
                    TemplateTranslation.Create(ctx.Env.OptionType.InstanceOf, value_type),
                    Lifetime.Timeless);
                ExecValue opt_exec = await createOption(ctx, option_type, received).ConfigureAwait(false);

                if (opt_exec.IsThrow)
                {
                    return(opt_exec);
                }
                ObjectData result = opt_exec.ExprValue;

                // at this point Skila option is initialized so we can return it

                return(ExecValue.CreateReturn(result));
            }
            else
            {
                throw new NotImplementedException($"{ExceptionCode.SourceInfo()}");
            }
        }
Ejemplo n.º 3
0
 private static async Task <ExecValue> executeNativeUnitFunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData this_value)
 {
     if (func.IsDefaultInitConstructor())
     {
         this_value.Assign(await ObjectData.CreateInstanceAsync(ctx, this_value.RunTimeTypeInstance, UnitType.UnitValue).ConfigureAwait(false));
         return(ExecValue.CreateReturn(null));
     }
     else
     {
         throw new NotImplementedException($"{ExceptionCode.SourceInfo()}");
     }
 }
Ejemplo n.º 4
0
 private static async Task <ExecValue> executeNativeBoolFunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData this_value)
 {
     if (func.IsDefaultInitConstructor())
     {
         this_value.Assign(await ObjectData.CreateInstanceAsync(ctx, this_value.RunTimeTypeInstance, false).ConfigureAwait(false));
         return(ExecValue.CreateReturn(null));
     }
     else if (func.IsCopyInitConstructor(ctx.CreateBareComputation()))
     {
         this_value.Assign(ctx.FunctionArguments.Single());
         return(ExecValue.CreateReturn(null));
     }
     else if (func.Name.Name == NameFactory.NotOperator)
     {
         return(ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx, this_value.RunTimeTypeInstance,
                                                                            !this_value.PlainValue.Cast <bool>()).ConfigureAwait(false)));
     }
     else
     {
         throw new NotImplementedException($"{ExceptionCode.SourceInfo()}");
     }
 }
Ejemplo n.º 5
0
        private static async Task <ExecValue> executeNativeEnumFunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData this_value)
        {
            if (func.IsInitConstructor() &&
                func.Parameters.Count == 1 && func.Parameters.Single().Name.Name == NameFactory.EnumConstructorParameter)
            {
                ObjectData arg_obj = ctx.FunctionArguments.Single();
                // changing runtime type from some kind enum (Nat/Int) to truly enum
                ObjectData enum_obj = await ObjectData.CreateInstanceAsync(ctx, this_value.RunTimeTypeInstance, arg_obj.PlainValue).ConfigureAwait(false);

                this_value.Assign(enum_obj);
                return(ExecValue.CreateReturn(null));
            }
            else if (func.Name.Name == NameFactory.EqualOperator)
            {
                ObjectData arg      = ctx.FunctionArguments.Single();
                var        this_int = this_value.NativeNat;
                var        arg_int  = arg.NativeNat;
                ExecValue  result   = ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx,
                                                                                                  func.ResultTypeName.Evaluation.Components, this_int == arg_int).ConfigureAwait(false));
                return(result);
            }
            else if (func.Name.Name == NameFactory.NotEqualOperator)
            {
                ObjectData arg      = ctx.FunctionArguments.Single();
                var        this_int = this_value.NativeNat;
                var        arg_int  = arg.NativeNat;
                ExecValue  result   = ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx,
                                                                                                  func.ResultTypeName.Evaluation.Components, this_int != arg_int).ConfigureAwait(false));
                return(result);
            }
            else if (func.Name.Name == NameFactory.ConvertFunctionName)
            {
                if (ctx.Env.IsNatType(func.ResultTypeName.Evaluation.Components))
                {
                    ObjectData result = await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components,
                                                                             this_value.PlainValue).ConfigureAwait(false);

                    return(ExecValue.CreateReturn(result));
                }
                else
                {
                    throw new NotImplementedException($"Enum func {func} is not implemented");
                }
            }
            else
            {
                throw new NotImplementedException($"Function {func} is not implemented");
            }
        }
Ejemplo n.º 6
0
        private async Task <ExecValue> executeNativeNat8FunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData thisValue)
        {
            if (func == ctx.Env.Nat8ParseStringFunction)
            {
                ObjectData arg_ptr = ctx.FunctionArguments.Single();
                ObjectData arg_val = arg_ptr.DereferencedOnce();

                string input_str = arg_val.NativeString;
                Option <ObjectData> int_obj;
                if (byte.TryParse(input_str, out byte int_val))
                {
                    int_obj = new Option <ObjectData>(await ObjectData.CreateInstanceAsync(ctx, ctx.Env.Nat8Type.InstanceOf, int_val)
                                                      .ConfigureAwait(false));
                }
                else
                {
                    int_obj = new Option <ObjectData>();
                }

                ExecValue opt_exec = await createOption(ctx, func.ResultTypeName.Evaluation.Components, int_obj).ConfigureAwait(false);

                if (opt_exec.IsThrow)
                {
                    return(opt_exec);
                }
                ObjectData result = opt_exec.ExprValue;
                return(ExecValue.CreateReturn(result));
            }
            else if (func.Name.Name == NameFactory.AddOperator)
            {
                var this_int = thisValue.NativeNat8;

                ObjectData arg     = ctx.FunctionArguments.Single();
                var        arg_int = arg.NativeNat8;

                byte       value     = (byte)checked (this_int + arg_int);
                ObjectData res_value = await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, value)
                                       .ConfigureAwait(false);

                ExecValue result = ExecValue.CreateReturn(res_value);
                return(result);
            }
            else if (func.Name.Name == NameFactory.AddOverflowOperator)
            {
                var this_int = thisValue.NativeNat8;

                ObjectData arg     = ctx.FunctionArguments.Single();
                var        arg_int = arg.NativeNat8;

                byte       value     = (byte)(this_int + arg_int);
                ObjectData res_value = await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, value)
                                       .ConfigureAwait(false);

                ExecValue result = ExecValue.CreateReturn(res_value);
                return(result);
            }
            else if (func.Name.Name == NameFactory.MulOperator)
            {
                var this_int = thisValue.NativeNat8;

                ObjectData arg     = ctx.FunctionArguments.Single();
                var        arg_int = arg.NativeNat8;

                byte       value     = (byte)checked (this_int * arg_int);
                ObjectData res_value = await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, value)
                                       .ConfigureAwait(false);

                ExecValue result = ExecValue.CreateReturn(res_value);
                return(result);
            }
            else if (func.Name.Name == NameFactory.SubOperator)
            {
                ObjectData arg       = ctx.FunctionArguments.Single();
                var        this_int  = thisValue.NativeNat8;
                var        arg_int   = arg.NativeNat8;
                byte       value     = (byte)checked (this_int - arg_int);
                ObjectData res_value = await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, value)
                                       .ConfigureAwait(false);

                ExecValue result = ExecValue.CreateReturn(res_value);
                return(result);
            }
            else if (func.IsDefaultInitConstructor())
            {
                thisValue.Assign(await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, (byte)0).ConfigureAwait(false));
                return(ExecValue.CreateReturn(null));
            }
            else if (func.IsCopyInitConstructor(ctx.CreateBareComputation()))
            {
                thisValue.Assign(ctx.FunctionArguments.Single());
                return(ExecValue.CreateReturn(null));
            }
            else if (func.Name.Name == NameFactory.ComparableCompare)
            {
                ObjectData arg      = ctx.FunctionArguments.Single();
                var        this_int = thisValue.NativeNat8;
                var        arg_int  = arg.NativeNat8;

                ObjectData ordering_type = await ctx.TypeRegistry.RegisterGetAsync(ctx, ctx.Env.OrderingType.InstanceOf).ConfigureAwait(false);

                ObjectData ordering_value;
                if (this_int < arg_int)
                {
                    ordering_value = ordering_type.GetField(ctx.Env.OrderingLess);
                }
                else if (this_int > arg_int)
                {
                    ordering_value = ordering_type.GetField(ctx.Env.OrderingGreater);
                }
                else
                {
                    ordering_value = ordering_type.GetField(ctx.Env.OrderingEqual);
                }

                ExecValue result = ExecValue.CreateReturn(ordering_value);
                return(result);
            }
            else
            {
                ExecValue?result = await numComparisonAsync <byte>(ctx, func, thisValue).ConfigureAwait(false);

                if (result.HasValue)
                {
                    return(result.Value);
                }
                else
                {
                    throw new NotImplementedException($"Function {func} is not implemented");
                }
            }
        }
Ejemplo n.º 7
0
        private async Task <ExecValue> executeNativeReal64FunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData thisValue)
        {
            if (func == ctx.Env.Real64ParseStringFunction)
            {
                ObjectData arg_ptr = ctx.FunctionArguments.Single();
                ObjectData arg_val = arg_ptr.DereferencedOnce();

                string input_str = arg_val.NativeString;
                Option <ObjectData> int_obj;
                if (Double.TryParse(input_str, out Double int_val))
                {
                    int_obj = new Option <ObjectData>(await ObjectData.CreateInstanceAsync(ctx, ctx.Env.Real64Type.InstanceOf, int_val)
                                                      .ConfigureAwait(false));
                }
                else
                {
                    int_obj = new Option <ObjectData>();
                }

                ExecValue opt_exec = await createOption(ctx, func.ResultTypeName.Evaluation.Components, int_obj).ConfigureAwait(false);

                if (opt_exec.IsThrow)
                {
                    return(opt_exec);
                }
                ObjectData result = opt_exec.ExprValue;
                return(ExecValue.CreateReturn(result));
            }
            else if (func.Name.Name == NameFactory.AddOperator)
            {
                var this_int = thisValue.NativeReal64;

                ObjectData arg     = ctx.FunctionArguments.Single();
                var        arg_int = arg.NativeReal64;

                double     value     = checked (this_int + arg_int);
                ObjectData res_value = await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, value)
                                       .ConfigureAwait(false);

                ExecValue result = ExecValue.CreateReturn(res_value);
                return(result);
            }
            else if (func.Name.Name == NameFactory.AddOverflowOperator)
            {
                var this_int = thisValue.NativeReal64;

                ObjectData arg     = ctx.FunctionArguments.Single();
                var        arg_int = arg.NativeReal64;

                double     value1    = this_int + arg_int;
                ObjectData res_value = await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, value1)
                                       .ConfigureAwait(false);

                ExecValue result = ExecValue.CreateReturn(res_value);
                return(result);
            }
            else if (func.Name.Name == NameFactory.MulOperator)
            {
                var this_int = thisValue.NativeReal64;

                ObjectData arg     = ctx.FunctionArguments.Single();
                var        arg_int = arg.NativeReal64;

                double     value2    = checked (this_int * arg_int);
                ObjectData res_value = await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, value2)
                                       .ConfigureAwait(false);

                ExecValue result = ExecValue.CreateReturn(res_value);
                return(result);
            }
            else if (func.Name.Name == NameFactory.SubOperator)
            {
                ObjectData arg       = ctx.FunctionArguments.Single();
                var        this_int  = thisValue.NativeReal64;
                var        arg_int   = arg.NativeReal64;
                double     value3    = checked (this_int - arg_int);
                ObjectData res_value = await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, value3)
                                       .ConfigureAwait(false);

                ExecValue result = ExecValue.CreateReturn(res_value);
                return(result);
            }
            else if (func.Name.Name == NameFactory.DivideOperator)
            {
                ObjectData arg      = ctx.FunctionArguments.Single();
                var        this_int = thisValue.NativeReal64;
                var        arg_int  = arg.NativeReal64;
                double     value    = checked (this_int / arg_int);
                if (!ctx.Env.Options.AllowRealMagic && (double.IsNaN(value) || double.IsInfinity(value)))
                {
                    ExecValue exec_cons = await createObject(ctx, ctx.Env.ExceptionType.Modifier.HasHeapOnly,
                                                             ctx.Env.ExceptionType.InstanceOf, ctx.Env.ExceptionType.DefaultConstructor(), null).ConfigureAwait(false);

                    if (exec_cons.IsThrow)
                    {
                        return(exec_cons);
                    }
                    if (ctx.Env.ExceptionType.Modifier.HasHeapOnly)
                    {
                        ctx.Heap.TryInc(ctx, exec_cons.ExprValue, RefCountIncReason.ThrowingException, "");
                    }
                    return(ExecValue.CreateThrow(exec_cons.ExprValue));
                }

                ObjectData res_value = await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, value)
                                       .ConfigureAwait(false);

                ExecValue result = ExecValue.CreateReturn(res_value);
                return(result);
            }
            // keep it for NaNs (as long as they part of the language)
            else if (func.Name.Name == NameFactory.EqualOperator)
            {
                var this_int = thisValue.NativeReal64;

                ObjectData arg     = ctx.FunctionArguments.Single();
                var        arg_int = arg.NativeReal64;
                ExecValue  result  = ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components,
                                                                                                 this_int == arg_int).ConfigureAwait(false));
                return(result);
            }
            else if (func.Name.Name == NameFactory.NotEqualOperator)
            {
                var this_int = thisValue.NativeReal64;

                ObjectData arg     = ctx.FunctionArguments.Single();
                var        arg_int = arg.NativeReal64;
                ExecValue  result  = ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components,
                                                                                                 this_int != arg_int).ConfigureAwait(false));
                return(result);
            }
            else if (func.IsDefaultInitConstructor())
            {
                thisValue.Assign(await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, (double)0).ConfigureAwait(false));
                return(ExecValue.CreateReturn(null));
            }
            else if (func.IsCopyInitConstructor(ctx.CreateBareComputation()))
            {
                thisValue.Assign(ctx.FunctionArguments.Single());
                return(ExecValue.CreateReturn(null));
            }
            else if (func == ctx.Env.Real64FromNat8Constructor)
            {
                ObjectData arg_obj = ctx.FunctionArguments.Single();
                var        arg_val = arg_obj.NativeNat8;

                thisValue.Assign(await ObjectData.CreateInstanceAsync(ctx, thisValue.RunTimeTypeInstance, (Double)arg_val).ConfigureAwait(false));
                return(ExecValue.CreateReturn(null));
            }
            else
            {
                ExecValue?result = await numComparisonAsync <double>(ctx, func, thisValue).ConfigureAwait(false);

                if (result.HasValue)
                {
                    return(result.Value);
                }
                else
                {
                    throw new NotImplementedException($"Function {func} is not implemented");
                }
            }
        }
Ejemplo n.º 8
0
        private async Task <ExecValue> executeNativeChunkFunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData this_value)
        {
            if (func == ctx.Env.ChunkSizeConstructor)
            {
                IEntityInstance elem_type = this_value.RunTimeTypeInstance.TemplateArguments.Single();
                ObjectData      size_obj  = ctx.FunctionArguments.Single();
                var             size      = size_obj.NativeNat64;
                ObjectData[]    chunk     = (await Task.WhenAll(Enumerable.Range(0, (int)size).Select(_ => ObjectData.CreateEmptyAsync(ctx, elem_type))).ConfigureAwait(false)).ToArray();
                this_value.Assign(await createChunk(ctx, this_value.RunTimeTypeInstance, chunk).ConfigureAwait(false));
                return(ExecValue.CreateReturn(null));
            }
            else if (func == ctx.Env.ChunkResizeConstructor)
            {
                IEntityInstance elem_type  = this_value.RunTimeTypeInstance.TemplateArguments.Single();
                ObjectData      size_obj   = ctx.FunctionArguments[0];
                var             size       = size_obj.NativeNat64;
                ObjectData      source_obj = ctx.FunctionArguments[1];
                if (!source_obj.TryDereferenceAnyOnce(ctx.Env, out ObjectData val_obj))
                {
                    throw new Exception($"{ExceptionCode.SourceInfo()}");
                }
                Chunk source = val_obj.PlainValue.Cast <Chunk>();

                ObjectData[] chunk     = new ObjectData[size];
                var          copy_size = Math.Min(size, source.Count);
                for (UInt64 i = 0; i != copy_size; ++i)
                {
                    chunk[i] = source[i];
                    ctx.Heap.TryInc(ctx, source[i], RefCountIncReason.CopyingChunkElem, "");
                }
                for (var i = copy_size; i < size; ++i)
                {
                    chunk[i] = await ObjectData.CreateEmptyAsync(ctx, elem_type).ConfigureAwait(false);
                }
                this_value.Assign(await createChunk(ctx, this_value.RunTimeTypeInstance, chunk).ConfigureAwait(false));
                return(ExecValue.CreateReturn(null));
            }
            else if (func == ctx.Env.ChunkAtSet)
            {
                ObjectData idx_obj = ctx.GetArgument(func, NameFactory.IndexIndexerParameter);
                var        idx     = idx_obj.NativeNat64;
                Chunk      chunk   = this_value.PlainValue.Cast <Chunk>();
                ctx.Heap.TryRelease(ctx, chunk[idx], passingOutObject: null, isPassingOut: false, reason: RefCountDecReason.ReplacingChunkElem, comment: "");
                ObjectData arg_ref_object = ctx.GetArgument(func, NameFactory.PropertySetterValueParameter);
                // indexer takes reference to element
                if (!arg_ref_object.TryDereferenceAnyOnce(ctx.Env, out ObjectData arg_val))
                {
                    throw new Exception($"{ExceptionCode.SourceInfo()}");
                }
                if (!ctx.Heap.TryIncPointer(ctx, arg_val, RefCountIncReason.SettingChunkElem, ""))
                {
                    arg_val = arg_val.Copy();
                }
                chunk[idx] = arg_val;
                return(ExecValue.CreateReturn(null));
            }
            else if (func == ctx.Env.ChunkAtGet)
            {
                ObjectData idx_obj   = ctx.GetArgument(func, NameFactory.IndexIndexerParameter);
                var        idx       = idx_obj.NativeNat64;
                Chunk      chunk     = this_value.PlainValue.Cast <Chunk>();
                ObjectData obj_value = chunk[idx];
                // indexer returns reference to an element value
                ObjectData obj_ref = await obj_value.ReferenceAsync(ctx).ConfigureAwait(false);

                return(ExecValue.CreateReturn(obj_ref));
            }
            else if (func == ctx.Env.ChunkCount)
            {
                Chunk      chunk  = this_value.PlainValue.Cast <Chunk>();
                ObjectData result = await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components,
                                                                         chunk.Count).ConfigureAwait(false);

                return(ExecValue.CreateReturn(result));
            }
            else
            {
                throw new NotImplementedException($"{ExceptionCode.SourceInfo()}");
            }
        }