public override int[] GetRanges(Variable filter) { bool[] cfilter = new bool[values.Length]; var setting = filter.Fetch().mo.setting; // minor hack to make :BoolProp work - converts to True/False if (filter.Fetch().Isa(setting.BoolMO)) filter = filter.Fetch().mo.mro_Str.Get(filter); for (int i = 0; i < values.Length; i++) { foreach (string s in values[i]) { if (DoMatch(s, filter)) { cfilter[i] = true; break; } } } List<int> res = new List<int>(); for (int i = 0; i < data.Length; i += 2) { if (cfilter[data[i+1]]) { int upto = (i+2 == data.Length) ? 0x110000 : data[i+2]; if (res.Count > 0 && res[res.Count-1] == data[i]) { res[res.Count-1] = upto; } else { res.Add(data[i]); res.Add(upto); } } } return res.ToArray(); }
public static Variable cb_finish(Variable si, Variable nam) { StringBuilder sb = new StringBuilder(); List <object> refs = new List <object>(); Downcaller.SerializeNam(nam, sb, refs); object[] args = new object[refs.Count + 3]; args[0] = "sub_finish"; args[1] = Kernel.UnboxAny <object>(si.Fetch()); args[2] = sb.ToString(); refs.CopyTo(args, 3); return(Downcaller.DCResult(si.Fetch().mo.setting, Downcaller.RawDowncall(args))); }
public virtual P6any GetWHO(P6any obj, string key) { Variable r = Get(Kernel.NewROScalar(obj), Kernel.BoxAnyMO(key, Kernel.StrMO)); return(r.Fetch().mo.who); }
protected static bool DoMatch(string value, Variable filter) { var sub = filter.Fetch(); Variable r = Builtins.InvokeMethod("ACCEPTS", filter, sub.mo.setting.MakeStr(value)); return(r.Fetch().mo.mro_raw_Bool.Get(r)); }
public static Variable cb_prune_match(Variable vr) { Cursor c = (Cursor)vr.Fetch(); // remove as much as possible - don't call this if you still need // the match! if (c.feedback != null) { c.feedback.CommitRule(); c.feedback.bt = null; c.feedback.st = new State(); c.feedback.ast = null; } for (CapInfo it = c.captures; it != null; it = it.prev) { if (it.cap != null && it.cap.Fetch() is Cursor) { cb_prune_match(it.cap); } } c.captures = null; c.feedback = null; c.ast = null; c.xact = null; c.nstate = null; return(vr); }
[ImplicitConsts] public static Variable asech(Constants c, Variable a1) { P6any o1 = a1.Fetch(); int r1; if (!o1.mo.is_any) { return(HandleSpecial1(c, a1, o1, asech_d)); } P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); return(c.setting.MakeComplex(v1.Asech())); } { Complex v1 = PromoteToComplex(r1, n1); Complex v2 = v1.Asech(); if (v2.im < -1e-15 || v2.im > 1e-15) { return(c.setting.MakeFloat(double.NaN)); } else { return(c.setting.MakeFloat(v2.re)); } } }
internal static object DCArg(Variable v) { P6any o = v.Fetch(); var s = o.mo.setting; if (o is BoxObject<object>) return Kernel.UnboxAny<object>(o); else if (o.IsDefined()) { if (o.Isa(s.StrMO)) return (string) o.mo.mro_raw_Str.Get(v); else if (o.Isa(s.BoolMO)) return (bool) o.mo.mro_raw_Bool.Get(v); else if (o.Isa(s.NumMO)) { double d = Kernel.UnboxAny<double>(o); if ((d % 1) == 0 && d <= int.MaxValue && d >= int.MinValue) return (object)(int)d; return (object)d; } else if (o.Isa(s.ListMO)) { VarDeque it = o.mo.mro_raw_iterator.Get(v); var lo = new List<object>(); while (Kernel.IterHasFlat(it, true)) lo.Add(DCArg(it.Shift())); return lo.ToArray(); } else return (int) o.mo.mro_raw_Numeric.Get(v); } else return null; }
[ImplicitConsts] public static P6any from_jsync(Constants c, string inp) { JsyncReader j = new JsyncReader() { setting = c.setting }; j.from = inp; j.SkipWhite(true); Variable top = j.GetTopLevel(); foreach (KeyValuePair <string, List <Variable> > da in j.anchorrefs) { P6any r; if (!j.anchors.TryGetValue(da.Key, out r)) { j.Err("Undefined anchor " + da.Key); } foreach (Variable to in da.Value) { to.Store(r); } } j.SkipWhite(false); if (j.ix != inp.Length) { j.Err("Trailing garbage after object"); } return(top.Fetch()); }
public static Variable cotanh(Variable a1) { P6any o1 = a1.Fetch(); int r1; if (!o1.mo.is_any) { return(HandleSpecial1(a1, o1, cotanh_d)); } P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); return(MakeComplex(v1.Cotanh())); } { Complex v1 = PromoteToComplex(r1, n1); Complex v2 = v1.Cotanh(); if (v2.im < -1e-15 || v2.im > 1e-15) { return(MakeFloat(double.NaN)); } else { return(MakeFloat(v2.re)); } } }
protected static bool DoMatch(string value, Variable filter) { Variable r = Kernel.RunInferior(filter.Fetch().InvokeMethod( Kernel.GetInferiorRoot(), "ACCEPTS", new Variable[] { filter, Builtins.MakeStr(value) }, null)); return(r.Fetch().mo.mro_raw_Bool.Get(r)); }
[ImplicitConsts] public static Variable ucd_get_value(Constants c, Variable tbl, Variable ch) { Property p = (Property)DataSet.GetTable( tbl.Fetch().mo.mro_raw_Str.Get(tbl)); return(c.setting.MakeStr(p.GetValue( (int)ch.Fetch().mo.mro_raw_Numeric.Get(ch)))); }
public static Variable ucd_get_value(Variable tbl, Variable ch) { Property p = (Property)DataSet.GetTable( tbl.Fetch().mo.mro_raw_Str.Get(tbl)); return(MakeStr(p.GetValue( (int)ch.Fetch().mo.mro_raw_Numeric.Get(ch)))); }
public override int[] GetRanges(Variable filter) { bool[] cfilter = new bool[values.Length]; var setting = filter.Fetch().mo.setting; // minor hack to make :BoolProp work - converts to True/False if (filter.Fetch().Isa(setting.BoolMO)) { filter = filter.Fetch().mo.mro_Str.Get(filter); } for (int i = 0; i < values.Length; i++) { foreach (string s in values[i]) { if (DoMatch(s, filter)) { cfilter[i] = true; break; } } } List <int> res = new List <int>(); for (int i = 0; i < data.Length; i += 2) { if (cfilter[data[i + 1]]) { int upto = (i + 2 == data.Length) ? 0x110000 : data[i + 2]; if (res.Count > 0 && res[res.Count - 1] == data[i]) { res[res.Count - 1] = upto; } else { res.Add(data[i]); res.Add(upto); } } } return(res.ToArray()); }
public static void AssignV(Variable lhs, IP6 rhs) { if (!lhs.islist) { lhs.Store(rhs); } else { Frame n = lhs.Fetch().InvokeMethod(Kernel.GetInferiorRoot(), "LISTSTORE", new Variable[2] { lhs, Kernel.NewROScalar(rhs) }, null); Kernel.RunInferior(n); } }
public static Variable cb_downcall(Variable list) { List <object> lo = new List <object>(); VarDeque it = Builtins.start_iter(list); while (Kernel.IterHasFlat(it, true)) { lo.Add(Downcaller.DCArg(it.Shift())); } return(Downcaller.DCResult(list.Fetch().mo.setting, Downcaller.RawDowncall(lo.ToArray()))); }
protected Variable Slice(Variable obj, Variable key) { if (key.Fetch().mo.HasType(Kernel.JunctionMO)) { return(Builtins.AutoThread(key.Fetch(), delegate(Variable v) { return Get(obj, v); })); } VarDeque iter = Builtins.start_iter(key); List <Variable> items = new List <Variable>(); while (Kernel.IterHasFlat(iter, true)) { items.Add(Get(obj, iter.Shift())); } // TODO: 1-element slices should be deparceled. Requires // LISTSTORE improvements though. return(Kernel.NewRWListVar(Kernel.BoxRaw <Variable[]>( items.ToArray(), Kernel.ParcelMO))); }
public static Variable ucd_get_ranges(Variable tbl, Variable sm) { Property p = (Property)DataSet.GetTable( tbl.Fetch().mo.mro_raw_Str.Get(tbl)); int[] rranges = p.GetRanges(sm); Variable[] cranges = new Variable[rranges.Length]; for (int i = 0; i < rranges.Length; i++) { cranges[i] = Builtins.MakeInt(rranges[i]); } return(Builtins.MakeParcel(cranges)); }
public static object CompileCClass(Variable pair) { P6any pairo = pair.Fetch(); Variable tbl = (Variable)pairo.GetSlot(Kernel.EnumMO, "$!key"); Variable sm = (Variable)pairo.GetSlot(Kernel.EnumMO, "$!value"); Property p = (Property)DataSet.GetTable( tbl.Fetch().mo.mro_raw_Str.Get(tbl)); int[] rranges = p.GetRanges(sm); object[] cranges = new object[rranges.Length * 2]; for (int i = 0; i < rranges.Length; i++) { cranges[2*i] = rranges[i]; cranges[2*i+1] = ((i & 1) != 0) ? 0 : 0x3FFFFFFF; } return cranges; }
internal static object DCArg(Variable v) { P6any o = v.Fetch(); var s = o.mo.setting; if (o is BoxObject <object> ) { return(Kernel.UnboxAny <object>(o)); } else if (o.IsDefined()) { if (o.Isa(s.StrMO)) { return((string)o.mo.mro_raw_Str.Get(v)); } else if (o.Isa(s.BoolMO)) { return((bool)o.mo.mro_raw_Bool.Get(v)); } else if (o.Isa(s.NumMO)) { double d = Kernel.UnboxAny <double>(o); if ((d % 1) == 0 && d <= int.MaxValue && d >= int.MinValue) { return((object)(int)d); } return((object)d); } else if (o.Isa(s.ListMO)) { VarDeque it = o.mo.mro_raw_iterator.Get(v); var lo = new List <object>(); while (Kernel.IterHasFlat(it, true)) { lo.Add(DCArg(it.Shift())); } return(lo.ToArray()); } else { return((int)o.mo.mro_raw_Numeric.Get(v)); } } else { return(null); } }
// TODO GetTopLevel public static P6any FromJson(string inp) { JsyncReader j = new JsyncReader(); j.from = inp; j.SkipWhite(true); Variable top = j.GetFromJson(true); j.SkipWhite(false); if (j.ix != inp.Length) { j.Err("Trailing garbage after object"); } return(top.Fetch()); }
[ImplicitConsts] public static Variable tan(Constants c, Variable a1) { P6any o1 = a1.Fetch(); int r1; if (!o1.mo.is_any) return HandleSpecial1(c, a1,o1, tan_d); P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); return c.setting.MakeComplex(v1.Tan()); } { double v1 = PromoteToFloat(r1, n1); return c.setting.MakeFloat(Math.Tan(v1)); } }
public static object CompileCClass(Variable pair) { P6any pairo = pair.Fetch(); Variable tbl = (Variable)pairo.GetSlot("key"); Variable sm = (Variable)pairo.GetSlot("value"); Property p = (Property)DataSet.GetTable( tbl.Fetch().mo.mro_raw_Str.Get(tbl)); int[] rranges = p.GetRanges(sm); object[] cranges = new object[rranges.Length * 2]; for (int i = 0; i < rranges.Length; i++) { cranges[2 * i] = rranges[i]; cranges[2 * i + 1] = ((i & 1) != 0) ? 0 : 0x3FFFFFFF; } return(cranges); }
public static Variable acosec(Variable a1) { P6any o1 = a1.Fetch(); int r1; if (!o1.mo.is_any) return HandleSpecial1(a1,o1, acosec_d); P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); return MakeComplex(v1.Acosec()); } { double v1 = PromoteToFloat(r1, n1); return MakeFloat(Math.Asin(1 / v1)); } }
public static IntPtr VariableToSV(Variable var) { P6any obj = var.Fetch(); if (obj is SVany) { return(((SVany)obj).sv); } else if (obj.Does(Compartment.Top.StrMO)) { string s = Kernel.UnboxAny <string>(obj); return(MarshalString(s)); } else { throw new NieczaException("can't convert argument to p5 type"); } }
public bool CheckSubset(P6any obj) { if (!obj.Does(superclasses[0])) { return(false); } if (subsetFilter == null) { subsetFilter = Kernel.RunInferior(subsetWhereThunk.Invoke( Kernel.GetInferiorRoot(), Variable.None, null)); } Variable ret = Kernel.RunInferior(subsetFilter.Fetch(). InvokeMethod(Kernel.GetInferiorRoot(), "ACCEPTS", new Variable[] { subsetFilter, Kernel.NewROScalar(obj) }, null)); return(ret.Fetch().mo.mro_raw_Bool.Get(ret)); }
public static IntPtr VariableToSV(Variable var) { P6any obj = var.Fetch(); if (obj is SVany) { return(((SVany)obj).sv); } else if (obj.Does(Kernel.StrMO)) { string s = Kernel.UnboxAny <string>(obj); return(Perl5Interpreter.newSVpvn(s, s.Length)); } else { throw new NieczaException("can't convert argument to p5 type"); } }
public static Variable cursor_allcaps(Variable cv) { Cursor c = (Cursor) cv.Fetch(); VarDeque dq = new VarDeque(); for (CapInfo it = c.captures; it != null; it = it.prev) { if (it.names[0] == null || it.cap == null) continue; // special node if (!it.cap.Fetch().Isa(Kernel.MatchMO)) continue; foreach (string name in it.names) dq.Unshift(pair(MakeStr(name), it.cap)); } P6opaque lst = new P6opaque(Kernel.ListMO); lst.slots[0 /*items*/] = dq; lst.slots[1 /*rest*/ ] = new VarDeque(); return Kernel.NewRWListVar(lst); }
Variable GetFromString() { if (s_content_type == ALIAS) { return(CreateAlias(s_content)); } if (s_content_type != SCALAR) { Err("Found directive or sequence mark where scalar expected"); } Variable obj = ParseScalar(); if (s_anchor != null) { AddAnchor(s_anchor, obj.Fetch()); } return(obj); }
[ImplicitConsts] public static P6any from_json(Constants c, string inp) { JsyncReader j = new JsyncReader() { setting = c.setting }; j.from = inp; j.SkipWhite(true); Variable top = j.GetFromJson(true); j.SkipWhite(false); if (j.ix != inp.Length) { j.Err("Trailing garbage after object"); } return(top.Fetch()); }
[ImplicitConsts] public static Variable tan(Constants c, Variable a1) { P6any o1 = a1.Fetch(); int r1; if (!o1.mo.is_any) { return(HandleSpecial1(c, a1, o1, tan_d)); } P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); return(c.setting.MakeComplex(v1.Tan())); } { double v1 = PromoteToFloat(r1, n1); return(c.setting.MakeFloat(Math.Tan(v1))); } }
public static Variable acos(Variable a1) { P6any o1 = a1.Fetch(); int r1; if (!o1.mo.is_any) { return(HandleSpecial1(a1, o1, acos_d)); } P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); return(MakeComplex(v1.Acos())); } { double v1 = PromoteToFloat(r1, n1); return(MakeFloat(Math.Acos(v1))); } }
public static Variable acosech(Variable a1) { P6any o1 = a1.Fetch(); int r1; if (!o1.mo.is_any) return HandleSpecial1(a1,o1, acosech_d); P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); return MakeComplex(v1.Acosech()); } { Complex v1 = PromoteToComplex(r1, n1); Complex v2 = v1.Acosech(); if (v2.im < -1e-15 || v2.im > 1e-15) { return MakeFloat(double.NaN); } else { return MakeFloat(v2.re); } } }
static object Callback(P6any fun, Type ret, object[] args, Type[] aty) { Variable[] pos = new Variable[args.Length]; for (int i = 0; i < args.Length; i++) { pos[i] = BoxResult(aty[i], args[i]); } Variable retv = Kernel.RunInferior(fun.Invoke( Kernel.GetInferiorRoot(), pos, null)); if (ret == typeof(void)) { return(null); } object reto; if (!CoerceArgument(out reto, ret, retv)) { throw new Exception("Return value coercion failed, " + retv.Fetch().mo.name + " to " + ret.FullName); } return(reto); }
static int Context(Variable var) { P6any obj = var.Fetch(); string s = Kernel.UnboxAny <string>(obj); if (s == "list") { return(0); } else if (s == "scalar") { return(1); } else if (s == "void") { return(2); } else { throw new NieczaException("unknown p5 context type: " + s); } }
// Better, but still fudgy. Relies too much on path structure. public static void InitSlave(Variable cb, Variable unit, Variable staticSub, Variable type) { if (responder != null) { return; } UnitP = unit.Fetch(); StaticSubP = staticSub.Fetch(); TypeP = type.Fetch(); obj_dir = Path.GetFullPath(Path.Combine( AppDomain.CurrentDomain.BaseDirectory, Path.Combine("..", "obj"))); AppDomain.CurrentDomain.AssemblyResolve += ObjLoader; upcall_cb = cb; responder = (IDictionary)Activator.CreateInstance(Type.GetType( "Niecza.CLRBackend.DowncallReceiver,Run.Kernel", true)); RawDowncall("set_binding", obj_dir, new UpcallReceiver()); }
// Better, but still fudgy. Relies too much on path structure. public static void cb_init_slave(Variable cb, P6any cmd_obj_dir, Variable unit, Variable staticSub, Variable type, Variable param, Variable value) { if (Downcaller.responder != null) { return; } Downcaller.UnitP = unit.Fetch(); Downcaller.StaticSubP = staticSub.Fetch(); Downcaller.TypeP = type.Fetch(); Downcaller.ParamP = param.Fetch(); Downcaller.ValueP = value.Fetch(); string[] obj_dirs = !cmd_obj_dir.IsDefined() ? new string[0] : cmd_obj_dir.Isa(cmd_obj_dir.mo.setting.StrMO) ? new string[] { cmd_obj_dir.mo.mro_raw_Str.Get(cmd_obj_dir) } : Builtins.UnboxLoS(Kernel.NewRWListVar(cmd_obj_dir)); if (obj_dirs.Length == 0) { obj_dirs = new string[2]; obj_dirs[0] = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.Combine("..", "obj")); obj_dirs[1] = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "NieczaModuleCache"); } for (int i = 0; i < obj_dirs.Length; i++) { Directory.CreateDirectory(obj_dirs[i]); // mkdir -p obj_dirs[i] = Path.GetFullPath(obj_dirs[i]); } Downcaller.obj_dirs = obj_dirs; Downcaller.upcall_cb = cb; Downcaller.responder = (IDictionary) new Niecza.CLRBackend.DowncallReceiver(); }
internal static object DCArg(Variable v) { P6any o = v.Fetch(); if (o is BoxObject <object> ) { return(Kernel.UnboxAny <object>(o)); } else if (o.IsDefined()) { if (o.Isa(Kernel.StrMO)) { return((string)o.mo.mro_raw_Str.Get(v)); } else if (o.Isa(Kernel.BoolMO)) { return((bool)o.mo.mro_raw_Bool.Get(v)); } else if (o.Isa(Kernel.ListMO)) { VarDeque it = o.mo.mro_raw_iterator.Get(v); var lo = new List <object>(); while (Kernel.IterHasFlat(it, true)) { lo.Add(DCArg(it.Shift())); } return(lo.ToArray()); } else { return((int)o.mo.mro_raw_Numeric.Get(v)); } } else { return(null); } }
public static Variable cb_cached_but(P6any but, Variable v1, Variable v2) { P6any a1 = v1.Fetch(); P6any a2 = v2.Fetch(); Dictionary <P6any, Variable> subcache; if (!role_cache.TryGetValue(a1, out subcache)) { role_cache[a1] = subcache = new Dictionary <P6any, Variable>(); } Variable var; if (subcache.TryGetValue(a2, out var)) { return(var); } // Mega-Hack - stop lots of internal data from being retained by // CALLER pointers Kernel.SetTopFrame(null); var = Builtins.InvokeSub(but, v1, v2); return(subcache[a2] = var); }
[ImplicitConsts] public static Variable sech(Constants c, Variable a1) { P6any o1 = a1.Fetch(); int r1; if (!o1.mo.is_any) return HandleSpecial1(c, a1,o1, sech_d); P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); return c.setting.MakeComplex(v1.Sech()); } { Complex v1 = PromoteToComplex(r1, n1); Complex v2 = v1.Sech(); if (v2.im < -1e-15 || v2.im > 1e-15) { return c.setting.MakeFloat(double.NaN); } else { return c.setting.MakeFloat(v2.re); } } }
// Coerce a number to a real rational value - note that this loses // the "inexact" annotation carried by Nums public static void GetAsRational(Variable v, out BigInteger num, out BigInteger den) { int rk; P6any n = GetNumber(v, v.Fetch(), out rk); if (rk == NR_COMPLEX || rk == NR_FLOAT) { double dbl = 0; if (rk == NR_COMPLEX) { Complex c = Kernel.UnboxAny<Complex>(n); if (c.im != 0) throw new NieczaException("Complex cannot be used here"); dbl = c.re; } else { dbl = Kernel.UnboxAny<double>(n); } ulong bits = (ulong)BitConverter.DoubleToInt64Bits(dbl); num = (bits & ((1UL << 52) - 1)) + (1UL << 52); den = (1UL << 52); if ((bits & (1UL << 63)) != 0) num = -num; int power = ((int)((bits >> 52) & 0x7FF)) - 0x3FF; if (power > 0) num <<= power; else den <<= -power; SimplifyFrac(ref num, ref den); } else if (rk == NR_FATRAT) { FatRat r = Kernel.UnboxAny<FatRat>(n); num = r.num; den = r.den; } else if (rk == NR_FIXRAT) { Rat r = Kernel.UnboxAny<Rat>(n); num = r.num; den = r.den; } else if (rk == NR_BIGINT) { num = Kernel.UnboxAny<BigInteger>(n); den = BigInteger.One; } else { num = Kernel.UnboxAny<int>(n); den = BigInteger.One; } }
// Coerce a real number to an integer, truncating towards 0 public static bool GetAsInteger(Variable v, out int small, out BigInteger big) { int rk; P6any n = GetNumber(v, v.Fetch(), out rk); small = 0; if (rk == NR_COMPLEX || rk == NR_FLOAT) { double dbl = 0; if (rk == NR_COMPLEX) { Complex c = Kernel.UnboxAny<Complex>(n); if (c.im != 0) throw new NieczaException("Complex cannot be used here"); dbl = c.re; } else { dbl = Kernel.UnboxAny<double>(n); } ulong bits = (ulong)BitConverter.DoubleToInt64Bits(dbl); big = (bits & ((1UL << 52) - 1)) + (1UL << 52); int power = ((int)((bits >> 52) & 0x7FF)) - 0x433; if (power > 0) big <<= power; else big >>= -power; if ((bits & (1UL << 63)) != 0) big = -big; } else if (rk == NR_FATRAT) { FatRat r = Kernel.UnboxAny<FatRat>(n); big = r.num / r.den; } else if (rk == NR_FIXRAT) { Rat r = Kernel.UnboxAny<Rat>(n); big = r.num / r.den; } else if (rk == NR_BIGINT) { big = Kernel.UnboxAny<BigInteger>(n); } else { big = BigInteger.Zero; small = Kernel.UnboxAny<int>(n); return false; } return true; }
public static Variable gcd(Variable a1, Variable a2) { int r1, r2; P6any o1 = a1.Fetch(), o2 = a2.Fetch(); if (!(o1.mo.is_any && o2.mo.is_any)) return HandleSpecial2(a1,a2, o1,o2, gcd_d); P6any n1 = GetNumber(a1, o1, out r1); P6any n2 = GetNumber(a2, o2, out r2); // SHOULD: optimize for the case of two small sized Ints return MakeInt(BigInteger.GreatestCommonDivisor(PromoteToBigInt(r1, n1), PromoteToBigInt(r2, n2))); }
public static Variable cb_finish(Variable si, Variable nam) { StringBuilder sb = new StringBuilder(); List<object> refs = new List<object>(); Downcaller.SerializeNam(nam, sb, refs); object[] args = new object[refs.Count + 3]; args[0] = "sub_finish"; args[1] = Kernel.UnboxAny<object>(si.Fetch()); args[2] = sb.ToString(); refs.CopyTo(args, 3); return Downcaller.DCResult(si.Fetch().mo.setting, Downcaller.RawDowncall(args)); }
internal static void SerializeNam(Variable v, StringBuilder sb, List<object> refs) { P6any o = v.Fetch(); if (o is BoxObject<int>) { /* includes bool */ sb.Append(Kernel.UnboxAny<int>(o)); } else if (o is BoxObject<double>) { sb.Append(Utils.N2S(Kernel.UnboxAny<double>(o))); } else if (o is BoxObject<string>) { string s = Kernel.UnboxAny<string>(o); sb.Append('"'); foreach (char c in s) { if (c >= ' ' && c <= '~' && c != '\\' && c != '"') sb.Append(c); else { sb.Append("\\u"); sb.AppendFormat("{0:X4}", (int)c); } } sb.Append('"'); } else if (!o.IsDefined()) { sb.Append("null"); } else if (o.Isa(o.mo.setting.ListMO)) { VarDeque d = o.mo.mro_raw_iterator.Get(v); bool comma = false; sb.Append('['); while (Kernel.IterHasFlat(d, true)) { if (comma) sb.Append(','); SerializeNam(d.Shift(), sb, refs); comma = true; } sb.Append(']'); } else if (o is BoxObject<object>) { sb.Append('!'); sb.Append(refs.Count); refs.Add(Kernel.UnboxAny<object>(o)); } else { throw new NieczaException("weird object in sub_finish " + o.mo.name); } }
public static Variable exp(Variable a1) { P6any o1 = a1.Fetch(); int r1; if (!o1.mo.is_any) return HandleSpecial1(a1,o1, exp_d); P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); return MakeComplex(Math.Exp(v1.re) * Math.Cos(v1.im), Math.Exp(v1.re) * Math.Sin(v1.im)); } { double v1 = PromoteToFloat(r1, n1); return MakeFloat(Math.Exp(v1)); } }
public static Variable eval_perl5(Variable v) { P6any o1 = v.Fetch(); string r = o1.mo.mro_raw_Str.Get(v); if (p5_interpreter == null) { System.Reflection.Assembly a = System.Reflection.Assembly.Load("Perl5Interpreter"); p5_interpreter = (IForeignInterpreter) a.CreateInstance("Perl5Interpreter"); } return p5_interpreter.Eval(r); }
public static Variable divide(Variable a1, Variable a2) { int r1, r2; P6any o1 = a1.Fetch(), o2 = a2.Fetch(); if (!(o1.mo.is_any && o2.mo.is_any)) return HandleSpecial2(a1,a2, o1,o2, divide_d); P6any n1 = GetNumber(a1, o1, out r1); P6any n2 = GetNumber(a2, o2, out r2); if (r1 == NR_COMPLEX || r2 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); Complex v2 = PromoteToComplex(r2, n2); double sn2 = v2.re*v2.re + v2.im*v2.im; return MakeComplex((v1.re*v2.re + v1.im*v2.im)/sn2, (v2.re*v1.im - v2.im*v1.re)/sn2); } if (r1 == NR_FLOAT || r2 == NR_FLOAT) { return MakeFloat(PromoteToFloat(r1, n1) / PromoteToFloat(r2, n2)); } if (r1 == NR_FATRAT || r2 == NR_FATRAT) { FatRat v1 = PromoteToFatRat(r1, n1); FatRat v2 = PromoteToFatRat(r2, n2); return MakeFatRat(v1.num*v2.den, v1.den*v2.num); } if (r1 == NR_FIXRAT || r2 == NR_FIXRAT) { Rat v1 = PromoteToFixRat(r1, n1); Rat v2 = PromoteToFixRat(r2, n2); return MakeFixRat(v1.num*v2.den, v2.num*v1.den); } if (r1 == NR_BIGINT || r2 == NR_BIGINT) { return MakeFixRat(PromoteToBigInt(r1, n1), PromoteToBigInt(r2, n2)); } return MakeFixRat(PromoteToFixInt(r1, n1), PromoteToFixInt(r2, n2)); }
public static Variable complex_re(Variable a1) { return MakeFloat(Kernel.UnboxAny<Complex>(a1.Fetch()).re); }
// Better, but still fudgy. Relies too much on path structure. public static void cb_init_slave(Variable cb, P6any cmd_obj_dir, Variable unit, Variable staticSub, Variable type, Variable param, Variable value) { if (Downcaller.responder != null) return; Downcaller.UnitP = unit.Fetch(); Downcaller.StaticSubP = staticSub.Fetch(); Downcaller.TypeP = type.Fetch(); Downcaller.ParamP = param.Fetch(); Downcaller.ValueP = value.Fetch(); string[] obj_dirs = !cmd_obj_dir.IsDefined() ? new string[0] : cmd_obj_dir.Isa(cmd_obj_dir.mo.setting.StrMO) ? new string[] { cmd_obj_dir.mo.mro_raw_Str.Get(cmd_obj_dir) } : Builtins.UnboxLoS(Kernel.NewRWListVar(cmd_obj_dir)) ; if (obj_dirs.Length == 0) { obj_dirs = new string[2]; obj_dirs[0] = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.Combine("..", "obj")); obj_dirs[1] = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "NieczaModuleCache"); } for (int i = 0; i < obj_dirs.Length; i++) { Directory.CreateDirectory(obj_dirs[i]); // mkdir -p obj_dirs[i] = Path.GetFullPath(obj_dirs[i]); } Downcaller.obj_dirs = obj_dirs; Downcaller.upcall_cb = cb; Downcaller.responder = (IDictionary) new Niecza.CLRBackend.DowncallReceiver(); }
public static IntPtr VariableToSV(Variable var) { P6any obj = var.Fetch(); if (obj is SVany) { return ((SVany)obj).sv; } else if (obj.Does(Kernel.StrMO)) { string s = Kernel.UnboxAny<string>(obj); return MarshalString(s); } else { throw new NieczaException("can't convert argument to p5 type"); } }
static int Context(Variable var) { P6any obj = var.Fetch(); string s = Kernel.UnboxAny<string>(obj); if (s == "list") { return 0; } else if (s == "scalar") { return 1; } else if (s == "void") { return 2; } else { throw new NieczaException("unknown p5 context type: "+s); } }
public static Variable fatrat_nu(Variable a1) { return MakeInt(Kernel.UnboxAny<FatRat>(a1.Fetch()).num); }
public static Variable cb_downcall(Variable list) { List<object> lo = new List<object>(); VarDeque it = Builtins.start_iter(list); while (Kernel.IterHasFlat(it, true)) lo.Add(Downcaller.DCArg(it.Shift())); return Downcaller.DCResult(list.Fetch().mo.setting, Downcaller.RawDowncall(lo.ToArray())); }
public static Variable floor(Variable a1) { P6any o1 = a1.Fetch(); int r1; if (!o1.mo.is_any) return HandleSpecial1(a1,o1, floor_d); P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_COMPLEX) { throw new NieczaException("floor is only defined for Reals, you have a Complex()"); } if (r1 == NR_FLOAT) { double v1 = PromoteToFloat(r1, n1); if (Double.IsNaN(v1) || Double.IsNegativeInfinity(v1) || Double.IsPositiveInfinity(v1)) { return MakeFloat(v1); } ulong bits = (ulong)BitConverter.DoubleToInt64Bits(v1); BigInteger big = (bits & ((1UL << 52) - 1)) + (1UL << 52); int power = ((int)((bits >> 52) & 0x7FF)) - 0x433; // note: >>= has flooring semantics for signed values if ((bits & (1UL << 63)) != 0) big = -big; if (power > 0) big <<= power; else big >>= -power; return MakeInt(big); } if (r1 == NR_FATRAT) { FatRat v1 = PromoteToFatRat(r1, n1); BigInteger rem; BigInteger red = BigInteger.DivRem(v1.num, v1.den, out rem); if (rem.Sign != 0 && v1.num.Sign < 0) return MakeInt(red - 1); else return MakeInt(red); } if (r1 == NR_FIXRAT) { Rat v1 = PromoteToFixRat(r1, n1); BigInteger rem; BigInteger red = BigInteger.DivRem(v1.num, v1.den, out rem); if (rem.Sign != 0 && v1.num.Sign < 0) return MakeInt(red - 1); else return MakeInt(red); } return Kernel.NewROScalar(n1); }
public static Variable cb_prune_match(Variable vr) { Cursor c = (Cursor)vr.Fetch(); // remove as much as possible - don't call this if you still need // the match! if (c.feedback != null) { c.feedback.CommitRule(); c.feedback.bt = null; c.feedback.st = new State(); c.feedback.ast = null; } for (CapInfo it = c.captures; it != null; it = it.prev) { if (it.cap != null && it.cap.Fetch() is Cursor) cb_prune_match(it.cap); } c.captures = null; c.feedback = null; c.ast = null; c.xact = null; c.nstate = null; return vr; }
// we don't need to do nominal checking stuff here because this // is in a method, never inlined, and as such the binder had to // already have been called. public static Variable complex_new(Variable a1, Variable a2) { double d1 = a1.Fetch().mo.mro_raw_Numeric.Get(a1); double d2 = a2.Fetch().mo.mro_raw_Numeric.Get(a2); return MakeComplex(d1,d2); }
public static Variable cb_cached_but(P6any but, Variable v1, Variable v2) { P6any a1 = v1.Fetch(); P6any a2 = v2.Fetch(); Dictionary<P6any,Variable> subcache; if (!role_cache.TryGetValue(a1, out subcache)) role_cache[a1] = subcache = new Dictionary<P6any,Variable>(); Variable var; if (subcache.TryGetValue(a2, out var)) return var; // Mega-Hack - stop lots of internal data from being retained by // CALLER pointers Kernel.SetTopFrame(null); var = Builtins.InvokeSub(but, v1, v2); return subcache[a2] = var; }
// this is only called from .Int public static Variable coerce_to_int(Variable a1) { int r1; P6any o1 = a1.Fetch(); P6any n1 = GetNumber(a1, o1, out r1); if (r1 == NR_FLOAT) { double v1 = PromoteToFloat(r1, n1); if (Double.IsNaN(v1) || Double.IsNegativeInfinity(v1) || Double.IsPositiveInfinity(v1)) { return MakeFloat(v1); } } int small; BigInteger big; return GetAsInteger(a1, out small, out big) ? MakeInt(big) : MakeInt(small); }
private static string RenderFormat(PrintfFormat format, Variable arg) { int n; if (format.directive == PrintfDirective.String) { return arg.Fetch().mo.mro_raw_Str.Get(arg); } if (format.directive == PrintfDirective.CodePoint) { n = (int) arg.Fetch().mo.mro_raw_Numeric.Get(arg); return "" + (char) n; } bool add_minus_sign = false; if (format.directive == PrintfDirective.Int) { P6any o1 = arg.Fetch(); int r1; P6any n1 = GetNumber(arg, o1, out r1); Variable arg2; if (r1 != NR_BIGINT && r1 != NR_FIXINT) { arg2 = Builtins.InvokeMethod("Int", arg); o1 = arg2.Fetch(); n1 = GetNumber(arg2, o1, out r1); } BigInteger value = PromoteToBigInt(r1, n1); if (value < 0) { add_minus_sign = true; value = -value; } String number; if (format.radix == 16) { number = RemoveInitialZero(value.ToString(format.radix, null)).ToLower(); } else { number = value.ToString(format.radix, null); } if (format.upper) { number = number.ToUpper(); } if (add_minus_sign) { if (format.rightJustifyZeroes) { return "-" + number.PadLeft(format.minimumWidth - 1, '0'); } else { return "-" + number; } } return number; } else { double f = arg.Fetch().mo.mro_raw_Numeric.Get(arg); if (f < 0.0) { add_minus_sign = true; f = -f; } int precision = format.precision > 0 ? format.precision : 6; String number = "??"; switch (format.directive) { case PrintfDirective.FloatFixedDecimal: number = f.ToString("F" + precision); break; case PrintfDirective.FloatScientific: number = f.ToString("e" + precision); break; case PrintfDirective.FloatEF: number = f.ToString("g" + precision); break; } if (format.upper) { number = number.ToUpper(); } if (add_minus_sign) { if (format.rightJustifyZeroes) { return "-" + number.PadLeft(format.minimumWidth - 1, '0'); } else { return "-" + number; } } return number; } }
// called from .Num public static Variable coerce_to_num(Variable a1) { int r1; P6any n1 = GetNumber(a1, a1.Fetch(), out r1); if (r1 == NR_COMPLEX) { Complex v1 = PromoteToComplex(r1, n1); if (v1.im != 0) throw new NieczaException("Complex cannot be used here"); return MakeFloat(v1.re); } else { return MakeFloat(PromoteToFloat(r1, n1)); } }