internal ObjectData TryDereferenceAnyMany(Language.Environment env) { ObjectData self = this; while (env.IsPointerLikeOfType(self.RunTimeTypeInstance)) { self = self.DereferencedOnce(); } return(self); }
public ObjectData Dereferenced(int count) { ObjectData self = this; for (int i = 0; i < count; ++i) { self = self.DereferencedOnce(); } return(self); }
internal ObjectData TryDereferenceAnyMany(Language.Environment env, int count) { ObjectData self = this; for (int i = 0; i < count; ++i) { if (!env.IsPointerLikeOfType(self.RunTimeTypeInstance)) { break; } else { self = self.DereferencedOnce(); } } return(self); }
private static async Task <ExecValue?> equalityTestAsync <T>(ExecutionContext ctx, FunctionDefinition func, ObjectData thisValue, bool heapArguments) where T : IComparable { var this_native = thisValue.PlainValue.Cast <T>(); if (func.Name.Name == NameFactory.EqualOperator) { ObjectData arg = ctx.FunctionArguments.Single(); if (heapArguments) { arg = arg.DereferencedOnce(); } var arg_native = arg.PlainValue.Cast <T>(); bool cmp = this_native.Equals(arg_native); ExecValue result = ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components, cmp).ConfigureAwait(false)); return(result); } else if (func.Name.Name == NameFactory.NotEqualOperator) { ObjectData arg = ctx.FunctionArguments.Single(); if (heapArguments) { arg = arg.DereferencedOnce(); } var arg_native = arg.PlainValue.Cast <T>(); bool cmp = !this_native.Equals(arg_native); ExecValue result = ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components, cmp).ConfigureAwait(false)); return(result); } return(null); }
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> executeNativeRegexFunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData thisValue) { if (func == ctx.Env.RegexContainsFunction) { ObjectData arg = ctx.FunctionArguments.Single(); ObjectData arg_val = arg.DereferencedOnce(); string arg_str = arg_val.NativeString; ObjectData pattern_obj = thisValue.GetField(ctx.Env.RegexPatternField); ObjectData pattern_val = pattern_obj.DereferencedOnce(); string pattern = pattern_val.NativeString; bool val = new System.Text.RegularExpressions.Regex(pattern).IsMatch(arg_str); ExecValue result = ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components, val).ConfigureAwait(false)); return(result); } else if (func == ctx.Env.RegexMatchFunction) { ObjectData arg = ctx.FunctionArguments.Single(); ObjectData arg_val = arg.DereferencedOnce(); string arg_str = arg_val.NativeString; ObjectData pattern_obj = thisValue.GetField(ctx.Env.RegexPatternField); ObjectData pattern_val = pattern_obj.DereferencedOnce(); string pattern = pattern_val.NativeString; System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(pattern); System.Text.RegularExpressions.MatchCollection matches = regex.Matches(arg_str); var elements = new List <ObjectData>(); for (int match_idx = 0; match_idx < matches.Count; ++match_idx) { System.Text.RegularExpressions.Match match = matches[match_idx]; ObjectData match_start_val = await createNat64Async(ctx, (UInt64)match.Index).ConfigureAwait(false); ObjectData match_end_val = await createNat64Async(ctx, (UInt64)(match.Index + match.Length)).ConfigureAwait(false); ObjectData array_captures_ptr; { if (!ctx.Env.DereferencedOnce(ctx.Env.MatchCapturesProperty.TypeName.Evaluation.Components, out IEntityInstance array_captures_type, out bool dummy)) { throw new Exception($"Internal error {ExceptionCode.SourceInfo()}"); } ExecValue ret = await createObject(ctx, true, array_captures_type, ctx.Env.ArrayDefaultConstructor, null) .ConfigureAwait(false); if (ret.IsThrow) { return(ret); } array_captures_ptr = ret.ExprValue; ctx.Heap.TryInc(ctx, array_captures_ptr, RefCountIncReason.StoringLocalPointer, ""); // skipping implicit "everything" group for (int grp_idx = 1; grp_idx < match.Groups.Count; ++grp_idx) { System.Text.RegularExpressions.Group group = match.Groups[grp_idx]; string group_name = regex.GroupNameFromNumber(grp_idx); if (group_name == $"{grp_idx}") // hack for anonymous captures { group_name = null; } for (int cap_idx = 0; cap_idx < group.Captures.Count; ++cap_idx) { System.Text.RegularExpressions.Capture cap = group.Captures[cap_idx]; ObjectData cap_start_val = await createNat64Async(ctx, (UInt64)cap.Index).ConfigureAwait(false); ObjectData cap_end_val = await createNat64Async(ctx, (UInt64)(cap.Index + cap.Length)).ConfigureAwait(false); ObjectData cap_opt_name_val; { Option <ObjectData> opt_group_name_obj; if (group_name != null) { ObjectData str_ptr = await createStringAsync(ctx, group_name).ConfigureAwait(false); opt_group_name_obj = new Option <ObjectData>(str_ptr); } else { opt_group_name_obj = new Option <ObjectData>(); } IEntityInstance opt_cap_type = ctx.Env.CaptureConstructor.Parameters.Last().TypeName.Evaluation.Components; ExecValue opt_exec = await createOption(ctx, opt_cap_type, opt_group_name_obj).ConfigureAwait(false); if (opt_exec.IsThrow) { return(opt_exec); } cap_opt_name_val = opt_exec.ExprValue; } ExecValue capture_obj_exec = await createObject(ctx, false, ctx.Env.CaptureType.InstanceOf, ctx.Env.CaptureConstructor, null, cap_start_val, cap_end_val, cap_opt_name_val).ConfigureAwait(false); if (capture_obj_exec.IsThrow) { return(capture_obj_exec); } ObjectData capture_ref = await capture_obj_exec.ExprValue.ReferenceAsync(ctx).ConfigureAwait(false); ExecValue append_exec = await callNonVariadicFunctionDirectly(ctx, ctx.Env.ArrayAppendFunction, null, array_captures_ptr, capture_ref).ConfigureAwait(false); if (append_exec.IsThrow) { return(append_exec); } } } } ObjectData match_val; { ExecValue ret = await createObject(ctx, false, ctx.Env.MatchType.InstanceOf, ctx.Env.MatchConstructor, null, match_start_val, match_end_val, array_captures_ptr).ConfigureAwait(false); ctx.Heap.TryRelease(ctx, array_captures_ptr, null, false, RefCountDecReason.DroppingLocalPointer, ""); if (ret.IsThrow) { return(ret); } match_val = ret.ExprValue; } elements.Add(match_val); } ObjectData heap_chunk = await createChunkOnHeap(ctx, ctx.Env.MatchType.InstanceOf, elements).ConfigureAwait(false); ExecValue result = ExecValue.CreateReturn(heap_chunk); return(result); } else { throw new NotImplementedException($"{ExceptionCode.SourceInfo()}"); } }