コード例 #1
0
        private static async Task <ExecValue> executeNativeIObjectFunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData this_value)
        {
            if (func == ctx.Env.IObjectGetTypeFunction)
            {
                // todo: add some real TypeInfo object, for now it is empty so we can return whatever is unique
                ObjectData fake = await ctx.TypeRegistry.RegisterGetAsync(ctx, this_value.RunTimeTypeInstance).ConfigureAwait(false);

                fake = await fake.ReferenceAsync(ctx).ConfigureAwait(false);

                return(ExecValue.CreateReturn(fake));
            }
            else
            {
                throw new NotImplementedException($"{ExceptionCode.SourceInfo()}");
            }
        }
コード例 #2
0
        private async Task <ExecValue> executeNativeUtf8StringFunctionAsync(ExecutionContext ctx, FunctionDefinition func,
                                                                            ObjectData thisValue)
        {
            string this_native = thisValue.NativeString;

            if (func == ctx.Env.Utf8StringCopyConstructor)
            {
                ObjectData arg_str_obj = ctx.FunctionArguments[0];
                if (!arg_str_obj.TryDereferenceAnyOnce(ctx.Env, out ObjectData arg_str_val))
                {
                    throw new Exception($"{ExceptionCode.SourceInfo()}");
                }
                string native_str_arg = arg_str_val.NativeString;

                return(await assignedNativeString(ctx, thisValue, native_str_arg).ConfigureAwait(false));
            }
            else if (func == ctx.Env.Utf8StringRemove)
            {
                ObjectData arg_start_obj    = ctx.FunctionArguments[0];
                int        native_start_arg = (int)arg_start_obj.NativeNat;
                ObjectData arg_end_obj      = ctx.FunctionArguments[1];
                int        native_end_arg   = (int)arg_end_obj.NativeNat;
                int        native_len_arg   = native_end_arg - native_start_arg;

                byte[] this_utf8 = Encoding.UTF8.GetBytes(this_native);
                string rest      = Encoding.UTF8.GetString(this_utf8, 0, native_start_arg)
                                   + Encoding.UTF8.GetString(this_utf8, native_start_arg + native_len_arg, this_utf8.Length - (native_start_arg + native_len_arg));

                return(await assignedNativeString(ctx, thisValue, rest).ConfigureAwait(false));
            }
            else if (func == ctx.Env.Utf8StringCountGetter)
            {
                int[]      code_points = toCodePoints(this_native);
                ObjectData result      = await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components,
                                                                              (UInt64)code_points.Length).ConfigureAwait(false);

                return(ExecValue.CreateReturn(result));
            }
            else if (func == ctx.Env.Utf8StringLengthGetter)
            {
                int        length = Encoding.UTF8.GetByteCount(this_native);
                ObjectData result = await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components,
                                                                         (UInt64)length).ConfigureAwait(false);

                return(ExecValue.CreateReturn(result));
            }
            else if (func == ctx.Env.Utf8StringTrimStart)
            {
                string trimmed = this_native.TrimStart();
                return(await assignedNativeString(ctx, thisValue, trimmed).ConfigureAwait(false));
            }
            else if (func == ctx.Env.Utf8StringReverse)
            {
                // https://en.wikipedia.org/wiki/Combining_character
                string reversed = reverseGraphemeClusters(this_native);
                return(await assignedNativeString(ctx, thisValue, reversed).ConfigureAwait(false));
            }
            else if (func == ctx.Env.Utf8StringTrimEnd)
            {
                string trimmed = this_native.TrimEnd();
                return(await assignedNativeString(ctx, thisValue, trimmed).ConfigureAwait(false));
            }
            else if (func == ctx.Env.Utf8StringAtGetter)
            {
                ObjectData arg_idx_obj    = ctx.FunctionArguments[0];
                int        native_idx_arg = (int)arg_idx_obj.NativeNat;

                byte[] this_utf8 = Encoding.UTF8.GetBytes(this_native);
                string sub       = Encoding.UTF8.GetString(this_utf8, native_idx_arg, this_utf8.Length - native_idx_arg);

                ObjectData obj_ch = await createCharAsync(ctx, sub[0]).ConfigureAwait(false);

                // indexer returns reference to an element value
                ObjectData obj_ref = await obj_ch.ReferenceAsync(ctx).ConfigureAwait(false);

                return(ExecValue.CreateReturn(obj_ref));
            }
            else if (func == ctx.Env.Utf8StringSlice)
            {
                ObjectData arg_start_obj    = ctx.FunctionArguments[0];
                int        native_start_arg = (int)arg_start_obj.NativeNat;
                ObjectData arg_end_obj      = ctx.FunctionArguments[1];
                int        native_end_arg   = (int)arg_end_obj.NativeNat;
                int        native_len_arg   = native_end_arg - native_start_arg;

                byte[] this_utf8 = Encoding.UTF8.GetBytes(this_native);
                string sub       = Encoding.UTF8.GetString(this_utf8, native_start_arg, native_len_arg);

                ObjectData result = await createStringAsync(ctx, sub).ConfigureAwait(false);

                if (!ctx.Heap.TryInc(ctx, result, RefCountIncReason.NewString, sub))
                {
                    throw new Exception($"{ExceptionCode.SourceInfo()}");
                }
                return(ExecValue.CreateReturn(result));
            }
            else if (func == ctx.Env.Utf8StringConcat)
            {
                ObjectData arg_str_obj = ctx.FunctionArguments[0];
                if (!arg_str_obj.TryDereferenceAnyOnce(ctx.Env, out ObjectData arg_str_val))
                {
                    throw new Exception($"{ExceptionCode.SourceInfo()}");
                }
                string native_str_arg = arg_str_val.NativeString;

                string concatenated = this_native + native_str_arg;
                return(await assignedNativeString(ctx, thisValue, concatenated).ConfigureAwait(false));
            }
            else if (func == ctx.Env.Utf8StringIndexOfString)
            {
                ObjectData arg_str_obj = ctx.FunctionArguments[0];
                if (!arg_str_obj.TryDereferenceAnyOnce(ctx.Env, out ObjectData arg_str_val))
                {
                    throw new Exception($"{ExceptionCode.SourceInfo()}");
                }
                string     native_str_arg = arg_str_val.NativeString;
                ObjectData arg_idx_obj    = ctx.FunctionArguments[1];
                int        native_idx_arg = (int)arg_idx_obj.NativeNat;

                byte[] this_utf8 = Encoding.UTF8.GetBytes(this_native);
                string sub       = Encoding.UTF8.GetString(this_utf8, native_idx_arg, this_utf8.Length - native_idx_arg);

                int idx = sub.IndexOf(native_str_arg);

                Option <ObjectData> index_obj;
                if (idx != -1)
                {
                    idx       = native_idx_arg + Encoding.UTF8.GetByteCount(sub.Substring(0, idx));
                    index_obj = new Option <ObjectData>(await ObjectData.CreateInstanceAsync(ctx, ctx.Env.SizeType.InstanceOf, (UInt64)idx)
                                                        .ConfigureAwait(false));
                }
                else
                {
                    index_obj = new Option <ObjectData>();
                }

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

                if (opt_exec.IsThrow)
                {
                    return(opt_exec);
                }

                return(ExecValue.CreateReturn(opt_exec.ExprValue));
            }
            else if (func == ctx.Env.Utf8StringLastIndexOfChar)
            {
                ObjectData arg_char_obj    = ctx.FunctionArguments[0];
                char       native_char_arg = arg_char_obj.NativeChar;
                ObjectData arg_idx_obj     = ctx.FunctionArguments[1];
                int        native_idx_arg  = (int)arg_idx_obj.NativeNat;

                byte[] this_utf8 = Encoding.UTF8.GetBytes(this_native);
                string sub       = Encoding.UTF8.GetString(this_utf8, 0, native_idx_arg);

                int idx = sub.LastIndexOf(native_char_arg);

                Option <ObjectData> index_obj;
                if (idx != -1)
                {
                    idx       = Encoding.UTF8.GetByteCount(this_native.Substring(0, idx));
                    index_obj = new Option <ObjectData>(await ObjectData.CreateInstanceAsync(ctx, ctx.Env.SizeType.InstanceOf, (UInt64)idx)
                                                        .ConfigureAwait(false));
                }
                else
                {
                    index_obj = new Option <ObjectData>();
                }

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

                if (opt_exec.IsThrow)
                {
                    return(opt_exec);
                }

                return(ExecValue.CreateReturn(opt_exec.ExprValue));
            }
            else
            {
                ExecValue?result = await equalityTestAsync <string>(ctx, func, thisValue, heapArguments : true).ConfigureAwait(false);

                if (result.HasValue)
                {
                    return(result.Value);
                }
                else
                {
                    throw new NotImplementedException($"Function {func} is not implemented");
                }
            }
        }
コード例 #3
0
ファイル: Interpreter.Chunk.cs プロジェクト: macias/Skila
        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()}");
            }
        }