Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Move to old-code

svn path=/old-code/; revision=156208
  • Loading branch information...
commit 48a8a8949dea56bcd51bdb8406a40073d424f002 1 parent 7c88762
@migueldeicaza migueldeicaza authored
Showing with 35,442 additions and 0 deletions.
  1. +774 −0 rubynet/Array.cs
  2. +813 −0 rubynet/Bignum.cs
  3. +7 −0 rubynet/ChangeLog
  4. +1,413 −0 rubynet/Class.cs
  5. +242 −0 rubynet/Const.cs
  6. +86 −0 rubynet/Enum.cs
  7. +370 −0 rubynet/Exception.cs
  8. +417 −0 rubynet/Hash.cs
  9. +70 −0 rubynet/IO.cs
  10. +882 −0 rubynet/Kernel.cs
  11. +25 −0 rubynet/LICENSE.txt
  12. +302 −0 rubynet/Loader.cs
  13. +54 −0 rubynet/Makefile
  14. +4,208 −0 rubynet/NETRuby.cs
  15. +1,226 −0 rubynet/Numeric.cs
  16. +928 −0 rubynet/Object.cs
  17. +178 −0 rubynet/Proc.cs
  18. +646 −0 rubynet/Regexp.cs
  19. +2,158 −0 rubynet/Scanner.cs
  20. +650 −0 rubynet/String.cs
  21. +94 −0 rubynet/Symbol.cs
  22. +1,517 −0 rubynet/Thread.cs
  23. +262 −0 rubynet/Time.cs
  24. +1,196 −0 rubynet/codegen.cs
  25. +49 −0 rubynet/example.rb
  26. +9 −0 rubynet/main.cs
  27. +4,107 −0 rubynet/node.cs
  28. +2,196 −0 rubynet/node_print.cs
  29. +7,309 −0 rubynet/parse.cs
  30. +2,485 −0 rubynet/parse.y
  31. +353 −0 rubynet/skeleton.cs
  32. +335 −0 rubynet/tags.rb
  33. +81 −0 rubynet/tests.rb
