PageRenderTime 63ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Backend/Modules/__builtin__.cs

https://bitbucket.org/AdamMil/boaold
C# | 1180 lines | 1038 code | 109 blank | 33 comment | 149 complexity | 0cdb72b8b605ac966b3e2601c2067f17 MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. Boa is the reference implementation for a language similar to Python,
  3. also called Boa. This implementation is both interpreted and compiled,
  4. targeting the Microsoft .NET Framework.
  5. http://www.adammil.net/
  6. Copyright (C) 2004-2005 Adam Milazzo
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. using System;
  20. using System.Collections;
  21. using Boa.AST;
  22. using Boa.Runtime;
  23. // TODO: make these functions conform to their docstrings
  24. // TODO: allow functions to return 'longint' if they'd overflow an 'int'
  25. // TODO: docstrings on fields and simple properties don't work because evaluating the attribute retrieves the value
  26. // TODO: implement reversed(): http://python.org/peps/pep-0322.html
  27. // TODO: make range() and xrange() work on arbitrary integers, not only int32s
  28. namespace Boa.Modules
  29. {
  30. [BoaType("module")]
  31. public sealed class __builtin__
  32. { __builtin__() { }
  33. #region EnumerateEnumerator
  34. public class EnumerateEnumerator : IEnumerator
  35. { public EnumerateEnumerator(IEnumerator e) { this.e = e; }
  36. public object Current
  37. { get
  38. { if(current==null) throw new InvalidOperationException();
  39. return current;
  40. }
  41. }
  42. public bool MoveNext()
  43. { if(!e.MoveNext()) { current=null; return false; }
  44. current = new Tuple(index++, e.Current);
  45. return true;
  46. }
  47. public void Reset()
  48. { e.Reset();
  49. index = 0;
  50. }
  51. IEnumerator e;
  52. Tuple current;
  53. int index;
  54. }
  55. #endregion
  56. #region SentinelEnumerator
  57. public class SentinelEnumerator : IEnumerator
  58. { public SentinelEnumerator(IEnumerator e, object sentinel) { this.e=e; this.sentinel=sentinel; }
  59. public object Current
  60. { get
  61. { if(done) throw new InvalidOperationException();
  62. return e.Current;
  63. }
  64. }
  65. public bool MoveNext()
  66. { if(!e.MoveNext() || Ops.Compare(e.Current, sentinel)==0) { done=true; return false; }
  67. return true;
  68. }
  69. public void Reset() { e.Reset(); done = false; }
  70. IEnumerator e;
  71. object sentinel;
  72. bool done;
  73. }
  74. #endregion
  75. #region Super
  76. [BoaType("super")]
  77. [DocString(@"super(type, [type-or-object])
  78. Return the superclass of type. If the second argument is omitted the super
  79. object returned is unbound. If the second argument is an object,
  80. isinstance(obj, type) must be true. If the second argument is a type,
  81. issubclass(type2, type) must be true. super() only works for new-style
  82. classes.
  83. A typical use for calling a cooperative superclass method is:
  84. class C(B):
  85. def meth(self, arg):
  86. super(C, self).meth(arg)")]
  87. public class Super : IHasAttributes
  88. { public Super(BoaType type) : this(type, null) { }
  89. public Super(BoaType type, object oot)
  90. { baseType=type;
  91. if(oot==null) mro = type.mro;
  92. else if(oot is BoaType) mro = ((BoaType)oot).mro;
  93. else if(oot!=null)
  94. { mro = ((BoaType)Ops.GetDynamicType(oot)).mro;
  95. obj = oot;
  96. }
  97. for(int i=0; i<mro.Count-1; i++) if(mro.items[i]==type) { index=i+1; return; }
  98. throw Ops.TypeError("'{0}' and '{1}' don't have a super() relationship", type.__name__,
  99. oot is DynamicType ? ((DynamicType)oot).__name__ : Ops.TypeName(oot));
  100. }
  101. public List __attrs__() { throw new NotSupportedException("calling __attrs__ on a 'super' object"); }
  102. public object __getattr__(string key) { return baseType.GetAttr(mro, index, obj, key); }
  103. public void __setattr__(string key, object value) { baseType.SetAttr(mro, index, obj, key, value); }
  104. public void __delattr__(string key) { baseType.DelAttr(mro, index, obj, key); }
  105. public override string ToString() { return string.Format("<super: {0}, {1}>", baseType, Ops.Str(obj)); }
  106. BoaType baseType;
  107. Tuple mro;
  108. int index;
  109. object obj;
  110. }
  111. #endregion
  112. #region Warnings
  113. public class Warning : Exception { public Warning(string message) : base(message) { } }
  114. public class UserWarning : Warning { public UserWarning(string message) : base(message) { } }
  115. public class DeprecationWarning : Warning { public DeprecationWarning(string message) : base(message) { } }
  116. public class PendingDeprecationWarning : Warning { public PendingDeprecationWarning(string message) : base(message) { } }
  117. public class SyntaxWarning : Warning { public SyntaxWarning(string message) : base(message) { } }
  118. public class RuntimeWarning : Warning { public RuntimeWarning(string message) : base(message) { } }
  119. public class FutureWarning : Warning { public FutureWarning(string message) : base(message) { } }
  120. #endregion
  121. #region XRange
  122. [BoaType("xrange")]
  123. [DocString(@"xrange([start,] stop[, step])
  124. This function is very similar to range(), but returns an 'xrange object'
  125. instead of a list. This is an opaque sequence type which yields the same
  126. values as the corresponding list, without actually storing them all
  127. simultaneously. xrange() is useful when when working with very large
  128. sequences or when many of a range's elements are never used.")]
  129. public class XRange : IEnumerable, ISequence, IRepresentable
  130. { public XRange(int stop) : this(0, stop, 1) { }
  131. public XRange(int start, int stop) : this(start, stop, 1) { }
  132. public XRange(int start, int stop, int step)
  133. { if(step==0) throw Ops.ValueError("step of 0 passed to xrange()");
  134. this.start=start; this.stop=stop; this.step=step;
  135. if(step<0 && start<=stop || step>0 && start>=stop) length = 0;
  136. else
  137. { int sign = Math.Sign(step);
  138. length = (stop-start+step-sign)/step;
  139. }
  140. }
  141. public override string ToString() { return __repr__(); }
  142. #region IEnumerable Members
  143. public IEnumerator GetEnumerator() { return new XRangeEnumerator(start, stop, step); }
  144. #endregion
  145. #region ISequence Members
  146. public object __add__(object o) { throw Ops.TypeError("xrange concatenation is not supported"); }
  147. public object __getitem__(int index) { return start + step*Ops.FixIndex(index, length); }
  148. public object __getitem__(Slice slice) { return Ops.SequenceSlice(this, slice); }
  149. public int __len__() { return length; }
  150. public bool __contains__(object value)
  151. { int val = Ops.ToInt(value);
  152. int index = (val-start)/step;
  153. if(index<0 || index>=length || index*step!=val-start) return false;
  154. return true;
  155. }
  156. #endregion
  157. #region IRepresentable Members
  158. public string __repr__() { return string.Format("xrange({0}, {1}, {2})", start, stop, step); }
  159. #endregion
  160. int start, stop, step, length;
  161. }
  162. public class XRangeEnumerator : IEnumerator
  163. { public XRangeEnumerator(int start, int stop, int step)
  164. { this.start=start; this.stop=stop; this.step=step; current=start-step;
  165. }
  166. public object Current
  167. { get
  168. { if(step<0)
  169. { if(current<=stop) throw new InvalidOperationException();
  170. }
  171. else if(current>=stop) throw new InvalidOperationException();
  172. return current;
  173. }
  174. }
  175. public bool MoveNext()
  176. { if(step<0)
  177. { if(current<=stop+step) return false;
  178. }
  179. else if(current>=stop-step) return false;
  180. current += step;
  181. return true;
  182. }
  183. public void Reset() { current=start-step; }
  184. internal int start, stop, step, current;
  185. }
  186. #endregion
  187. public static string __repr__() { return "<module '__builtin__' (built-in)>"; }
  188. public static string __str__() { return __repr__(); }
  189. public static MethodWrapper _method(IFancyCallable func) { return new MethodWrapper(func); }
  190. [DocString(@"abs(object) -> object
  191. Return the absolute value of a number. The argument may be a plain or long
  192. integer or a floating point number. If the argument is a complex number, its
  193. magnitude is returned.")]
  194. public static object abs(object o)
  195. { switch(Convert.GetTypeCode(o))
  196. { case TypeCode.Boolean: return (bool)o ? 1 : 0;
  197. case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: return o;
  198. case TypeCode.Decimal: return Math.Abs((Decimal)o);
  199. case TypeCode.Double: return Math.Abs((double)o);
  200. case TypeCode.Int16: return Math.Abs((short)o);
  201. case TypeCode.Int32: return Math.Abs((int)o);
  202. case TypeCode.Int64: return Math.Abs((long)o);
  203. case TypeCode.Object:
  204. if(o is Integer) return ((Integer)o).abs();
  205. if(o is Complex) return ((Complex)o).abs();
  206. return Ops.Invoke(o, "__abs__");
  207. case TypeCode.SByte: return Math.Abs((sbyte)o);
  208. case TypeCode.Single: return Math.Abs((float)o);
  209. default: throw Ops.TypeError("invalid operand type for abs(): got '{0}'", Ops.TypeName(o));
  210. }
  211. }
  212. [DocString(@"callable(object) -> bool
  213. Return true if the object argument appears callable, false if not. If this
  214. returns true, it is still possible that a call fails, but if it is false,
  215. calling object will never succeed. Note that classes are callable (calling
  216. a class returns a new instance); class instances are callable if they have
  217. a __call__() method.")]
  218. public static object callable(object o) { return o is ICallable ? Ops.TRUE : hasattr(o, "__call__"); }
  219. [DocString(@"chr(i) -> str
  220. Return a string of one character whose ASCII code is the integer passed.
  221. For example, chr(97) returns the string 'a'. This is the inverse of ord().")]
  222. public static string chr(int value) { return new string((char)value, 1); }
  223. [DocString(@"classmethod(function) -> function
  224. Return a class method for function.
  225. A class method receives the class as implicit first argument, just like an
  226. instance method receives the instance. To declare a class method, use this
  227. idiom:
  228. class C:
  229. def f(cls, arg1, arg2, ...): ...
  230. f = classmethod(f)
  231. It can be called either on the class (such as C.f()) or on an instance
  232. (such as C().f()). The instance is ignored except for its class. If a class
  233. method is called for a derived class, the derived class object is passed as
  234. the implied first argument.
  235. Class methods are different than C++ or Java static methods. If you want
  236. those, see staticmethod().")]
  237. public static Function classmethod(Function func) { return func.MakeMarked(FunctionType.Class); }
  238. [DocString(@"cmp(x, y) -> int
  239. Compare the two objects x and y and return an integer according to the
  240. outcome. The return value is negative if x<y, zero if x==y and strictly
  241. positive if x>y.")]
  242. public static int cmp(object a, object b) { return Ops.Compare(a, b); }
  243. // TODO: compile(string, filename, kind[, flags[, dont_inherit]])
  244. [DocString(@"delattr(object, name)
  245. This is a relative of setattr(). The arguments are an object and a string.
  246. The string must be the name of one of the object's attributes. The function
  247. deletes the named attribute, provided the object allows it. For example,
  248. delattr(x, 'foobar') is equivalent to del x.foobar.")]
  249. public static void delattr(object o, string name) { Ops.DelAttr(o, name); }
  250. // FIXME: dir() without args should return local variables, not module variables (but this is complicated)
  251. [DocString(@"dir([object]) -> list
  252. Without arguments, return the list of names in the current local symbol
  253. table. With an argument, attempts to return a list of valid attributes
  254. for that object. This information is gleaned from the object's __dict__
  255. attribute, if defined, and from the class or type object. The list is
  256. not necessarily complete. If the object is a module object, the list
  257. contains the names of the module's attributes. If the object is a type or
  258. class object, the list contains the names of its attributes, and recursively
  259. of the attributes of its bases. Otherwise, the list contains the object's
  260. attributes' names, the names of its class's attributes, and recursively of
  261. the attributes of its class's base classes. The resulting list is sorted
  262. alphabetically.")]
  263. public static List dir() { return dir(Ops.GetExecutingModule()); }
  264. public static List dir(object o)
  265. { List list = Ops.GetAttrNames(o);
  266. list.sort();
  267. return list;
  268. }
  269. // FIXME: make this conform to the docstring
  270. [DocString(@"divmod(a, b) -> object
  271. Take two (non complex) numbers as arguments and return a pair of numbers
  272. consisting of their quotient and remainder when using long division. With
  273. mixed operand types, the rules for binary arithmetic operators apply. For
  274. plain and long integers, the result is the same as (a / b, a % b). For
  275. floating point numbers the result is (q, a % b), where q is usually
  276. math.floor(a / b) but may be 1 less than that. In any case q * b + a % b
  277. is very close to a, if a % b is non-zero it has the same sign as b, and
  278. 0 <= abs(a % b) < abs(b).")]
  279. public static Tuple divmod(object a, object b) { return Ops.DivMod(a, b); }
  280. [DocString(@"enumerate(object) -> iter
  281. Return an enumerator object. The argument must be a sequence, an iterator,
  282. or some other object which supports iteration. The next() method of the
  283. iterator returned by enumerate() returns a tuple containing a count (from
  284. zero) and the corresponding value obtained from iterating over iterable.
  285. enumerate() is useful for obtaining an indexed series:
  286. (0, seq[0]), (1, seq[1]), (2, seq[2])")]
  287. public static IEnumerator enumerate(object o) { return new EnumerateEnumerator(Ops.GetEnumerator(o)); }
  288. [DocString(@"eval(expression[, globals[, locals]]) -> object
  289. The arguments are a string and two optional dictionaries. The expression
  290. argument is parsed and evaluated as a Boa expression using the globals and
  291. locals dictionaries as global and local name space. If the locals dictionary
  292. is omitted it defaults to the globals dictionary. If both dictionaries are
  293. omitted, the expression is executed in the environment where eval is called.
  294. The return value is the result of the evaluated expression. Syntax errors
  295. are reported as exceptions. Example:
  296. >>> x = 1
  297. >>> print eval('x+1')
  298. 2
  299. This function can also be used to execute arbitrary code objects (such as
  300. those created by compile()). In this case pass a code object instead of a
  301. string.
  302. Hints: dynamic execution of statements is supported by the exec statement.
  303. Execution of statements from a file is supported by the execfile() function.
  304. The globals() and locals() functions returns the current global and local
  305. dictionary, respectively, which may be useful to pass around for use by
  306. eval() or execfile().")]
  307. public static object eval(object expr) { return eval(expr, globals(), locals()); }
  308. public static object eval(object expr, IDictionary globals) { return eval(expr, globals, globals); }
  309. public static object eval(object expr, IDictionary globals, IDictionary locals)
  310. { Frame frame = new Frame(locals, globals);
  311. try
  312. { System.Threading.Monitor.Enter(Ops.Frames);
  313. Ops.Frames.Push(frame);
  314. if(expr is string) return Parser.FromString((string)expr).ParseExpression().Evaluate(frame);
  315. else throw new NotImplementedException();
  316. }
  317. finally
  318. { Ops.Frames.Pop();
  319. System.Threading.Monitor.Exit(Ops.Frames);
  320. }
  321. }
  322. [DocString(@"exec(code[, globals[, locals]])
  323. This function implements the exec statement. The arguments are an object
  324. and two optional dictionaries. The return value is null.
  325. 'code' should be either a string, an open file object, or a code object.
  326. If it is a string, the string is parsed as a suite of Python statements
  327. which is then executed (unless a syntax error occurs). If it is an open
  328. file, the file is parsed until EOF and executed. If it is a code object,
  329. it is simply executed.
  330. The execution uses the globals and locals dictionaries as the global and
  331. local namespaces. If the locals dictionary is omitted it defaults to the
  332. globals dictionary. If both dictionaries are omitted, the expression is
  333. executed in the environment where execfile() is called. The return value
  334. is null.
  335. Warning: The default locals act as described for function locals():
  336. modifications to the default locals dictionary should not be attempted.
  337. Pass an explicit locals dictionary if you need to see effects of the code on
  338. locals after function execfile() returns. exec() cannot be used reliably
  339. to modify a function's locals.")]
  340. public static void exec(object code) { exec(code, globals(), locals()); }
  341. public static void exec(object code, IDictionary globals) { exec(code, globals, globals); }
  342. public static void exec(object code, IDictionary globals, IDictionary locals)
  343. { Frame frame = new Frame(locals, globals);
  344. try
  345. { System.Threading.Monitor.Enter(Ops.Frames);
  346. Ops.Frames.Push(frame);
  347. if(code is string) Parser.FromString((string)code).Parse().Execute(frame);
  348. else throw new NotImplementedException();
  349. }
  350. finally
  351. { Ops.Frames.Pop();
  352. System.Threading.Monitor.Exit(Ops.Frames);
  353. }
  354. }
  355. [DocString(@"execfile(filename[, globals[, locals]])
  356. This function is similar to the exec statement, but parses a file instead of
  357. a string. It is different from the import statement in that it does not use
  358. the module administration -- it reads the file unconditionally and does not
  359. create a new module.
  360. The arguments are a file name and two optional dictionaries. The file is
  361. parsed and evaluated as a sequence of Boa statements (similarly to a module)
  362. using the globals and locals dictionaries as global and local namespace. If
  363. the locals dictionary is omitted it defaults to the globals dictionary. If
  364. both dictionaries are omitted, the expression is executed in the environment
  365. where execfile() is called. The return value is null.
  366. Warning: The default locals act as described for function locals():
  367. modifications to the default locals dictionary should not be attempted.
  368. Pass an explicit locals dictionary if you need to see effects of the code on
  369. locals after function execfile() returns. execfile() cannot be used reliably
  370. to modify a function's locals.")]
  371. public static void execfile(string filename) { execfile(filename, globals(), locals()); }
  372. public static void execfile(string filename, IDictionary globals) { execfile(filename, globals, globals); }
  373. public static void execfile(string filename, IDictionary globals, IDictionary locals)
  374. { Frame frame = new Frame(locals, globals);
  375. try
  376. { System.Threading.Monitor.Enter(Ops.Frames);
  377. Ops.Frames.Push(frame);
  378. Parser.FromFile(filename).Parse().Execute(frame);
  379. }
  380. finally
  381. { Ops.Frames.Pop();
  382. System.Threading.Monitor.Exit(Ops.Frames);
  383. }
  384. }
  385. [DocString(@"filter(function, sequence) -> sequence
  386. Construct a sequence from those elements of sequence for which function
  387. returns true. 'sequence' may be either a sequence, a container which
  388. supports iteration, or an iterator, If 'sequence' is a string or a tuple,
  389. the result also has that type; otherwise it is always a list. If function
  390. is null, the truth function is assumed, that is, all elements of list
  391. that are false (zero or empty) are removed.
  392. Note that filter(function, list) is equivalent to
  393. [item for item in list if function(item)] if function is not null and
  394. [item for item in list if item] if function is null.")]
  395. public static object filter(object function, object seq)
  396. { if(seq is string)
  397. { if(function==null) return seq;
  398. System.Text.StringBuilder sb = new System.Text.StringBuilder();
  399. string str = (string)seq;
  400. for(int i=0; i<str.Length; i++)
  401. if(Ops.IsTrue(Ops.Call(function, new string(str[i], 1)))) sb.Append(str[i]);
  402. return sb.ToString();
  403. }
  404. else
  405. { List ret;
  406. ICollection col = seq as ICollection;
  407. IEnumerator e;
  408. if(col!=null) { ret=new List(Math.Max(col.Count/2, 16)); e=col.GetEnumerator(); }
  409. else { ret=new List(); e=Ops.GetEnumerator(seq); }
  410. if(function==null)
  411. { while(e.MoveNext()) if(Ops.IsTrue(e.Current)) ret.append(e.Current);
  412. }
  413. else while(e.MoveNext()) if(Ops.IsTrue(Ops.Call(function, e.Current))) ret.append(e.Current);
  414. return seq is Tuple ? ret.ToTuple() : (object)ret;
  415. }
  416. }
  417. [DocString(@"getattr(object, name[, default]) -> object
  418. Return the value of the named attribute of an object. The name must be a
  419. string. If the string is the name of one of the object's attributes, the
  420. result is the value of that attribute. For example, getattr(x, 'foobar') is
  421. equivalent to x.foobar. If the named attribute does not exist, default is
  422. returned if provided, otherwise AttributeError is raised.")]
  423. public static object getattr(object o, string name) { return Ops.GetAttr(o, name); }
  424. public static object getattr(object o, string name, object defaultValue)
  425. { object ret;
  426. return Ops.GetAttr(o, name, out ret) ? ret : defaultValue;
  427. }
  428. [DocString(@"globals() -> dict
  429. Return a dictionary representing the current global symbol table. This is
  430. always the dictionary of the current module (inside a function or method,
  431. this is the module where it is defined, not the module from which it is
  432. called).")]
  433. public static IDictionary globals() { return Ops.GetExecutingModule().__dict__; }
  434. [DocString(@"hasattr(object, name) -> bool
  435. The arguments are an object and a string. The result is true if the string
  436. is the name of one of the object's attributes, false if not.")]
  437. public static object hasattr(object o, string name)
  438. { object dummy;
  439. return Ops.FromBool(Ops.GetAttr(o, name, out dummy));
  440. }
  441. // FIXME: python says: Numeric values that compare equal have the same hash value (even if they are of different types, as is the case for 1 and 1.0).
  442. [DocString(@"hash(object) -> int
  443. Return the hash value of the object (if it has one). Hash values are
  444. integers. They are used to quickly compare dictionary keys during a
  445. dictionary lookup.")]
  446. public static int hash(object o) { return o==null ? 0 : o.GetHashCode(); }
  447. [DocString(@"help([object])
  448. Invoke the built-in help system (intended for interactive use). If no
  449. argument is given, the interactive help system starts on the interpreter
  450. console. If the argument is a string, then the string is looked up as the
  451. name of a module, function, class, method, keyword, or documentation topic,
  452. and a help page is printed on the console. If the argument is any other kind
  453. of object, a help page on the object is generated.")]
  454. public static void help() { throw new NotImplementedException(); }
  455. public static void help(object o) { Console.Write(helptext(o)); }
  456. [DocString(@"hex(number) -> str
  457. Convert an integer number (of any size) to a hexadecimal string. The result
  458. is a valid Boa expression. Note: this always yields an unsigned literal.
  459. For example, on a 32-bit machine, hex(-1) yields '0xffffffff'. When
  460. evaluated on a machine with the same word size, this literal is evaluated
  461. as -1; at a different word size, it may turn up as a large positive number
  462. or raise an OverflowError exception.")]
  463. public static object hex(object o) // TODO: should this be implemented this way? or using Ops.ToInt() ?
  464. { if(o is int) return "0x" + ((int)o).ToString("x");
  465. if(o is long) return "0x" + ((long)o).ToString("x") + "L";
  466. return Ops.Invoke(o, "__hex__");
  467. }
  468. public static int id(object o) { throw new NotImplementedException(); }
  469. [DocString(@"input([prompt]) -> str
  470. If the prompt argument is present, it is written to standard output without
  471. a trailing newline. The function then reads a line from input, converts it
  472. to a string (stripping a trailing newline), and returns that. When EOF is
  473. read, EOFError is raised.")]
  474. public static string input() { return input(null); }
  475. public static string input(string prompt)
  476. { if(prompt!=null) Console.Write(prompt);
  477. string line = Console.ReadLine();
  478. if(line==null) throw Ops.EOFError("input() reached EOF");
  479. return line;
  480. }
  481. [DocString(@"intern(string) -> str
  482. Enters the given string into the 'interned' string table. Interned strings
  483. that compare equal will be shared. That is, they will be the same object.")]
  484. public static string intern(string s) { return string.Intern(s); }
  485. [DocString(@"isinstance(object, type) -> bool
  486. Return true if the object argument is an instance of the type argument,
  487. or of a (direct or indirect) subclass thereof. Also return true if type
  488. is a type object and object is an object of that type. If object is not a
  489. class instance or an object of the given type, the function always returns
  490. false. If type is neither a class object nor a type object, it may be
  491. a tuple of class or type objects, or may recursively contain other such
  492. tuples (other sequence types are not accepted). If type is not a class,
  493. type, or tuple of classes, types, and such tuples, a TypeError exception is
  494. raised.")]
  495. public static bool isinstance(object o, object type) { return issubclass(Ops.GetDynamicType(o), type); }
  496. [DocString(@"issubclass(type, parent) -> bool
  497. Return true if the type argument is a subclass (direct or indirect) of the
  498. parent argument. A class is considered a subclass of itself. The parent may
  499. be a tuple of class objects, or may recursively contain other such tuples
  500. (other sequence types are not accepted), in which case every entry in will
  501. be checked. In any other case, a TypeError exception is raised.")]
  502. public static bool issubclass(DynamicType type, object parentType)
  503. { Tuple tup = parentType as Tuple;
  504. if(tup==null) return type.IsSubclassOf(parentType);
  505. for(int i=0; i<tup.items.Length; i++) if(issubclass(type, tup.items[i])) return true;
  506. return false;
  507. }
  508. [DocString(@"len(object) -> int
  509. Return the length (the number of items) of an object. The argument may be a
  510. sequence (string, tuple or list) or a mapping (dictionary).")]
  511. public static int len(object o)
  512. { string s = o as string;
  513. if(s!=null) return s.Length;
  514. ICollection col = o as ICollection;
  515. if(col!=null) return col.Count;
  516. ISequence seq = o as ISequence;
  517. if(seq!=null) return seq.__len__();
  518. return Ops.ToInt(Ops.Invoke(o, "__len__"));
  519. }
  520. [DocString(@"locals() -> dict
  521. Update and return a dictionary representing the current local symbol table.
  522. Warning: The contents of this dictionary should not be modified; changes
  523. may not affect the values of local variables used by the interpreter.")]
  524. public static IDictionary locals() { throw new NotImplementedException(); }
  525. [DocString(@"map(function, seq1, ...) -> list
  526. Takes a function object (or null) and one or more sequences, and applies the
  527. function to the items of the sequences and return a list of the results. The
  528. function must take as many arguments as the number of sequences passed. The
  529. function will be applied to the items of all lists in parallel; if a list is
  530. shorter than another it is assumed to be extended with null items. If
  531. the function is null, the identity function is assumed; if there are multiple
  532. list arguments, map() returns a list consisting of tuples containing the
  533. corresponding items from all lists (a kind of transpose operation). The list
  534. arguments may be any kind of sequence; the result is always a list.")]
  535. public static List map(object function, object seq)
  536. { List ret;
  537. IEnumerator e;
  538. ICollection col = seq as ICollection;
  539. if(col!=null) { ret = new List(col.Count); e = col.GetEnumerator(); }
  540. else { ret = new List(); e = Ops.GetEnumerator(seq); }
  541. if(function==null) while(e.MoveNext()) ret.append(e.Current);
  542. else while(e.MoveNext()) ret.append(Ops.Call(function, e.Current));
  543. return ret;
  544. }
  545. public static List map(object function, params object[] seqs)
  546. { if(seqs.Length==0) throw Ops.TypeError("at least 2 arguments required to map");
  547. if(seqs.Length==1) return map(function, seqs[0]);
  548. List ret = new List();
  549. IEnumerator[] enums = new IEnumerator[seqs.Length];
  550. for(int i=0; i<enums.Length; i++) enums[i] = Ops.GetEnumerator(seqs[i]);
  551. object[] items = new object[enums.Length];
  552. bool done=false;
  553. while(true)
  554. { done=true;
  555. for(int i=0; i<enums.Length; i++)
  556. if(enums[i].MoveNext()) { items[i]=enums[i].Current; done=false; }
  557. else items[i]=null;
  558. if(done) break;
  559. ret.append(function==null ? new Tuple((object[])items.Clone()) : Ops.CallWithArgsSequence(function, items));
  560. }
  561. return ret;
  562. }
  563. [DocString(@"max(sequence) -> object
  564. max(value1, value1, ...) -> object
  565. With a single argument s, returns the largest item of a non-empty sequence
  566. (such as a string, tuple or list). With more than one argument, returns the
  567. largest of the arguments.")]
  568. public static object max(object sequence)
  569. { IEnumerator e = Ops.GetEnumerator(sequence);
  570. if(!e.MoveNext()) throw Ops.ValueError("sequence is empty");
  571. object ret = e.Current;
  572. while(e.MoveNext()) if(Ops.IsTrue(Ops.More(e.Current, ret))) ret = e.Current;
  573. return ret;
  574. }
  575. public static object max(object a, object b) { return Ops.IsTrue(Ops.More(a, b)) ? a : b; }
  576. public static object max(params object[] args)
  577. { if(args.Length==0) throw Ops.TooFewArgs("max()", 1, 0);
  578. object ret = args[0];
  579. for(int i=1; i<args.Length; i++) if(Ops.IsTrue(Ops.More(args[i], ret))) ret = args[i];
  580. return ret;
  581. }
  582. [DocString(@"min(sequence) -> object
  583. min(value1, value2, ...) -> object
  584. With a single argument s, returns the smallest item of a non-empty sequence
  585. (such as a string, tuple or list). With more than one argument, returns the
  586. smallest of the arguments.")]
  587. public static object min(object sequence)
  588. { IEnumerator e = Ops.GetEnumerator(sequence);
  589. if(!e.MoveNext()) throw Ops.ValueError("sequence is empty");
  590. object ret = e.Current;
  591. while(e.MoveNext()) if(Ops.IsTrue(Ops.Less(e.Current, ret))) ret = e.Current;
  592. return ret;
  593. }
  594. public static object min(object a, object b) { return Ops.IsTrue(Ops.Less(a, b)) ? a : b; }
  595. public static object min(params object[] args)
  596. { if(args.Length==0) throw Ops.TooFewArgs("min()", 1, 0);
  597. object ret = args[0];
  598. for(int i=1; i<args.Length; i++) if(Ops.IsTrue(Ops.Less(args[i], ret))) ret = args[i];
  599. return ret;
  600. }
  601. [DocString(@"oct(value) -> str
  602. Convert an integer number (of any size) to an octal string. The result is a
  603. valid Boa expression. Note: this always yields an unsigned literal. For
  604. example, on a 32-bit machine, oct(-1) yields '037777777777'. When evaluated
  605. on a machine with the same word size, this literal is evaluated as -1; at a
  606. different word size, it may turn up as a large positive number or raise an
  607. OverflowError exception.")]
  608. public static object oct(object o)
  609. { throw new NotImplementedException();
  610. return Ops.Invoke(o, "__oct__");
  611. }
  612. [DocString(@"open(filename[, mode[, bufsize]])
  613. This function has been superceded by the file object constructor.
  614. See the documentation for 'file'.")]
  615. public static BoaFile open(string filename) { return new BoaFile(filename); }
  616. public static BoaFile open(string filename, string mode) { return new BoaFile(filename, mode); }
  617. public static BoaFile open(string filename, string mode, int bufsize)
  618. { return new BoaFile(filename, mode, bufsize);
  619. }
  620. [DocString(@"ord(char) -> int
  621. Return the ASCII value of a string of one character. Eg, ord('a') returns
  622. the integer 97, ord('\u2020') returns 8224. This is the inverse of chr().")]
  623. public static int ord(string s)
  624. { if(s.Length!=1) throw Ops.TypeError("ord() expected a character but got string of length {0}", s.Length);
  625. return (int)s[0];
  626. }
  627. public static int ord(char c) { return (int)c; }
  628. [DocString(@"pow(x, y[, z]) -> object
  629. Returns x to the power y; if z is present, returns x to the power y,
  630. modulo z (possibly computed more efficiently than pow(x, y) % z). The
  631. arguments must have numeric types. With mixed operand types, the coercion
  632. rules for binary arithmetic operators apply. For int and long int operands,
  633. the result has the same type as the operands (after coercion) unless the
  634. second argument is negative; in that case, all arguments are converted to
  635. float and a float result is delivered. For example, 10**2 returns 100,
  636. but 10**-2 returns 0.01.")]
  637. public static object pow(object value, object power) { return Ops.Power(value, power); }
  638. public static object pow(object value, object power, object mod) { return Ops.PowerMod(value, power, mod); }
  639. [DocString(@"range([start,] stop[, step]) -> list
  640. This is a versatile function to create lists containing arithmetic
  641. progressions. It is most often used in for loops. The arguments must be
  642. plain integers. If the step argument is omitted, it defaults to 1. If the
  643. start argument is omitted, it defaults to 0. The full form returns a list
  644. of plain integers [start, start + step, start + 2 * step, ...]. If step is
  645. positive, the last element is the largest start + i * step less than stop;
  646. if step is negative, the last element is the largest start + i * step
  647. greater than stop. step must not be zero (or else ValueError is raised).
  648. Example:
  649. >>> range(10)
  650. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  651. >>> range(1, 11)
  652. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  653. >>> range(0, 30, 5)
  654. [0, 5, 10, 15, 20, 25]
  655. >>> range(0, 10, 3)
  656. [0, 3, 6, 9]
  657. >>> range(0, -10, -1)
  658. [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
  659. >>> range(0)
  660. []
  661. >>> range(1, 0)
  662. []")]
  663. public static List range(int stop) { return range(0, stop, 1); }
  664. public static List range(int start, int stop) { return range(start, stop, 1); }
  665. public static List range(int start, int stop, int step)
  666. { if(step==0) throw Ops.ValueError("step of 0 passed to range()");
  667. if(step<0 && start<=stop || step>0 && start>=stop) return new List();
  668. int sign = Math.Sign(step);
  669. List ret = new List((stop-start+step-sign)/step);
  670. for(; start<stop; start += step) ret.append(start);
  671. return ret;
  672. }
  673. [DocString(@"reduce(function, sequence[, initializer]) -> object
  674. Apply function of two arguments cumulatively to the items of sequence, from
  675. left to right, so as to reduce the sequence to a single value. For example,
  676. reduce(lambda x,y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). The
  677. left argument, x, is the accumulated value and the right argument, y, is the
  678. update value from the sequence. If the optional initializer is present, it
  679. is placed before the items of the sequence in the calculation, and serves as
  680. a default when the sequence is empty. If initializer is not given and
  681. sequence contains only one item, the first item is returned.")]
  682. public static object reduce(object function, object seq)
  683. { IEnumerator e = Ops.GetEnumerator(seq);
  684. if(!e.MoveNext()) throw Ops.TypeError("reduce() of empty sequence with no initial value");
  685. object ret = e.Current;
  686. while(e.MoveNext()) ret = Ops.Call(function, ret, e.Current);
  687. return ret;
  688. }
  689. public static object reduce(object function, object seq, object initial)
  690. { IEnumerator e = Ops.GetEnumerator(seq);
  691. while(e.MoveNext()) initial = Ops.Call(function, initial, e.Current);
  692. return initial;
  693. }
  694. public static Module reload(Module module) { throw new NotImplementedException(); }
  695. [DocString(@"repr(object) -> str
  696. Return a string containing a printable representation of an object. This is
  697. the same value yielded by conversions (reverse quotes). It is sometimes
  698. useful to be able to access this operation as an ordinary function. For many
  699. types, this function makes an attempt to return a string that would yield an
  700. object with the same value when passed to eval().")]
  701. public static string repr(object o) { return Ops.Repr(o); }
  702. [DocString(@"round(x[, n]) -> float
  703. Returns the floating point value x rounded to n digits after the decimal
  704. point. If n is omitted, it defaults to zero. The result is a floating point
  705. number. Values are rounded to the closest multiple of 10 to the power minus
  706. n; if two multiples are equally close, rounding is done away from odd
  707. integers (so, for example, both 1.5 and 2.5 round to 2.0).")]
  708. public static double round(double value) { return Math.Round(value); }
  709. public static double round(double value, int ndigits)
  710. { if(ndigits<0)
  711. { double factor = Math.Pow(10, -ndigits);
  712. return factor*Math.Round(value/factor);
  713. }
  714. return Math.Round(value, Math.Min(ndigits, 15));
  715. }
  716. [DocString(@"setattr(object, name, value)
  717. This is the counterpart of getattr(). The arguments are an object, a string
  718. and an arbitrary value. The string may name an existing attribute or a new
  719. attribute. The function assigns the value to the attribute, provided the
  720. object allows it. For example, setattr(x, 'foobar', 123) is equivalent to
  721. x.foobar = 123.")]
  722. public static void setattr(object o, string name, object value) { Ops.SetAttr(value, o, name); }
  723. [DocString(@"staticmethod(function) -> function
  724. Return a static method for function.
  725. A static method does not receive an implicit first argument. To declare a
  726. static method, use this idiom:
  727. class C:
  728. def f(arg1, arg2, ...): ...
  729. f = staticmethod(f)
  730. It can be called either on the class (such as C.f()) or on an instance
  731. (such as C().f()). The instance is ignored except for its class.
  732. Static methods in Python are similar to those found in Java or C++. For a
  733. more advanced concept, see classmethod().")]
  734. public static Function staticmethod(Function func) { return func.MakeMarked(FunctionType.Static); }
  735. [DocString(@"str([object]) -> str
  736. Return a string containing a nicely printable representation of an object.
  737. For strings, this returns the string itself. The difference with
  738. repr(object) is that str(object) does not always attempt to return a string
  739. that is acceptable to eval(); its goal is to return a printable string. If
  740. no argument is given, returns the empty string, ''.")]
  741. public static string str() { return string.Empty; }
  742. public static string str(object o) { return Ops.Str(o); }
  743. [DocString(@"sum(sequence[, start]) -> object
  744. Sums start and the items of a sequence, from left to right, and returns the
  745. total. start defaults to 0. The sequence's items are normally numbers, but
  746. could be strings. However, the fast, correct way to concatenate sequence of
  747. strings is by calling string.join(). Note that sum(range(n), m) is equivalent
  748. to reduce(operator.add, range(n), m).")]
  749. public static object sum(object seq) { return sum(seq, 0); }
  750. public static object sum(object seq, object start)
  751. { IEnumerator e = Ops.GetEnumerator(seq);
  752. while(e.MoveNext()) start = Ops.Add(start, e.Current);
  753. return start;
  754. }
  755. [DocString(@"type(object) -> type
  756. Returns the type of an object. The return value is a type object.")]
  757. public static DynamicType type(object obj) { return Ops.GetDynamicType(obj); }
  758. // TODO: vars()
  759. [DocString(@"zip(seq1, ...) -> list
  760. This function returns a list of tuples, where the i-th tuple contains the
  761. i-th element from each of the argument sequences. At least one sequence is
  762. required, otherwise a TypeError is raised. The returned list is truncated
  763. in length to the length of the shortest argument sequence. When there are
  764. multiple argument sequences which are all of the same length, zip() is
  765. similar to map() with an initial argument of null. With a single sequence
  766. argument, it returns a list of 1-tuples.")]
  767. public static List zip(params object[] seqs)
  768. { if(seqs.Length==0) throw Ops.TypeError("zip() requires at least one sequence");
  769. List ret = new List();
  770. IEnumerator[] enums = new IEnumerator[seqs.Length];
  771. for(int i=0; i<enums.Length; i++) enums[i] = Ops.GetEnumerator(seqs[i]);
  772. object[] items = new object[enums.Length];
  773. while(true)
  774. { for(int i=0; i<enums.Length; i++)
  775. if(!enums[i].MoveNext()) return ret;
  776. else items[i]=enums[i].Current;
  777. ret.append(new Tuple(items));
  778. }
  779. }
  780. [DocString(@"This value is set to the result of the last expression evaluated in
  781. interactive mode by the default sys.displayhook handler.")]
  782. public static object _;
  783. [DocString(@"This value is 1 when the interpreter/compiler is running in debug mode and
  784. 0 otherwise. Debug mode alters many facets of Boa's internal operation,
  785. including whether or not 'assert' statements will be executed. This value
  786. cannot be altered at runtime.")]
  787. public static int __debug__ { get { return Options.Debug ? 1 : 0; } }
  788. public static object exit = "Use Ctrl-Z plus Return (eg EOF) to exit.";
  789. public static object quit = "Use Ctrl-Z plus Return (eg EOF) to exit.";
  790. // TODO: figure out how to handle these types that collide with the functions
  791. // (perhaps by modifying ReflectedType.cons)
  792. #region Data types
  793. public static readonly ReflectedType @bool = ReflectedType.FromType(typeof(bool));
  794. public static readonly ReflectedType complex = ReflectedType.FromType(typeof(Complex));
  795. public static readonly ReflectedType dict = ReflectedType.FromType(typeof(Dict));
  796. public static readonly ReflectedType file = ReflectedType.FromType(typeof(BoaFile));
  797. public static readonly ReflectedType @float = ReflectedType.FromType(typeof(double));
  798. public static readonly ReflectedType @int = ReflectedType.FromType(typeof(int));
  799. public static readonly ReflectedType iter = ReflectedType.FromType(typeof(IEnumerator));
  800. public static readonly ReflectedType list = ReflectedType.FromType(typeof(List));
  801. public static readonly ReflectedType @long = ReflectedType.FromType(typeof(Integer));
  802. public static readonly ReflectedType @object = ReflectedType.FromType(typeof(object));
  803. public static readonly ReflectedType slice = ReflectedType.FromType(typeof(Slice));
  804. public static readonly ReflectedType @string = ReflectedType.FromType(typeof(string)); // FIXME: this should be 'str'
  805. public static readonly ReflectedType super = ReflectedType.FromType(typeof(Super));
  806. public static readonly ReflectedType tuple = ReflectedType.FromType(typeof(Tuple));
  807. public static readonly ReflectedType xrange = ReflectedType.FromType(typeof(XRange));
  808. #endregion
  809. // TODO: add the proper python base types to these (eg, IOError should derive from EnvironmentError)
  810. #region Exceptions
  811. public static readonly ReflectedType ApplicationError = ReflectedType.FromType(typeof(ApplicationException));
  812. public static readonly ReflectedType ArithmeticError = ReflectedType.FromType(typeof(ArithmeticException));
  813. public static readonly ReflectedType AssertionError = ReflectedType.FromType(typeof(AssertionErrorException));
  814. public static readonly ReflectedType EOFError = ReflectedType.FromType(typeof(System.IO.EndOfStreamException));
  815. public static readonly ReflectedType Exception = ReflectedType.FromType(typeof(Exception));
  816. public static readonly ReflectedType EnvironmentError = ReflectedType.FromType(typeof(EnvironmentErrorException));
  817. public static readonly ReflectedType FloatingPointError = ReflectedType.FromType(typeof(FloatingPointErrorException));
  818. public static readonly ReflectedType ImportError = ReflectedType.FromType(typeof(ImportErrorException));
  819. public static readonly ReflectedType IndexError = ReflectedType.FromType(typeof(IndexErrorException));
  820. public static readonly ReflectedType IOError = ReflectedType.FromType(typeof(System.IO.IOException));
  821. public static readonly ReflectedType KeyError = ReflectedType.FromType(typeof(KeyErrorException));
  822. public static readonly ReflectedType LookupError = ReflectedType.FromType(typeof(LookupErrorException));
  823. public static readonly ReflectedType MemoryError = ReflectedType.FromType(typeof(OutOfMemoryException));
  824. public static readonly ReflectedType NameError = ReflectedType.FromType(typeof(NameErrorException));
  825. public static readonly ReflectedType NotImplementedError = ReflectedType.FromType(typeof(NotImplementedException));
  826. public static readonly ReflectedType OSError = ReflectedType.FromType(typeof(OSErrorException));
  827. public static readonly ReflectedType OverflowError = ReflectedType.FromType(typeof(OverflowException));
  828. public static readonly ReflectedType RuntimeError = ReflectedType.FromType(typeof(RuntimeException));
  829. public static readonly ReflectedType StandardError = ReflectedType.FromType(typeof(StandardErrorException));
  830. public static readonly ReflectedType StopIteration = ReflectedType.FromType(typeof(StopIterationException));
  831. public static readonly ReflectedType SyntaxError = ReflectedType.FromType(typeof(SyntaxErrorException));
  832. public static readonly ReflectedType SystemExit = ReflectedType.FromType(typeof(SystemExitException));
  833. public static readonly ReflectedType TypeError = ReflectedType.FromType(typeof(TypeErrorException));
  834. public static readonly ReflectedType ValueError = ReflectedType.FromType(typeof(ValueErrorException));
  835. public static readonly ReflectedType ZeroDivisionError = ReflectedType.FromType(typeof(DivideByZeroException));
  836. #endregion
  837. [DocString(@"bool([x]) -> bool
  838. Convert a value to a Boolean, using the standard truth testing procedure.
  839. If x is false or omitted, this returns false; otherwise it returns true.")]
  840. internal static object _bool() { return Ops.FALSE; }
  841. internal static object _bool(object o) { return Ops.FromBool(Ops.IsTrue(o)); }
  842. [DocString(@"float([value]) -> float
  843. Convert a string or a number to floating point. If the argument is a string,
  844. it must contain a possibly signed decimal or floating point number, possibly
  845. embedded in whitespace. Otherwise, the argument may be a plain or long
  846. integer or a floating point number, and a floating point number with the same
  847. value (within Boa's floating point precision) is returned. If no argument is
  848. given, returns 0.")]
  849. internal static double _float() { return 0.0; }
  850. internal static double _float(object o) { return Ops.ToFloat(o); }
  851. [DocString(@"int([value[, radix]) -> int
  852. Convert a string or number to a plain integer. If the argument is a string,
  853. it must contain a possibly signed decimal number representable as a Boa
  854. integer, possibly embedded in whitespace. The radix parameter gives the base
  855. for the conversion, or zero. If radix is zero, the proper radix is guessed
  856. based on the contents of string; the interpretation is the same as for
  857. integer literals. If radix is specified and x is not a string, TypeError is
  858. raised. Otherwise, the argument may be a plain or long integer or a floating
  859. point number. Conversion of floating point numbers to integers truncates
  860. (towards zero). If the argument is outside the integer range a long object
  861. will be returned instead. If no arguments are given, returns 0.")]
  862. internal static int _int() { return 0; }
  863. internal static int _int(object o) { return Ops.ToInt(o); }
  864. internal static int _int(string s, int radix)
  865. { if(radix==0)
  866. { s = s.ToLower();
  867. if(s.IndexOf('.')!=-1 || s.IndexOf('e')!=-1) radix=10;
  868. else if(s.StartsWith("0x")) { radix=16; s=s.Substring(2); }
  869. else if(s.StartsWith("0")) radix=8;
  870. else radix=10;
  871. }
  872. try { return Convert.ToInt32(s, radix); }
  873. catch(FormatException) { throw Ops.ValueError("string does not contain a valid int"); }
  874. catch(OverflowException) { throw Ops.ValueError("too big for int"); }
  875. }
  876. [DocString(@"iter(object[, sentinel]) -> iter
  877. Return an iterator object. The first argument is interpreted very differently
  878. depending on the presence of the second argument. Without a second argument,
  879. the first argument must be a collection object which supports the iteration
  880. protocol (the __iter__() method), or it must support the sequence protocol
  881. (the __getitem__() method with integer arguments starting at 0). If it does
  882. not support either of those protocols, TypeError is raised. If the second
  883. argument, sentinel, is given, then the object must be callable. The iterator
  884. created in this case will call the object with no arguments for each call to
  885. its next() method; if the value returned is equal to sentinel, StopIteration
  886. will be raised, otherwise the value will be returned.")]
  887. internal static IEnumerator _iter(object o) { return Ops.GetEnumerator(o); }
  888. internal static IEnumerator _iter(object o, object sentinel)
  889. { return new SentinelEnumerator(Ops.GetEnumerator(o), sentinel);
  890. }
  891. internal static string helptext(object o) { return helptext(o, new System.Text.StringBuilder()); }
  892. static string helptext(object o, System.Text.StringBuilder sb)
  893. { object doc;
  894. string docstr;
  895. if(o is FunctionWrapper) o = ((FunctionWrapper)o).func;
  896. if(o==null) sb.Append("This is a null value.\n");
  897. else if(o is Function)
  898. { Function f = (Function)o;
  899. sb.Append("def ").Append(f.Name).Append('(');
  900. int i=0;
  901. for(; i<f.NumRequired; i++)
  902. { if(i!=0) sb.Append(", ");
  903. sb.Append(f.ParamNames[i]);
  904. }
  905. for(int j=0, end=f.ParamNames.Length-(f.HasDict?1:0)-(f.HasList?1:0); i<end; i++,j++)
  906. { if(i!=0) sb.Append(", ");
  907. sb.Append(f.ParamNames[i]).Append('=').Append(Ops.Repr(f.Defaults[j]));
  908. }
  909. if(f.HasList)
  910. { if(i++!=0) sb.Append(", ");
  911. sb.Append('*').Append(f.ParamNames[f.ParamNames.Length-(f.HasDict?2:1)]);
  912. }
  913. if(f.HasDict)
  914. { if(i!=0) sb.Append(", ");
  915. sb.Append("**").Append(f.ParamNames[f.ParamNames.Length-1]);
  916. }
  917. sb.Append("):\n");
  918. if(Ops.GetAttr(o, "__doc__", out doc) && doc!=null && (docstr=Ops.Str(doc))!="")
  919. sb.Append(docstr).Append('\n');
  920. }
  921. else if(Ops.GetAttr(o, "__doc__", out doc) && doc!=null && (docstr=Ops.Str(doc))!="")
  922. sb.Append(docstr).Append('\n');
  923. else if(o is ReflectedEvent)
  924. { ReflectedEvent re = (ReflectedEvent)o;
  925. sb.Append(re.info.Name).Append(" is an event that takes a ")
  926. .Append(TypeName(re.info.EventHandlerType)).Append(" object\n");
  927. helptext(ReflectedType.FromType(re.info.EventHandlerType), sb);
  928. }
  929. else if(o is ReflectedField)
  930. { ReflectedField rf = (ReflectedField)o;
  931. sb.Append(rf.info.Name).Append(" is a field of type ").Append(TypeName(rf.info.FieldType)).Append('\n');
  932. }
  933. else if(o is ReflectedMethodBase)
  934. { ReflectedMethodBase rm = (ReflectedMethodBase)o;
  935. foreach(System.Reflection.MethodBase mb i

Large files files are truncated, but you can click here to view the full file