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)); }
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()}"); } }
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()}"); } }
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()}"); } }
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"); } }
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"); } } }
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"); } } }
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()}"); } }