View
774 rubynet/Array.cs
@@ -0,0 +1,774 @@
+/*
+Copyright (C) 2001-2002 arton
+Copyright (C) 2005 Jaen Saul
+*/
+
+using System;
+using System.Text;
+using System.Globalization;
+using System.Collections;
+using System.Reflection;
+using System.Security;
+
+namespace NETRuby
+{
+ public class RArray : RBasic, ICloneable, IList, IEnumerable
+ {
+ public RArray(NetRuby rb, ArrayList a) :
+ base(rb, rb.cArray)
+ {
+ ptr = a;
+ }
+ public RArray(NetRuby rb, ArrayList a, bool clone) :
+ base(rb, rb.cArray)
+ {
+ if (clone)
+ {
+ // but it creates only a shallow copy.
+ ptr = (ArrayList)a.Clone();
+ }
+ else
+ {
+ ptr = a;
+ }
+ }
+ public RArray(NetRuby rb, ICollection col) :
+ base(rb, rb.cArray)
+ {
+ ptr = new ArrayList(col);
+ }
+ public RArray(NetRuby rb, bool newobj) :
+ base(rb, rb.cArray)
+ {
+ ptr = (newobj) ? new ArrayList() : null;
+ }
+ public RArray(NetRuby rb, bool newobj, RMetaObject spr) :
+ base(rb, spr)
+ {
+ ptr = (newobj) ? new ArrayList() : null;
+ }
+ public RArray(NetRuby rb, int capa) :
+ base(rb, rb.cArray)
+ {
+ ptr = new ArrayList(capa);
+ }
+
+ public ArrayList ArrayList
+ {
+ get { return ptr; }
+ }
+
+ public bool IsFixedSize
+ {
+ get { return false; }
+ }
+ public bool IsReadOnly
+ {
+ get { return IsFrozen; }
+ }
+
+ public override RArray ToArray()
+ {
+ return this;
+ }
+
+ public object[] Array
+ {
+ get { return ptr.ToArray(); }
+ }
+
+ public object Clone()
+ {
+ RArray ra = new RArray(ruby, (ArrayList)ptr.Clone());
+ if (Test(FL.TAINT)) ra.Set(FL.TAINT);
+ return ra;
+ }
+
+ public override string ToString()
+ {
+ if (ptr == null || ptr.Count <= 0) return String.Empty;
+ return Join(ruby.outputFS).ToString();
+ }
+
+ public override RString ToRString()
+ {
+ if (ptr.Count <= 0) return new RString(ruby, String.Empty, false);
+ return Join(ruby.outputFS);
+ }
+
+ public override object Inspect()
+ {
+ if (ptr.Count == 0) return "[]";
+ if (ruby.IsInspecting(this)) return "[...]";
+ return ruby.ProtectInspect(this,
+ new InspectMethod(inspect_ary),
+ new object[2] {this, 0});
+ }
+
+ public void Clear()
+ {
+ ptr.Clear();
+ }
+ public RArray Clear2()
+ {
+ ptr.Clear();
+ return this;
+ }
+
+ static public RArray AssocNew(NetRuby ruby, RBasic car, RBasic cdr)
+ {
+ ArrayList ar = new ArrayList();
+ ar.Add(car);
+ ar.Add(cdr);
+ return new RArray(ruby, ar);
+ }
+ static public RArray AssocNew(NetRuby ruby, object car, object cdr)
+ {
+ ArrayList ar = new ArrayList();
+ ar.Add(car);
+ ar.Add(cdr);
+ return new RArray(ruby, ar);
+ }
+
+ public RArray Fill(object[] argv)
+ {
+ object[] args = new object[3];
+ ruby.ScanArgs(argv, "12", args);
+ int beg = 0;
+ int len = ptr.Count;
+ switch (argv.Length)
+ {
+ case 1:
+ break;
+ case 2:
+ //range
+ goto case 3;
+ case 3:
+ beg = (args[1] == null) ? 0 : (int)args[1];
+ if (beg < 0)
+ {
+ beg = ptr.Count + beg;
+ if (beg < 0) beg = 0;
+ }
+ len = (args[2] == null) ? ptr.Count - beg : (int)args[2];
+ break;
+ }
+ CheckModify();
+ int end = beg + len;
+ if (end > ptr.Count)
+ {
+ ptr.AddRange(new object[end - ptr.Count]);
+ }
+ for (int i = beg; i < len; i++)
+ {
+ ptr[i] = args[0];
+ }
+ return this;
+ }
+
+ public bool Contains(object o)
+ {
+ return ptr.Contains(o);
+ }
+
+ public RArray ToRArrayWith(object x)
+ {
+ if (x is ArrayList)
+ return new RArray(ruby, (ArrayList)x);
+ return (RArray)ruby.ConvertType(x, typeof(RArray), "Array", "to_ary");
+ }
+
+ public RArray Concat(object o)
+ {
+ RArray ary = ToRArrayWith(o);
+ ptr.AddRange(ary.ptr);
+ return this;
+ }
+
+ public RString JoinMethod(object[] argv)
+ {
+ object[] args = new object[1];
+ ruby.ScanArgs(argv, "01", args);
+ return Join((args[0] == null) ? ruby.outputFS : args[0]);
+ }
+
+ public RString Join(object sep)
+ {
+ if (ptr.Count <= 0) return new RString(ruby, String.Empty, false);
+ bool taint = IsTainted;
+ if (sep is RBasic && ((RBasic)sep).IsTainted)
+ {
+ taint = true;
+ }
+ string ssep = String.Empty;
+ if (sep != null)
+ {
+ if (sep is string || sep is RString)
+ {
+ ssep = sep.ToString();
+ }
+ else
+ {
+ ssep = RString.StringToRString(ruby, sep).ToString();
+ }
+ }
+ string result = String.Empty;
+ string tmp;
+ for (int i = 0; i < ptr.Count; i++)
+ {
+ object o = ptr[i];
+ if (o is RBasic && ((RBasic)o).IsTainted) taint = true;
+
+ if (o is string || o is RString)
+ {
+ tmp = o.ToString();
+ }
+ else if (o is RArray)
+ {
+ if (ruby.IsInspecting(o))
+ {
+ tmp = "[...]";
+ }
+ else
+ {
+ tmp = ruby.ProtectInspect(this,
+ new InspectMethod(inspect_join),
+ new object[2] {o, sep}).ToString();
+ }
+ }
+ else
+ {
+ tmp = RString.AsString(ruby, o);
+ }
+ if (i > 0)
+ {
+ result += ssep;
+ }
+ result += tmp;
+ }
+ return new RString(ruby, result, taint);
+ }
+
+ public RArray Reverse()
+ {
+ RArray ary = (RArray)Clone();
+ return ary.ReverseAt();
+ }
+ public RArray ReverseAt()
+ {
+ CheckModify();
+ ptr.Reverse();
+ return this;
+ }
+ public RArray Sort()
+ {
+ RArray ary = (RArray)Clone();
+ return ary.SortAt();
+ }
+ public RArray SortAt()
+ {
+ CheckModify();
+ ptr.Sort();
+ return this;
+ }
+ public RArray Collect()
+ {
+ if (ruby.IsBlockGiven == false)
+ return (RArray)Clone();
+ RArray collect = new RArray(ruby, ptr.Count);
+ lock (ptr.SyncRoot)
+ {
+ foreach (object o in ptr)
+ {
+ collect.Add(ruby.Yield(o));
+ }
+ }
+ return collect;
+ }
+ public RArray CollectAt()
+ {
+ CheckModify();
+ lock (ptr.SyncRoot)
+ {
+ for (int i = 0; i < ptr.Count; i++)
+ {
+ ptr[i] = ruby.Yield(ptr[i]);
+ }
+ }
+ return this;
+ }
+ private object inspect_ary(RBasic ary, object[] args)
+ {
+ bool taint = false;
+ StringBuilder result = new StringBuilder("[");
+ for (int i = 0; i < ptr.Count; i++)
+ {
+ object o = ruby.Inspect(ptr[i]);
+ if (o is RBasic && ((RBasic)o).IsTainted) taint = true;
+ if (i > 0)
+ result.AppendFormat(", {0}", (o == null) ? "nil" : o.ToString());
+ else
+ result.Append(o.ToString());
+ }
+ result.Append("]");
+ if (IsTainted || taint)
+ return new RString(ruby, result.ToString(), true);
+ else
+ return result.ToString();
+ }
+ private object inspect_join(RBasic ary, object[] args)
+ {
+ RString rs = ((RArray)args[0]).Join(args[1]);
+ return rs;
+ }
+
+ public RArray Initialize(object[] argv)
+ {
+ object[] args = new object[2];
+ if (ruby.ScanArgs(argv, "02", args) == 0)
+ {
+ ptr = new ArrayList();
+ return this;
+ }
+ CheckModify();
+ int len = (int)args[0];
+ if (len < 0)
+ {
+ throw new ArgumentException("negative array size");
+ }
+ if (len > ptr.Capacity)
+ {
+ ptr = ArrayList.Repeat(args[1], len);
+ }
+ return this;
+ }
+
+ private void CheckModify()
+ {
+ if (IsFrozen) ruby.ErrorFrozen("array");
+/*
+ // Sort is done by .NET Framework
+ if (IsTainted == false && ruby.SafeLevel >= 4)
+ throw new SecurityException("Insecure: can't modify array");
+*/
+ }
+
+ internal static object s_new(RBasic r, params object[] args)
+ {
+ NetRuby rb = r.ruby;
+ RArray a = new RArray(rb, false, (RMetaObject)r);
+ rb.CallInit(a, args);
+ if (a.ptr == null) a.ptr = new ArrayList();
+ return a;
+ }
+
+ internal static RArray Create(NetRuby rb, object[] args)
+ {
+ RArray a = new RArray(rb, args);
+ return a;
+ }
+
+ public object this[int index]
+ {
+ get {
+ if (ptr.Count == 0) return null;
+ if (index < 0)
+ {
+ index += ptr.Count;
+ }
+ if (index < 0 || ptr.Count <= index)
+ {
+ return null;
+ }
+ return ptr[index];
+ }
+ set {
+ if (index >= ptr.Count)
+ {
+ ptr.Insert(index, value);
+ }
+ else
+ {
+ ptr[index] = value;
+ }
+ }
+ }
+ public object First
+ {
+ get { return (ptr.Count == 0) ? null : ptr[0]; }
+ }
+ public object Last
+ {
+ get { return (ptr.Count == 0) ? null : ptr[ptr.Count - 1]; }
+ }
+ internal object ARef(object[] argv)
+ {
+ int beg, len;
+ object[] args = new object[2];
+ if (ruby.ScanArgs(argv, "11", args) == 2)
+ {
+ beg = RInteger.ToInt(ruby, args[0]);
+ len = RInteger.ToInt(ruby, args[1]);
+ if (beg < 0)
+ beg += ptr.Count;
+ return Subseq(beg, len);
+ }
+ int offset;
+ if (args[0] is int)
+ offset = (int)args[0];
+ else if (args[0] is RBignum)
+ throw new eIndexError("index too big");
+ else
+ // Range object check
+ offset = RInteger.ToInt(ruby, args[0]);
+ if (offset < 0)
+ offset = ptr.Count + offset;
+ if (offset < 0 || ptr.Count <= offset)
+ return null;
+ return ptr[offset];
+ }
+ internal object Subseq(int beg, int len)
+ {
+ if (beg > ptr.Count) return null;
+ if (beg < 0 || len < 0) return null;
+ if (beg + len > ptr.Count)
+ {
+ len = ptr.Count - beg;
+ }
+ if (len < 0) len = 0;
+ if (len == 0) return new RArray(ruby, true);
+ RArray ary2 = new RArray(ruby, ptr.GetRange(beg, len));
+ ary2.klass = Class;
+ return ary2;
+ }
+ internal void Replace(int beg, int len, object rpl)
+ {
+ if (len < 0) throw new ArgumentOutOfRangeException("negative length " + len.ToString());
+ if (beg < 0)
+ beg += ptr.Count;
+ if (beg < 0)
+ {
+ beg -= ptr.Count;
+ throw new ArgumentOutOfRangeException("index " + beg.ToString() + " out of array");
+ }
+ if (beg + len > ptr.Count)
+ {
+ len = ptr.Count - beg;
+ }
+ ArrayList ary2;
+ if (rpl == null)
+ {
+ ary2 = new ArrayList();
+ }
+ else if (rpl is RArray == false)
+ {
+ ary2 = new ArrayList();
+ ary2.Add(rpl);
+ }
+ else
+ {
+ ary2 = ((RArray)rpl).ArrayList;
+ }
+ CheckModify();
+ if (beg >= ptr.Count)
+ {
+ if (beg > ptr.Count)
+ ptr.AddRange(new object[beg - ptr.Count]);
+ ptr.AddRange(ary2);
+ }
+ else
+ {
+ if (beg + len > ptr.Count)
+ {
+ len = ptr.Count - beg;
+ }
+ ptr.RemoveRange(beg, len);
+ ptr.InsertRange(beg, ary2);
+ }
+#if ARRAY_DEBUG
+ System.Console.WriteLine("replace");
+ foreach (object x in ptr)
+ {
+ System.Console.WriteLine(" - " + ((x == null) ? "null" : x.ToString()));
+ }
+ System.Console.WriteLine("done");
+#endif
+ }
+ internal object ASet(object[] argv)
+ {
+ if (argv.Length == 3)
+ {
+ Replace((int)argv[0], (int)argv[1], argv[2]);
+ return argv[2];
+ }
+ if (argv.Length != 2)
+ {
+ throw new ArgumentException("wrong # of argments(" + argv.Length.ToString() + " for 2)");
+ }
+ // Range object check
+ CheckModify();
+ int idx = RInteger.ToInt(ruby, argv[0]);
+ if (idx < 0)
+ {
+ idx += ptr.Count;
+ if (idx < 0)
+ throw new eIndexError(String.Format("index {0} out of array",
+ idx - ptr.Count));
+ }
+ if (idx >= ptr.Count)
+ {
+ ptr.Insert(idx, argv[1]);
+ }
+ else
+ {
+ ptr[idx] = argv[1];
+ }
+ return argv[1];
+ }
+ internal object At(int pos)
+ {
+ return this[pos];
+ }
+ internal object Push(params object[] argv)
+ {
+ if (argv.Length == 0)
+ {
+ throw new ArgumentException("wrong # of arguments(at least 1)");
+ }
+ CheckModify();
+ ptr.AddRange(argv);
+ return this;
+ }
+ public int Add(object o)
+ {
+ return ptr.Add(o);
+ }
+ internal object Pop()
+ {
+ CheckModify();
+ if (ptr.Count == 0) return null;
+ object result = ptr[ptr.Count - 1];
+ ptr.Remove(ptr.Count - 1);
+ return result;
+ }
+ internal object Shift()
+ {
+ CheckModify();
+ if (ptr.Count == 0) return null;
+ object result = ptr[0];
+ ptr.RemoveAt(0);
+ return result;
+ }
+ internal object Unshift(params object[] args)
+ {
+ if (args == null || args.Length == 0)
+ throw new eArgError("wrong # of arguments(at least 1)");
+
+ CheckModify();
+ ptr.InsertRange(0, args);
+ return this;
+ }
+ internal RArray Each()
+ {
+ foreach (object o in ptr)
+ {
+ ruby.Yield(o);
+ }
+ return this;
+ }
+ internal RArray EachIndex()
+ {
+ for (int i = 0; i < ptr.Count; i++)
+ {
+ ruby.Yield(i);
+ }
+ return this;
+ }
+ internal RArray ReverseEach()
+ {
+ for (int i = ptr.Count - 1; i >= 0; i--)
+ {
+ ruby.Yield(ptr[i]);
+ }
+ return this;
+ }
+ internal bool ArrayEqual(object o)
+ {
+ if (this == o) return true;
+ if (o is RArray == false) return false;
+ RArray a = (RArray)o;
+ if (ptr == a.ptr) return true;
+ if (ptr.Count != a.ptr.Count) return false;
+ for (int i = 0; i < ptr.Count; i++)
+ {
+ if (ruby.Equal(ptr[i], a.ptr[i]) == false) return false;
+ }
+ return true;
+ }
+ internal bool ArrayEql(object o)
+ {
+ if (o is RArray == false) return false;
+ RArray a = (RArray)o;
+ if (ptr.Count != a.ptr.Count) return false;
+ for (int i = 0; i < ptr.Count; i++)
+ {
+ if (ruby.Eql(ptr[i], a.ptr[i])== false) return false;
+ }
+ return true;
+ }
+ public IEnumerator GetEnumerator()
+ {
+ return ptr.GetEnumerator();
+ }
+ public int Count
+ {
+ get { return ptr.Count; }
+ }
+ public bool IsSynchronized
+ {
+ get { return ptr.IsSynchronized; }
+ }
+ public object SyncRoot
+ {
+ get { return ptr.SyncRoot; }
+ }
+ public void CopyTo(Array array, int index)
+ {
+ ptr.CopyTo(array, index);
+ }
+ public bool IsEmpty
+ {
+ get { return (ptr.Count == 0); }
+ }
+ public int IndexOf(object o)
+ {
+ for (int i = 0; i < ptr.Count; i++)
+ {
+ if (ruby.Equal(ptr[i], o)) return i;
+ }
+ return -1;
+ }
+ public void Insert(int index, object value)
+ {
+ ptr.Insert(index, value);
+ }
+ public void Remove(object o)
+ {
+ int i = IndexOf(o);
+ if (i >= 0) RemoveAt(i);
+ }
+ public void RemoveAt(int i)
+ {
+ if (i < 0 || i >= ptr.Count) throw new ArgumentOutOfRangeException();
+ try
+ {
+ DeleteAt(i);
+ }
+ catch (SecurityException)
+ {
+ throw new NotSupportedException();
+ }
+ catch (eTypeError)
+ {
+ throw new NotSupportedException();
+ }
+ }
+ internal object Delete(object item)
+ {
+ int pos = ptr.Count;
+ Remove(item);
+ if (ptr.Count == pos)
+ {
+ if (ruby.IsBlockGiven)
+ {
+ ruby.Yield(item);
+ }
+ return null;
+ }
+ return item;
+ }
+ internal object DeleteAt(int pos)
+ {
+ CheckModify();
+ if (pos >= ptr.Count) return null;
+ if (pos < 0) pos += ptr.Count;
+ if (pos < 0) return null;
+ object del = ptr[pos];
+ ptr.RemoveAt(pos);
+ return del;
+ }
+ public object Index(object o)
+ {
+ int i = IndexOf(o);
+ if (i < 0)
+ return null;
+ return i;
+ }
+ public object RIndex(object o)
+ {
+ for (int i = ptr.Count - 1; i >= 0; i--)
+ {
+ if (ruby.Equal(ptr[i], o)) return i;
+ }
+ return null;
+ }
+ ArrayList ptr;
+
+ static internal void Init(NetRuby rb)
+ {
+ BindingFlags bf = BindingFlags.InvokeMethod
+ | BindingFlags.Static | BindingFlags.Public
+ | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy
+ | BindingFlags.Instance;
+ RClass ary = rb.DefineClass("Array", rb.cObject);
+ RMetaObject.IncludeModule(ary, rb.mEnumerable);
+ rb.cArray = ary;
+ Type obj = typeof(RArray);
+ ary.DefineSingletonMethod("new", new RMethod(s_new), -1);
+ ary.DefineSingletonMethod("[]", obj.GetMethod("Create", bf));
+
+ ary.DefineMethod("initialize", obj.GetMethod("Initialize", bf));
+
+ ary.DefineMethod("to_ary", obj.GetMethod("ToArray", bf));
+ ary.DefineMethod("==", obj.GetMethod("ArrayEqual", bf));
+ ary.DefineMethod("eql?", obj.GetMethod("ArrayEql", bf));
+
+ ary.DefineMethod("[]", obj.GetMethod("ARef", bf));
+ ary.DefineMethod("[]=", obj.GetMethod("ASet", bf));
+ ary.DefineMethod("at", obj.GetMethod("At", bf));
+ ary.DefineMethod("first", obj.GetMethod("get_First", bf));
+ ary.DefineMethod("last", obj.GetMethod("get_Last", bf));
+ ary.DefineMethod("concat", obj.GetMethod("Concat", bf));
+ ary.DefineMethod("<<", obj.GetMethod("Push", bf));
+ ary.DefineMethod("push", obj.GetMethod("Push", bf));
+ ary.DefineMethod("pop", obj.GetMethod("Pop", bf));
+ ary.DefineMethod("shift", obj.GetMethod("Shift", bf));
+ ary.DefineMethod("unshift", obj.GetMethod("Unshift", bf));
+ ary.DefineMethod("each", obj.GetMethod("Each", bf));
+ ary.DefineMethod("each_index", obj.GetMethod("EachIndex", bf));
+ ary.DefineMethod("reverse_each", obj.GetMethod("ReverseEach", bf));
+ ary.DefineMethod("length", obj.GetMethod("get_Count", bf));
+ ary.DefineAlias("size", "length");
+ ary.DefineMethod("empty?", obj.GetMethod("get_IsEmpty", bf));
+ ary.DefineMethod("index", obj.GetMethod("Index", bf));
+ ary.DefineMethod("rindex", obj.GetMethod("RIndex", bf));
+
+ ary.DefineMethod("clone", obj.GetMethod("Clone", bf));
+ ary.DefineMethod("join", obj.GetMethod("JoinMethod", bf));
+
+ ary.DefineMethod("reverse", obj.GetMethod("Reverse", bf));
+ ary.DefineMethod("reverse!", obj.GetMethod("ReverseAt", bf));
+ ary.DefineMethod("sort", obj.GetMethod("Sort", bf));
+ ary.DefineMethod("sort!", obj.GetMethod("SortAt", bf));
+ ary.DefineMethod("collect", obj.GetMethod("Collect", bf));
+ ary.DefineMethod("collect!", obj.GetMethod("CollectAt", bf));
+
+ ary.DefineMethod("delete", obj.GetMethod("Delete", bf));
+ ary.DefineMethod("delete_at", obj.GetMethod("DeleteAt", bf));
+
+ ary.DefineMethod("clear", obj.GetMethod("Clear2", bf));
+ ary.DefineMethod("fill", obj.GetMethod("Fill", bf));
+ ary.DefineMethod("include", obj.GetMethod("Contains", bf));
+ }
+ }
+}
View
813 rubynet/Bignum.cs
@@ -0,0 +1,813 @@
+/*
+Copyright (C) 1993-2001 Yukihiro Matsumoto
+Copyright (C) 2001-2002 arton
+Copyright (C) 2005 Jaen Saul
+*/
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Security;
+using System.Text;
+
+namespace NETRuby
+{
+ public class RBignum : RInteger, IComparable, ICloneable
+ {
+
+ internal RBignum(NetRuby rb, int ln, bool sgn)
+ : base(rb, rb.cBignum)
+ {
+ sign = sgn;
+ len = ln;
+ digits = new uint[ln];
+ for (int i = 0; i < ln; i++) digits[i] = 0;
+ }
+
+ internal RBignum(NetRuby rb, uint u, bool sgn)
+ : base(rb, rb.cBignum)
+ {
+ sign = sgn;
+ len = 1;
+ digits = new uint[1];
+ digits[0] = u;
+ }
+
+ internal RBignum(NetRuby rb, long l)
+ : base(rb, rb.cBignum)
+ {
+ sign = (l < 0) ? false : true;
+ len = 2;
+ digits = new uint[2];
+ digits[0] = BIGLO(l);
+ digits[1] = (uint)BIGDN(l);
+ }
+
+ internal RBignum(NetRuby rb, uint[] us, bool sgn)
+ : base(rb, rb.cBignum)
+ {
+ sign = sgn;
+
+ len = us.Length;
+ digits = us;
+ // normalize
+ int i = len;
+ while (i-- != 0 && digits[i] == 0);
+ len = ++i;
+ }
+
+ private bool sign;
+ private int len;
+ private uint[] digits;
+
+ public ulong Big2Ulong()
+ {
+ if (len > 8)
+ throw new eRangeError("bignum too big to convert into `ulong'");
+ ulong num = 0;
+ int i = len;
+ while (i-- > 0)
+ {
+ num = BIGUP(num);
+ num += digits[i];
+ }
+ return num;
+ }
+
+ public override RFloat ToFloat()
+ {
+ return new RFloat(ruby, Big2Dbl());
+ }
+
+ public override long ToLong()
+ {
+ ulong num = Big2Ulong();
+ if (num > (ulong)Int64.MaxValue)
+ throw new eRangeError("bignum too big to convert into `long'");
+ long l = (long)num;
+ return (sign) ? l : -l;
+ }
+
+ public override object Clone()
+ {
+ RBignum big = new RBignum(ruby, len, sign);
+ Array.Copy(digits, big.digits, len);
+ return big;
+ }
+
+ public void TwoComp()
+ {
+ int i = len;
+ while (i-- > 0) digits[i] = ~digits[i];
+ i = 0;
+ ulong num = 1;
+ do
+ {
+ num += digits[i];
+ digits[i++] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ while (i < len);
+ if (digits[0] == 1 || digits[0] == 0)
+ {
+ for (i = 1; i < len; i++)
+ {
+ if (digits[i] != 0) return;
+ }
+ uint[] ns = new uint[len + 1];
+ for (i = 0; i < len; i++)
+ ns[i] = digits[i];
+ ns[len] = 1;
+ len++;
+ digits = ns;
+ }
+ }
+ public double Big2Dbl()
+ {
+ double d = 0.0;
+ int i = len;
+ while (i-- != 0)
+ {
+ d = digits[i] + BIGRAD * d;
+ }
+ return (sign) ? d : -d;
+ }
+
+ public static RBignum Dbl2Big(NetRuby ruby, double d)
+ {
+ if (Double.IsInfinity(d))
+ {
+ throw new eFloatDomainError((d < 0) ? "-Infinity" : "Infinity");
+ }
+ if (Double.IsNaN(d))
+ {
+ throw new eFloatDomainError("NaN");
+ }
+ int i = 0;
+ double u = (d < 0) ? -d : d;
+ while (u <= Int32.MaxValue == false || 0 != (int)u)
+ {
+ u /= (double)BIGRAD;
+ i++;
+ }
+ uint[] dg = new uint[i];
+ while (i-- != 0)
+ {
+ u *= BIGRAD;
+ dg[i] = (uint)u;
+ u -= dg[i];
+ }
+ return new RBignum(ruby, dg, (d >= 0));
+ }
+
+ public static RBignum Int2Big(NetRuby ruby, int n)
+ {
+ bool neg = false;
+ if (n < 0)
+ {
+ n = -n;
+ neg = true;
+ }
+ RBignum big = Uint2Big(ruby, (uint)n);
+ if (neg)
+ {
+ big.sign = false;
+ }
+ return big;
+ }
+
+ public static RBignum Uint2Big(NetRuby ruby, uint n)
+ {
+ RBignum big = new RBignum(ruby, 1, true);
+ big.digits[0] = n;
+ if (n == 0) big.len = 0;
+ return big;
+ }
+
+ public static RBignum Long2Big(NetRuby ruby, long n)
+ {
+ bool neg = false;
+ if (n < 0)
+ {
+ n = -n;
+ neg = true;
+ }
+ RBignum big = Ulong2Big(ruby, (ulong)n);
+ if (neg)
+ {
+ big.sign = false;
+ }
+ return big;
+ }
+
+ public static RBignum Ulong2Big(NetRuby ruby, ulong n)
+ {
+ ulong num = (ulong)n;
+ RBignum big = new RBignum(ruby, 2, true);
+ big.digits[0] = (uint)n;
+ big.digits[1] = (uint)(n >> 32);
+ return big;
+ }
+
+ static private RBignum to_big(NetRuby ruby, object o)
+ {
+ RBignum y = null;
+ if (o is RFixnum)
+ o = ((RFixnum)o).GetData();
+ if (o is RBignum)
+ y = (RBignum)o;
+ if (o is int)
+ y = Int2Big(ruby, (int)o);
+ else if (o is long)
+ y = Long2Big(ruby, (long)o);
+ else if (o is double)
+ y = Dbl2Big(ruby, (double)o);
+ else if (o is RFloat)
+ y = Dbl2Big(ruby, ((RFloat)o).Double);
+ return y;
+ }
+
+ public bool Eq(object o)
+ {
+ RBignum y = null;
+ if (o is RFixnum)
+ o = ((RFixnum)o).GetData();
+ if (o is int)
+ y = Int2Big(ruby, (int)o);
+ else if (o is long)
+ y = Long2Big(ruby, (long)o);
+ else if (o is double)
+ return (Big2Dbl() == (double)o);
+ else if (o is RFloat)
+ return (Big2Dbl() == ((RFloat)o).Double);
+ else if (o is RBignum == false)
+ return false;
+ else
+ y = (RBignum)o;
+ if (sign != y.sign) return false;
+ if (len != y.len) return false;
+ for (int i = 0; i < len; i++)
+ {
+ if (digits[i] != y.digits[i]) return false;
+ }
+ return true;
+ }
+
+ public override string ToString()
+ {
+ return ToRString(10).ToString();
+ }
+
+ public override RString ToRString()
+ {
+ return ToRString(10);
+ }
+ public override RInteger ToInteger()
+ {
+ return this;
+ }
+
+ private static readonly string hexmap = "0123456789abcdef";
+ public RString ToRString(int radix)
+ {
+ if (len == 0) return new RString(ruby, "0");
+ int j = 0;
+ int hbase = 0;
+ switch (radix)
+ {
+ case 10:
+ j = (32 * len * 241)/800 + 2;
+ hbase = 10000;
+ break;
+ case 16:
+ j = (32 * len) / 4 + 2;
+ hbase = 0x10000;
+ break;
+ case 8:
+ j = (32 * len) + 2;
+ hbase = 0x1000;
+ break;
+ case 2:
+ j = (32 * len) + 2;
+ hbase = 0x10;
+ break;
+ default:
+ throw new eArgError("bignum cannot treat base " + base.ToString());
+ }
+ uint[] t = new uint[len];
+ Array.Copy(digits, t, len);
+ StringBuilder ss = new StringBuilder(j);
+ ss.Length = j;
+ int i = len;
+ while (i != 0 && j != 0)
+ {
+ int k = i;
+ ulong num = 0;
+ while (k-- != 0)
+ {
+ num = BIGUP(num) + t[k];
+ t[k] = (uint)(num / (uint)hbase);
+ num %= (uint)hbase;
+ }
+ if (t[i - 1] == 0) i--;
+ k = 4;
+ while (k-- != 0)
+ {
+ int c = (char)(num % (uint)radix);
+ ss[--j] = hexmap[c];
+ num /= (uint)radix;
+ if (i == 0 && num == 0) break;
+ }
+ }
+ while (ss[j] == '0') j++;
+ if (sign == false)
+ {
+ ss[--j] = '-';
+ }
+ int ln = ss.Length - j;
+ string s = ss.ToString().Substring(j, ln);
+ return new RString(ruby, s);
+ }
+
+ public int CompareTo(object o)
+ {
+ RBignum r = to_big(ruby, o);
+ if (r == null)
+ {
+ throw new ArgumentException("object is not a Bignum");
+ }
+ if (sign && !r.sign) return 1;
+ if (!sign && r.sign) return -1;
+ if (len < r.len)
+ return (sign) ? -1 : 1;
+ if (len > r.len)
+ return (sign) ? 1 : -1;
+ int xlen = len;
+ while ((xlen-- > 0) && digits[xlen] == r.digits[xlen]);
+ if (xlen < 0) return 0;
+ return (digits[xlen] > r.digits[xlen]) ? (sign ? 1 : -1) : (sign ? -1 : 1);
+ }
+ public override bool Gt(object o)
+ {
+ RBignum r = to_big(ruby, o);
+ if (r == null)
+ {
+ return (bool)CoerceBin(o);
+ }
+ int i = CompareTo(r);
+ return i > 0;
+ }
+ public override bool GE(object o)
+ {
+ RBignum r = to_big(ruby, o);
+ if (r == null)
+ {
+ return (bool)CoerceBin(o);
+ }
+ int i = CompareTo(r);
+ return i >= 0;
+ }
+ public override bool Lt(object o)
+ {
+ RBignum r = to_big(ruby, o);
+ if (r == null)
+ {
+ return (bool)CoerceBin(o);
+ }
+ int i = CompareTo(r);
+ return i < 0;
+ }
+ public override bool LE(object o)
+ {
+ RBignum r = to_big(ruby, o);
+ if (r == null)
+ {
+ return (bool)CoerceBin(o);
+ }
+ int i = CompareTo(r);
+ return i <= 0;
+ }
+
+ public RInteger Negate()
+ {
+ RBignum z = (RBignum)Clone();
+ if (sign == false) z.TwoComp();
+ for (int i = 0; i < len; i++)
+ {
+ z.digits[i] = ~z.digits[i];
+ }
+ if (sign) z.TwoComp();
+ z.sign = !z.sign;
+ return z.Normalize;
+ }
+ public override RInteger Normalize
+ {
+ get {
+ int i = len;
+ while (i-- != 0 && digits[i] == 0);
+ len = ++i;
+ if (len <= 1 && (int)digits[0] <= Int32.MaxValue)
+ {
+ return new RFixnum(ruby, (sign ? (int)digits[0] : -(int)digits[0]));
+ }
+ return this;
+ }
+ }
+ public override RArray Coerce(object y)
+ {
+ if (y is int || y is long || y is RFixnum)
+ return RArray.AssocNew(ruby, to_big(ruby, y), this);
+ throw new eTypeError("Can't create " + ruby.ClassOf(y).Name + " to Bignum");
+ }
+ public override RNumeric Plus(object o)
+ {
+ return (this + to_big(ruby, o)).Normalize;
+ }
+ public override RNumeric Minus(object o)
+ {
+ return (this - to_big(ruby, o)).Normalize;
+ }
+ public override RNumeric Multiply(object o)
+ {
+ return (this * to_big(ruby, o)).Normalize;
+ }
+ public override RNumeric Divide(object o)
+ {
+ RBignum z;
+ RBignum y = divmod(o, out z);
+ return y.Normalize;
+ }
+ public override RNumeric Modulo(object o)
+ {
+ RBignum z;
+ divmod(o, out z);
+ return z.Normalize;
+ }
+ public override RNumeric Remainder(object o)
+ {
+ return (this % to_big(ruby, o)).Normalize;
+ }
+ public override RArray DivMod(object o)
+ {
+ RBignum z;
+ RBignum y = divmod(o, out z);
+ return RArray.AssocNew(ruby, y.Normalize, z.Normalize);
+ }
+ private RBignum divmod(object o, out RBignum mod)
+ {
+ mod = null;
+ RBignum y = to_big(ruby, o);
+ RBignum dv = divrem(y, out mod);
+ if (sign != y.sign && mod.len > 0)
+ {
+ dv = dv - to_big(ruby, 1);
+ mod = mod + y;
+ }
+ return dv;
+ }
+
+ public override bool Equals(object o)
+ {
+ return base.Equals(o);
+ }
+ public bool Sign
+ {
+ get { return sign; }
+ }
+ static internal object ruby_neg(RBasic r, params object[] args)
+ {
+ return ((RBignum)r).Negate();
+ }
+ static internal object ruby_eq(RBasic r, params object[] args)
+ {
+ return ((RBignum)r).Eq(args[0]);
+ }
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+ public static bool operator ==(RBignum b1, RBignum b2)
+ {
+ return b1.Eq(b2);
+ }
+ public static bool operator !=(RBignum b1, RBignum b2)
+ {
+ return !b1.Eq(b2);
+ }
+ public static RBignum operator +(RBignum b1, RBignum b2)
+ {
+ return b1.add(b2, true);
+ }
+ public static RBignum operator -(RBignum b1, RBignum b2)
+ {
+ return b1.add(b2, false);
+ }
+ public static RBignum operator *(RBignum x, RBignum y)
+ {
+ int j = x.len + y.len + 1;
+ uint[] z = new uint[j];
+ while (j-- != 0) z[j] = 0;
+ for (int i = 0; i < x.len; i++)
+ {
+ ulong dd = x.digits[i];
+ if (dd == 0) continue;
+ ulong n = 0;
+ for (j = 0; j < y.len; j++)
+ {
+ ulong ee = n + dd * y.digits[j];
+ n = (ulong)z[i + j] + ee;
+ if (ee != 0) z[i + j] = BIGLO(n);
+ n = BIGDN(n);
+ }
+ if (n != 0)
+ {
+ z[i + j] = (uint)n;
+ }
+ }
+ return new RBignum(x.ruby, z, x.sign == y.sign);
+ }
+ public static RBignum operator /(RBignum x, RBignum y)
+ {
+ RBignum mod;
+ return x.divrem(y, out mod);
+ }
+ public static RBignum operator %(RBignum x, RBignum y)
+ {
+ RBignum mod;
+ RBignum div = x.divrem(y, out mod);
+ return mod;
+ }
+ public static bool operator >(RBignum x, RBignum y)
+ {
+ return x.Gt(y);
+ }
+ public static bool operator >=(RBignum x, RBignum y)
+ {
+ return x.GE(y);
+ }
+ public static bool operator <(RBignum x, RBignum y)
+ {
+ return x.Lt(y);
+ }
+ public static bool operator <=(RBignum x, RBignum y)
+ {
+ return x.LE(y);
+ }
+
+ private RBignum sub(RBignum y)
+ {
+ uint[] xx = digits;
+ uint[] yy = y.digits;
+ int xlen = len;
+ int ylen = y.len;
+ bool sig = true;
+ int i;
+ if (len < y.len)
+ {
+ xx = y.digits;
+ yy = digits;
+ sig = false;
+ xlen = y.len;
+ ylen = len;
+ }
+ else if (len == y.len)
+ {
+ for (i = len; i > 0; )
+ {
+ i--;
+ if (xx[i] > yy[i])
+ break;
+ if (xx[i] < yy[i])
+ {
+ xx = y.digits;
+ yy = digits;
+ xlen = y.len;
+ ylen = len;
+ sig = false;
+ }
+ }
+ }
+ uint[] z = new uint[xlen];
+ long num = 0;
+ for (i = 0; i < ylen; i++)
+ {
+ num += (long)xx[i] - yy[i];
+ z[i] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ while (num != 0 && i < xlen)
+ {
+ num += xx[i];
+ z[i++] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ while (i < xlen)
+ {
+ z[i] = xx[i];
+ i++;
+ }
+ return new RBignum(ruby, z, sig);
+ }
+ private RBignum add(RBignum y, bool s)
+ {
+ bool sig = (s == y.sign);
+ if (sign != sig)
+ {
+ if (sig) return y.sub(this);
+ return sub(y);
+ }
+ uint[] xx = digits;
+ uint[] yy = y.digits;
+ int xlen = len;
+ int ylen = y.len;
+ int nl = len;
+ if (nl > y.len)
+ {
+ nl++;
+ xx = y.digits;
+ yy = digits;
+ xlen = y.len;
+ ylen = len;
+ }
+ else
+ {
+ nl = y.len + 1;
+ }
+ uint[] z = new uint[nl];
+ ulong num = 0;
+ int i;
+ for (i = 0; i < xlen; i++)
+ {
+ num += (ulong)xx[i] + (ulong)yy[i];
+ z[i] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ while (num != 0 && i < ylen)
+ {
+ num += yy[i];
+ z[i++] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ while (i < ylen)
+ {
+ z[i] = yy[i];
+ i++;
+ }
+ z[i] = (uint)num;
+ return new RBignum(ruby, z, sig);
+ }
+
+ private RBignum divrem(RBignum y, out RBignum mod)
+ {
+ mod = null;
+ uint dd;
+ int ny = y.len;
+ int nx = len;
+ int i;
+ ulong t2;
+ if (ny == 0 && y.digits[0] == 0)
+ throw new DivideByZeroException("divided by 0");
+ if (nx < ny || nx == ny && digits[nx - 1] < y.digits[ny - 1])
+ {
+ mod = this;
+ return new RBignum(ruby, (uint)0, true);
+ }
+ if (ny == 1)
+ {
+ dd = y.digits[0];
+ RBignum z = (RBignum)Clone();
+ i = nx;
+ t2 = 0;
+ while (i-- != 0)
+ {
+ t2 = (ulong)BIGUP(t2) + z.digits[i];
+ z.digits[i] = (uint)(t2 / dd);
+ t2 %= dd;
+ }
+ z.sign = (sign == y.sign);
+ mod = Uint2Big(ruby, (uint)t2);
+ mod.sign = sign;
+ return z;
+ }
+
+ uint[] zz = new uint[(nx == ny) ? nx + 2 : nx + 1];
+ if (nx == ny) zz[nx + 1] = 0;
+ while (y.digits[ny - 1] == 0) ny--;
+
+ dd = 0;
+ uint q = y.digits[ny - 1];
+ int j = 0;
+ uint[] ys = y.digits;
+ while ((q & ((uint)1 << (int)(BITSPERDIG-1))) == 0)
+ {
+ q <<= 1;
+ dd++;
+ }
+ if (dd != 0)
+ {
+ RBignum yy = (RBignum)y.Clone();
+ j = 0;
+ t2 = 0;
+ while (j < ny)
+ {
+ t2 += ((ulong)y.digits[j]) << (int)dd;
+ yy.digits[j++] = BIGLO(t2);
+ t2 = BIGDN(t2);
+ }
+ ys = yy.digits;
+ j = 0;
+ t2 = 0;
+ while (j < nx)
+ {
+ t2 += ((ulong)digits[j]) << (int)dd;
+ zz[j++] = BIGLO(t2);
+ t2 = BIGDN(t2);
+ }
+ zz[j] = (uint)t2;
+ }
+ else
+ {
+ zz[nx] = 0;
+ j = nx;
+ while (j-- != 0) zz[j] = digits[j];
+ }
+
+ j = (nx == ny) ? nx + 1 : nx;
+ do
+ {
+ if (zz[j] == ys[ny - 1]) q = (uint)(BIGRAD - 1);
+ else q = (uint)((BIGUP(zz[j]) + zz[j - 1])/ys[ny - 1]);
+ if (q != 0)
+ {
+ i = 0;
+ long num = 0;
+ t2 = 0;
+ do
+ {
+ t2 += (ulong)ys[i] * q;
+ ulong ee = (ulong)(num - BIGLO(t2));
+ num = (long)(zz[j - ny + i] + ee);
+ if (ee != 0) zz[j - ny + i] = BIGLO(num);
+ num = BIGDN(num);
+ t2 = BIGDN(t2);
+ }
+ while (++i < ny);
+ num += (long)(zz[j - ny + i] - t2);
+ while (num != 0)
+ {
+ i = 0;
+ num = 0;
+ q--;
+ do
+ {
+ ulong ee = (ulong)(num + ys[i]);
+ num = (long)((ulong)zz[j - ny + i] + ee);
+ if (ee != 0) zz[j - ny + i] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ while (++i < ny);
+ num--;
+ }
+ }
+ zz[j] = q;
+ }
+ while (--j >= ny);
+ RBignum div = new RBignum(ruby, zz, sign == y.sign);
+ mod = (RBignum)div.Clone();
+ j = (nx == ny ? nx + 2 : nx + 1) - ny;
+ for (i = 0; i < j; i++) div.digits[i] = div.digits[i + ny];
+ div.len = i;
+
+ while (ny-- != 0 && mod.digits[ny] == 0);
+ ny++;
+ if (dd != 0)
+ {
+ t2 = 0;
+ i = ny;
+ while (i-- != 0)
+ {
+ t2 = (t2 | mod.digits[i]) >> (int)dd;
+ q = mod.digits[i];
+ mod.digits[i] = BIGLO(t2);
+ t2 = BIGUP(q);
+ }
+ mod.len = ny;
+ mod.sign = sign;
+ }
+ return div;
+ }
+
+ static internal new void Init(NetRuby rb)
+ {
+ RClass big = rb.DefineClass("Bignum", rb.cInteger);
+ rb.cBignum = big;
+
+ big.DefineMethod("~", new RMethod(ruby_neg), 0);
+
+ RMethod rm = new RMethod(ruby_eq);
+ big.DefineMethod("==", rm, 1);
+ big.DefineMethod("===", rm, 1);
+ big.DefineMethod("eql?", rm, 1);
+ }
+ }
+}
View
7 rubynet/ChangeLog
@@ -0,0 +1,7 @@
+2005-08-30 Florian Gross <flgr@ccan.de>
+
+ * Fixed Makefile to work correctly on BSD style platforms
+
+2005-08-18 Florian Gross <flgr@ccan.de>
+
+ * Everything: Set svn:eol-style to native
View
1,413 rubynet/Class.cs
@@ -0,0 +1,1413 @@
+/*
+Copyright (C) 1993-2000 Yukihiro Matsumoto
+Copyright (C) 2001-2002 arton
+Copyright (C) 2005 Jaen Saul
+*/
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Security;
+
+namespace NETRuby
+{
+ public abstract class RMetaObject : RObjectBase
+ {
+ internal RMetaObject(NetRuby rb, string name, RMetaObject sp, RMetaObject meta)
+ : base(rb, meta)
+ {
+ super = sp;
+ m_tbl = new st_table();
+ if (name != null)
+ {
+ uint id = rb.intern(name);
+ IVarSet("__classid__", Symbol.ID2SYM(id));
+ }
+ }
+ internal RMetaObject(RMetaObject o) :
+ base(o)
+ {
+ if (o.m_tbl != null)
+ {
+ m_tbl = (st_table)o.m_tbl.Clone();
+ }
+ }
+ internal RMetaObject super;
+ internal st_table m_tbl;
+
+ public override string ToString()
+ {
+ return ClassPath;
+ }
+
+ public void Attribute(uint id, bool read, bool write, bool ex)
+ {
+ string s = ruby.id2name(id);
+ if (s == null)
+ throw new eArgError("argument needs to be symbol or string");
+ Attribute(s, read, write, ex);
+ }
+ public void Attribute(string name, bool read, bool write, bool ex)
+ {
+ NOEX noex = NOEX.PUBLIC;
+ RThread th = ruby.GetCurrentContext();
+ if (ex)
+ {
+ if (th.ScopeTest(Scope.ScopeMode.Private))
+ {
+ noex = NOEX.PRIVATE;
+ ruby.warning((th.ScopeMode == Scope.ScopeMode.ModFunc) ?
+ "attribute accessor as module_function" :
+ "private attribute?");
+ }
+ else if (th.ScopeTest(Scope.ScopeMode.Protected))
+ {
+ noex = NOEX.PROTECTED;
+ }
+ }
+ uint id = ruby.ToID(name);
+ uint attriv = ruby.intern("@" + name);
+ if (read)
+ {
+ ////addMethod(id, new RNIVar(th, attriv), noex);
+ ruby.Funcall(this, "method_added", Symbol.ID2SYM(id));
+ }
+ if (write)
+ {
+ id = ruby.intern(name + "=");
+ ////addMethod(id, new RNAttrSet(th, attriv), noex);
+ ruby.Funcall(this, "method_added", Symbol.ID2SYM(id));
+ }
+ }
+ public void DefineConst(string name, object val)
+ {
+ uint id = ruby.intern(name);
+ ////if (this == ruby.cObject) ruby.Secure(4);
+ if (Parser.is_const_id(id) == false)
+ throw new eNameError("wrong constant name " + name);
+ ConstSet(id, val);
+ }
+ public void ConstSet(uint id, object val)
+ {
+ valSet(id, val, true);
+ }
+
+ public object ConstGet(uint id)
+ {
+ bool fretry = false;
+ RMetaObject klass = this;
+ retry:
+ while (klass != null)
+ {
+ object o;
+ if (klass.iv_tbl != null && klass.iv_tbl.lookup(id, out o))
+ {
+ return o;
+ }
+ if (klass == ruby.cObject && ruby.TopConstGet(id, out o))
+ {
+ return o;
+ }
+ klass = klass.super;
+ }
+ if (fretry == false && this is RModule)
+ {
+ fretry = true;
+ klass = ruby.cObject;
+ goto retry;
+ }
+ if (this != ruby.cObject)
+ {
+ string s = String.Format("uninitialized constant {0} at {1}",
+ ruby.id2name(id), ClassPath);
+#if _DEBUG
+ System.Console.Error.WriteLine(s);
+#endif
+ throw new eNameError(s);
+ }
+ throw new eNameError("uninitialized constant " + ruby.id2name(id));
+ }
+
+ public object ConstGetAt(uint id)
+ {
+ object o;
+ if (iv_tbl != null && iv_tbl.lookup(id, out o))
+ {
+ return o;
+ }
+ if (this == ruby.cObject && ruby.TopConstGet(id, out o))
+ {
+ return o;
+ }
+ throw new eNameError(String.Format("uninitialized constant {0}::{1}",
+ ClassPath, ruby.id2name(id)));
+ }
+
+ public bool IsConstDefinedAt(uint id)
+ {
+ if (iv_tbl != null && iv_tbl.ContainsKey(id))
+ return true;
+ if (this == ruby.cObject)
+ return IsConstDefined(id);
+ return false;
+ }
+ public bool IsConstDefined(uint id)
+ {
+ RMetaObject kclass = this;
+
+ while (kclass != null)
+ {
+ if (kclass.iv_tbl != null && kclass.iv_tbl.ContainsKey(id))
+ {
+ return true;
+ }
+ kclass = kclass.super;
+ }
+ if (this is RModule)
+ {
+ return ruby.cObject.IsConstDefined(id);
+ }
+ if (ruby.class_tbl.ContainsKey(id)) return true;
+ ////return ruby.IsAutoloadDefined(id);
+ return false;
+ }
+ public object RemoveConst(uint id)
+ {
+ if (Parser.is_const_id(id) == false)
+ throw new eNameError("wrong constant name " + ruby.id2name(id));
+/*
+ if (IsTainted == false && ruby.SafeLevel >= 4)
+ throw new SecurityException("Insecure: can't remove constant");
+*/
+ if (IsFrozen) ruby.ErrorFrozen("class/module");
+ object o;
+ if (iv_tbl != null && iv_tbl.delete(id, out o)) return o;
+ if (IsConstDefinedAt(id))
+ throw new eNameError(String.Format("cannot remove {0}::{1}",
+ Name, ruby.id2name(id)));
+ throw new eNameError(String.Format("constant {0}::{1} not defined",
+ Name, ruby.id2name(id)));
+ }
+ public void CVarDeclare(uint id, object val)
+ {
+ try
+ {
+ CVarSet(id, val);
+ }
+ catch (eNameError)
+ {
+ valSet(id, val, false);
+ }
+ }
+ public object CVarGet(uint id)
+ {
+ RMetaObject tmp = this;
+ object result = null;
+ while (tmp != null)
+ {
+ if (tmp.iv_tbl != null && tmp.iv_tbl.lookup(id, out result))
+ return result;
+ tmp = tmp.super;
+ }
+ throw new eNameError(String.Format("uninitialized class variable {0} in {1}",
+ ruby.id2name(id), ClassName));
+ }
+ public void CVarSet(uint id, object val)
+ {
+ RMetaObject tmp = this;
+ while (tmp != null)
+ {
+ lock (tmp.iv_tbl.SyncRoot)
+ {
+ if (tmp.iv_tbl != null && tmp.iv_tbl.ContainsKey(id))
+ {
+ tmp.CVarCheck("class variable");
+ tmp.iv_tbl[id] = val;
+ return;
+ }
+ }
+ tmp = tmp.super;
+ }
+ throw new eNameError("uninitialized class variable " + ruby.id2name(id) + " in " + ClassName);
+ }
+ void valSet(uint id, object val, bool isconst)
+ {
+ string dest = (isconst) ? "constant" : "class variable";
+ CVarCheck(dest);
+ lock (this)
+ {
+ if (iv_tbl == null)
+ {
+ iv_tbl = new st_table();
+ }
+ else if (isconst)
+ {
+ if (iv_tbl.ContainsKey(id) ||
+ (this == ruby.cObject && ruby.class_tbl.ContainsKey(id)))
+ {
+ ruby.warn(String.Format("already initialized {0} {1}",
+ dest, ruby.id2name(id)));
+ }
+ }
+ iv_tbl[id] = val;
+ }
+ }
+ protected void CVarCheck(string dest)
+ {
+/*
+ if (IsTainted == false && ruby.SafeLevel >= 4)
+ {
+ throw new SecurityException("Insecure: can't set " + dest);
+ }
+*/
+ if (IsFrozen) ruby.ErrorFrozen("class/module");
+ }
+
+ public virtual string Name // class2name
+ {
+ get { return ClassPath; }
+ }
+ public string ModuleName
+ {
+ get {
+ string s = ClassPath;
+ if (s != null) return s;
+ return String.Empty;
+ }
+ }
+ public virtual RMetaObject ClassReal
+ {
+ get {
+ RMetaObject cl;
+ if (this is RIncClass)
+ {
+ cl = klass;
+ }
+ else
+ {
+ cl = this;
+ }
+ while (cl is RIncClass || cl is RSingletonClass)
+ {
+ cl = cl.super;
+ }
+ return cl;
+ }
+ }
+ public string ClassPath
+ {
+ get {
+ string s = ClassName;
+ if (s != null) return s;
+ s = "Class";
+ if (this is RModule) s = "Module";
+ return String.Format("#<{0} 0lx{1:x8}>", s, GetHashCode());
+ }
+ }
+ public string ClassName
+ {
+ get {
+ object path = null;
+ uint cp = ruby.intern("__classpath__");
+ RMetaObject klass = ClassReal;
+ if (klass == null) klass = ruby.cObject;
+ lock (klass)
+ {
+ if (klass.iv_tbl != null &&
+ klass.iv_tbl.lookup(cp, out path) == false)
+ {
+ uint cid = ruby.intern("__classid__");
+ if (klass.iv_tbl.lookup(cid, out path))
+ {
+ path = ruby.id2name(Symbol.SYM2ID((uint)path));
+ klass.iv_tbl[cp] = path;
+ klass.iv_tbl.Remove(cid);
+ }
+ }
+ }
+ if (path == null)
+ {
+ path = klass.FindClassPath();
+ if (path == null) return String.Empty;
+ return (string)path;
+ }
+ if (path is string == false)
+ {
+ ruby.bug("class path is not set properly");
+ }
+ return (string)path;
+ }
+ }
+
+ internal void SetClassPath(RMetaObject under, string name)
+ {
+ string str = name;
+ if (under != ruby.cObject)
+ {
+ str = under.ClassPath;
+ str += "::" + name;
+ }
+ IVarSet("__classpath__", str);
+ }
+ private class fc_result
+ {
+ internal fc_result(uint key, RObjectBase kl, RObjectBase value, fc_result pv)
+ {
+ name = key;
+ path = null;
+ klass = kl;
+ track = value;
+ prev = pv;
+ }
+ internal bool end(RObjectBase o) { return (o == track); }
+ internal bool lookup(uint id, out string val)
+ {
+ val = null;
+ object o;
+ if (track.iv_tbl != null && track.iv_tbl.lookup(id, out o))
+ {
+ val = (string)o;
+ return true;
+ }
+ return false;
+ }
+ internal uint name;
+ internal RObjectBase klass;
+ internal string path;
+ RObjectBase track;
+ internal fc_result prev;
+ }
+ private string fc_path(fc_result fc, uint name)
+ {
+ string path = ruby.id2name(name);
+ string tmp;
+ uint cp = ruby.intern("__classpath__");
+ while (fc != null)
+ {
+ if (fc.end(ruby.cObject)) break;
+ if (fc.lookup(cp, out tmp))
+ {
+ return tmp + "::" + path;
+ }
+ tmp = ruby.id2name(fc.name);
+ path = tmp + "::" + path;
+ fc = fc.prev;
+ }
+ return path;
+ }
+ private bool fc_i(uint key, object value, fc_result res)
+ {
+ if (Parser.is_const_id(key)) return false;
+ if (value is RModule || value is RClass)
+ {
+ RMetaObject va = (RMetaObject)value;
+ if (va == res.klass)
+ {
+ res.path = fc_path(res, key);
+ return true;
+ }
+ if (va.iv_tbl == null) return false;
+ fc_result list = res;
+ while (list != null)
+ {
+ if (list.end(va)) return false;
+ list = list.prev;
+ }
+ fc_result arg = new fc_result(key, res.klass, va, res);
+ lock (va.iv_tbl.SyncRoot)
+ {
+ foreach (DictionaryEntry ent in va.iv_tbl)
+ {
+ if (fc_i((uint)ent.Key, ent.Value, arg))
+ {
+ res.path = arg.path;
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ internal object FindClassPath()
+ {
+ fc_result arg = new fc_result(0, this, ruby.cObject, null);
+ if (ruby.cObject.iv_tbl != null)
+ {
+ lock (ruby.cObject.iv_tbl.SyncRoot)
+ {
+ foreach (DictionaryEntry entry in ruby.cObject.iv_tbl)
+ {
+ if (fc_i((uint)entry.Key, entry.Value, arg)) break;
+ }
+ }
+ }
+ if (arg.path == null)
+ {
+ lock (ruby.class_tbl.SyncRoot)
+ {
+ foreach (DictionaryEntry entry in ruby.class_tbl)
+ {
+ if(fc_i((uint)entry.Key, entry.Value, arg)) break;
+ }
+ }
+ }
+ if (arg.path != null)
+ {
+ lock (this)
+ {
+ if (iv_tbl == null) iv_tbl = new st_table();
+ iv_tbl[ruby.intern("__classpath__")] = arg.path;
+ }
+ }
+ return (string)arg.path;
+ }
+
+ public static void ExtendObject(RBasic klass, RMetaObject module)
+ {
+ IncludeModule(SingletonClass(klass, klass.ruby), module);
+ }
+ internal static object extend_object(RBasic r, params object[] args)
+ {
+ ExtendObject((RMetaObject)args[0], (RMetaObject)r);
+ return r;
+ }
+ public static void IncludeModule(RMetaObject klass, RMetaObject module)
+ {
+ bool changed = false;
+ if (module == null) return;
+ if (module == klass) return;
+ // call Check_Type if need
+
+ // what is the syncroot ?
+ RMetaObject c = klass;
+ while (module != null)
+ {
+ for (RMetaObject r = klass.super; r != null; r = r.super)
+ {
+ if (r is RIncClass &&
+ r.m_tbl == module.m_tbl)
+ {
+ c = r;
+ goto skip;
+ }
+ }
+ c.super = new RIncClass(module, c.super);
+ c = c.super;
+ changed = true;
+ skip:
+ module = module.super;
+ }
+ ////if (changed) klass.ruby.ClearCache();
+ }
+
+ private class InsMethods
+ {
+ internal virtual string Inspect(NetRuby ruby, uint key, RNode body)
+ {
+ if ((body.noex & (NOEX.PRIVATE | NOEX.PROTECTED)) == 0)
+ {
+ if (body.body != null)
+ return ruby.id2name(key);
+ }
+ return null;
+ }
+ }
+ private class InsMethodsProtected : InsMethods
+ {
+ internal override string Inspect(NetRuby ruby, uint key, RNode body)
+ {
+ if (body.body != null && (body.noex & (NOEX.PROTECTED)) != 0)
+ {
+ return ruby.id2name(key);
+ }
+ return null;
+ }
+ }
+ private class InsMethodsPrivate : InsMethods
+ {
+ internal override string Inspect(NetRuby ruby, uint key, RNode body)
+ {
+ if (body.body != null && (body.noex & (NOEX.PRIVATE)) != 0)
+ {
+ return ruby.id2name(key);
+ }
+ return null;
+ }
+ }
+ public override RArray SingletonMethods
+ {
+ get {
+ ArrayList ary = new ArrayList();
+ RMetaObject klass = this;
+ InsMethods ins = new InsMethods();
+ while (klass != null && klass.Test(FL.SINGLETON))
+ {
+ lock (klass.m_tbl.SyncRoot)
+ {
+ foreach (DictionaryEntry ent in klass.m_tbl)
+ {
+ string s = ins.Inspect(ruby, (uint)ent.Key, (RNode)ent.Value);
+ if (s != null && ary.Contains(s) == false)
+ {
+ ary.Add(s);
+ }
+ }
+ }
+ klass = klass.super;
+ }
+ return new RArray(ruby, ary);
+ }
+ }
+ public virtual RArray ClassInstanceMethods(object[] argv)
+ {
+ object[] inherited_too = new object[1];
+ ruby.ScanArgs(argv, "01", inherited_too);
+ return MethodList(RTest(inherited_too[0]), new InsMethods());
+ }
+ public virtual RArray ClassProtectedInstanceMethods(object[] argv)
+ {
+ object[] inherited_too = new object[1];
+ ruby.ScanArgs(argv, "01", inherited_too);
+ return MethodList(RTest(inherited_too[0]), new InsMethodsProtected());
+ }
+ public virtual RArray ClassPrivateInstanceMethods(object[] argv)
+ {
+ object[] inherited_too = new object[1];
+ ruby.ScanArgs(argv, "01", inherited_too);
+ return MethodList(RTest(inherited_too[0]), new InsMethodsPrivate());
+
+ }
+ private RArray MethodList(bool inherited_too, InsMethods ins)
+ {
+ ArrayList ary = new ArrayList();
+ lock (this)
+ {
+ for (RMetaObject klass = this; klass != null; klass = klass.super)
+ {
+ foreach (DictionaryEntry entry in klass.m_tbl)
+ {
+ ////string s = ins.Inspect(ruby, (uint)entry.Key, (RNode)entry.Value);
+ RCMethod m = (RCMethod)entry.Value;
+ string s = m.Name;
+ if (s != null && ary.Contains(s) == false)
+ {
+ ary.Add(s);
+ }
+ }
+ if (inherited_too == false) break;
+ }
+ }
+ return new RArray(ruby, ary);
+ }
+ public object AppendFeatures(object o)
+ {
+
+ if (o is RMetaObject == false)
+ {
+ ruby.CheckType(o, typeof(RClass));
+ }
+
+ IncludeModule((RMetaObject)o, this);
+ return this;
+ }
+ public object Include(object[] args)
+ {
+ uint id = ruby.intern("append_features");
+ for (int i = 0; i < args.Length; i++)
+ {
+ ruby.CheckType(args[i], typeof(RModule));
+ ruby.Funcall(args[i], id, this);
+ }
+ return this;
+ }
+ private void ExportMethod(uint name, NOEX noex)
+ {
+/*
+ if (this == ruby.cObject)
+ {
+ ruby.Secure(4);
+ }
+ RMetaObject origin;
+ RNode body = SearchMethod(name, out origin);
+ if (body == null && this is RModule)
+ {
+ body = ruby.cObject.SearchMethod(name, out origin);
+ }
+ if (body == null)
+ {
+ printUndef(name);
+ }
+ if (body.noex != noex)
+ {
+ if (this == origin)
+ {
+ body.noex = noex;
+ }
+ else
+ {
+ ruby.ClearCache(name);
+ addMethod(name, new RNZSuper(ruby.GetCurrentContext(), ruby), noex);
+ }
+ }
+*/
+ }
+ private void SetMethodVisibility(object[] args, NOEX ex)
+ {
+ ////ruby.SecureVisibility(this);
+ for (int i = 0; i < args.Length; i++)
+ {
+ ExportMethod(ruby.ToID(args[i]), ex);
+ }
+ }
+ public object Public(params object[] args)
+ {
+ ////ruby.SecureVisibility(this);
+ RThread th = ruby.GetCurrentContext();
+ if (args == null || args.Length == 0)
+ {
+ th.ScopeSet(Scope.ScopeMode.Public);
+ }
+ else
+ {
+ SetMethodVisibility(args, NOEX.PUBLIC);
+ }
+ return this;
+ }
+ public object Protected(params object[] args)
+ {
+ ////ruby.SecureVisibility(this);
+ RThread th = ruby.GetCurrentContext();
+ if (args == null || args.Length == 0)
+ {
+ th.ScopeSet(Scope.ScopeMode.Protected);
+ }
+ else
+ {
+ SetMethodVisibility(args, NOEX.PROTECTED);
+ }
+ return this;
+ }
+ public object Private(params object[] args)
+ {
+ ////ruby.SecureVisibility(this);
+ RThread th = ruby.GetCurrentContext();
+ if (args == null || args.Length == 0)
+ {
+ th.ScopeSet(Scope.ScopeMode.Private);
+ }
+ else
+ {
+ SetMethodVisibility(args, NOEX.PRIVATE);
+ }
+ return this;
+ }
+ public RMetaObject ModuleFunction(params object[] argv)
+ {
+/*
+ if (this is RModule == false)
+ throw new eTypeError("module_function must be called for modules");
+ ////ruby.SecureVisibility(this);
+ RThread th = ruby.GetCurrentContext();
+ if (argv == null || argv.Length == 0)
+ {
+ th.ScopeSet(Scope.ScopeMode.ModFunc);
+ return this;
+ }
+ SetMethodVisibility(argv, NOEX.PRIVATE);
+ for (int i = 0; i < argv.Length; i++)
+ {
+ uint id = ruby.ToID(argv[i]);
+ RMetaObject origin;
+ RNode body = SearchMethod(id, out origin);
+ if (body == null || body.body == null)
+ {
+ ruby.bug(String.Format("undefined method `{0}'; can't happen",
+ ruby.id2name(id)));
+ }
+ SingletonClass(this, ruby).addMethod(id, body.body, NOEX.PUBLIC);
+ ruby.Funcall(this, "singleton_method_added", Symbol.ID2SYM(id));
+ }
+*/
+ return this;
+ }
+
+ public bool Eqq(object o)
+ {
+ return ruby.InstanceOf(o).IsKindOf(this);
+ }
+ private RMetaObject ModCheck(object o)
+ {
+ if (o is RMetaObject == false)
+ {
+ throw new eTypeError("<=> requires Class or Module (" +
+ ruby.ClassOf(o).ClassName + " given)");
+ }
+ return (RMetaObject)o;
+ }
+ public int CompareTo(object o)
+ {
+ if (this == o) return 0;
+ RMetaObject r = ModCheck(o);
+ if (le(r)) return -1;
+ return 1;
+ }
+ public bool le(object o)
+ {
+ RMetaObject arg = ModCheck(o);
+ RMetaObject mod = this;
+ while (mod != null)
+ {
+ if (mod.m_tbl == arg.m_tbl)
+ return true;
+ mod = mod.super;
+ }
+ return false;
+ }
+ public bool lt(object o)
+ {
+ if (this == o) return false;
+ return le(o);
+ }
+ public bool ge(object o)
+ {
+ RMetaObject arg = ModCheck(o);
+ return arg.le(this);
+ }
+ public bool gt(object o)
+ {
+ if (this == o) return false;
+ return ge(o);
+ }
+ public RArray IncludedModules()
+ {
+ ArrayList a = new ArrayList();
+ for (RMetaObject p = super; p != null; p = p.super)
+ {
+ if (p is RIncClass) a.Add(p.klass);
+ }
+ return new RArray(ruby, a);
+ }
+
+ public void DefineModuleFunction(string name, MethodInfo mi)
+ {
+ DefinePrivateMethod(name, mi);
+ DefineSingletonMethod(name, mi);
+ }
+ public void DefineModuleFunction(string name, RMethod rm, int argc)
+ {
+ DefinePrivateMethod(name, rm, argc);
+ DefineSingletonMethod(name, rm, argc);
+ }
+ public void DefinePrivateMethod(string name, MethodInfo mi)
+ {
+ addMethod(name, mi, NOEX.PRIVATE | NOEX.CFUNC);
+ }
+ public void DefinePrivateMethod(string name, RMethod rm, int argc)
+ {
+ addMethod(name, rm, argc, NOEX.PRIVATE | NOEX.CFUNC);
+ }
+ public void DefineProtectedMethod(string name, MethodInfo mi)
+ {
+ addMethod(name, mi, NOEX.PROTECTED | NOEX.CFUNC);
+ }
+ public void DefineProtectedMethod(string name, RMethod rm, int argc)
+ {
+ addMethod(name, rm, argc, NOEX.PROTECTED | NOEX.CFUNC);
+ }
+ public void DefineMethod(string name, MethodInfo mi)
+ {
+ addMethod(name, mi,
+ ((name == "initialize") ? NOEX.PRIVATE : NOEX.PUBLIC) | NOEX.CFUNC);
+ }
+
+ public void DefineMethod(string name, RCMethod rm)
+ {
+ m_tbl[name] = rm;
+ }
+
+ public void DefineMethod(string name, RMethod rm, int argc)
+ {
+ AddMethodCheck();
+ NOEX accs = ((name == "initialize") ? NOEX.PRIVATE : NOEX.PUBLIC) | NOEX.CFUNC;
+ addMethod(name, rm, argc, accs);
+ }
+/*
+ protected void addMethod(string name, RMethod rm, int argc, NOEX noex)
+ {
+ RNode func = new RNRFunc(ruby, rm, argc);
+ RNode body = new RNMethod(func, noex);
+#if INIT_DEBUG
+ System.Console.WriteLine("AddMethod for " + ToString() + ", " + name + "(" + ruby.intern(name).ToString() + ")");
+#endif
+ lock (m_tbl.SyncRoot)
+ {
+ m_tbl[ruby.intern(name)] = body;
+ }
+ }
+*/
+
+ protected void addMethod(string name, RMethod rm, int argc, NOEX noex)
+ {
+ //Console.WriteLine("addMethod " + rm.Method.DeclaringType.Name + "." + rm.Method.Name);
+ m_tbl[name] = new RDelegateMethod(ruby, name, rm);
+ }
+
+ public static RBasic ConvertToRuby(NetRuby ruby, object v)
+ {
+ if(v is RBasic) {
+ return (RBasic)v;
+ } else if (v is int) {
+ return new RFixnum(ruby, (int)v);
+ } else if (v is bool) {
+ if((bool)v)
+ return new RTrue(ruby);
+ else
+ return new RFalse(ruby);
+ } else if (v is string) {
+ return new RString(ruby, (string)v);
+ } else if (v == null) {
+ return ruby.oNil;
+ } else {
+ throw new Exception("Illegal type to convert to Ruby object: " + v.GetType().Name);
+ }
+ }
+
+ class RDelegateMethod : RCMethod
+ {
+ NetRuby ruby;
+ RMethod method;
+
+ internal RDelegateMethod(NetRuby r, string n, RMethod m)
+ {
+ method = m;
+ ruby = r;
+ name = n;
+ }
+
+ public override RBasic Call(RThread th, RBasic self, RBasic[] args, RCBlock block)
+ {
+ th.PushLegacyBlock(block);
+ RBasic ret = RClass.ConvertToRuby(ruby, method(self, (object[])args));
+ th.PopLegacyBlock();
+ return ret;
+ }
+
+ public override string ToString()
+ {
+ return "<DelegateMethod: " + method.Method.DeclaringType.Name + "." + method.Method.Name + ">";
+ }
+ }
+
+ class RBuiltinMethod : RCMethod
+ {
+ NetRuby ruby;
+ MethodInfo method_info;
+
+ internal RBuiltinMethod(NetRuby r, MethodInfo mi)
+ {
+ ruby = r;
+ method_info = mi;
+ }
+
+ public override string ToString()
+ {
+ return "<BuiltinMethod: " + method_info.DeclaringType.Name + "." + method_info.Name + ">";
+ }
+
+ public override RBasic Call(RThread th, RBasic self, RBasic[] args, RCBlock block)
+ {
+ th.PushLegacyBlock(block);
+ /*
+ Console.WriteLine("Invoke " + method_info.Name + " self=" + self.GetType().Name + ":" + self.ToString());
+ Console.WriteLine("mi_type=" + method_info.DeclaringType.Name);
+ foreach(ParameterInfo p in method_info.GetParameters()) {
+ Console.WriteLine("mparam: " + p.ParameterType.Name);
+ }
+ foreach(RBasic r in args) {
+ Console.WriteLine("realparam: " + r.GetType().Name);
+ }
+ */
+
+ // return (RBasic)method_info.Invoke(null, new object[] { self, args });
+ ParameterInfo[] pi = method_info.GetParameters();
+ RBasic ret;