notes.txt 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. todo:
  2. object genericgetattr is wrong. should be looking up bases, not types. dummy
  3. make a type-name-getting function, rather than obj.tp$name so that number works (and it'd be a good error checking place too)
  4. genexpr with free vars test
  5. generator func repr test
  6. __builtin__ needs work
  7. test for __bases__ and __mro__ of list/str/dict/etc
  8. IfExp: a if a < b else b
  9. why aren't the methods in .js's actually method? (have to pass 'self' to loadIdentity)
  10. final mode:
  11. make a build mode that compiles all py
  12. removes all goog.exportSymbol
  13. then compiles all resulting .js for final dist type builds
  14. generated code will make closure v unhappy right now though
  15. add line/col numbers to all error messages
  16. change .tp$name to ['$n'] so external module tpnames work
  17. ide:
  18. - load shaders
  19. - switch btwn files and set defaulttext
  20. - perspective matrix
  21. - matrix lib
  22. - basic procedural objects
  23. -------------------
  24. notes:
  25. both the type object's slots, and the tp_dict elements of a CPython
  26. typeobject are handled by the prototype object in js. ob$type, tp$xyz,
  27. sq$xyz, etc. correspond to slots, and non-$-containing ones are entries
  28. in tp$dict (that is methods, etc defined on the class).
  29. there is still a __dict__ object on instances (corresponding to dict at
  30. tp_dictoffset in CPython) which holds the attributes for the instance.
  31. these are not stored in the "object" js storage because objects in js
  32. are only string->obj, not obj->obj mappings. we might want to revisit
  33. that at some point, depending on whether anything other than strings
  34. really goes on the lhs. the __dict__ is accessible as inst.inst$dict on
  35. instances.
  36. having the prototype be the type object is slightly not good. when we
  37. want to get the type of a list, we do:
  38. listinst = []
  39. listinst.ob$type == list.prototype; // <- great
  40. listinst.ob$type.ob$type == list.prototype; // <- bad!
  41. we want the second one to be type.prototype because the type of the type
  42. of a list instance is infact 'type'. this is just a silly artifact of
  43. how javascript inheritance works: by copying that prototype object. so,
  44. if we make a new thing based on the object that's using that as its
  45. prototype, we can't tell the difference between the copy and the
  46. prototype itself.
  47. what if we made the type object for a list instance be a "new list()"
  48. i.e. based on the prototype, but then with its ob$type set?
  49. todo;;;
  50. prototype should contain pyfunction objects, not just typeof x ===
  51. 'function'. in lookup, the 'descr' from type lookup should be a function
  52. object so that it can get its ob$type (which would be the function type)
  53. would have a descriptor on it, so it can wrap (or not) the function into
  54. a bound method.
  55. ??? how does cpython work? they're obviously just regular c functions in the slots.
  56. -- ah. tp_methods is a list of the methods which is some data that gets
  57. wrapped into appropriate method objects on startup to build the type
  58. up.
  59. descriptor lookup:
  60. looking up 'name' on obj
  61. get obj.ob_type, pass to type_lookup (e.g. Sk.builtin.list.ob$type, which is basically the prototype obj of list)
  62. descr = obj.ob_type[name] (a builtin.func object)
  63. f = descr.ob_type.tp_descr_get
  64. result = f(descr, obj, obj.ob_type)
  65. so, the functions on list (say, 'extend') are actually descriptors
  66. SO!
  67. - for the builtin types, the 'slot' functions tp$stuff are just js
  68. functions. but, the accessible functions like list.extend are
  69. builtin.func's. that way they have the various methods, they have an
  70. ob$type, and they have a tp$descr_get which does appropriate binding.
  71. oh, ffs I hate JS.
  72. klass = new Object();
  73. klass.prototype.x = function(){};
  74. new klass();
  75. assigning keyword arguments:
  76. - place all positional into array
  77. - for each keyword, figure out what it's position would be
  78. - if there's nothing there, then insert
  79. - otherwise, throw TypeError multiple values
  80. Oh wait, no, that's dumb. We don't know the target we're calling so the
  81. binding has to be in the call not at the call site (though it could look
  82. in the function object that's being called.)
  83. So, just build up a list of name/value for keywords, and .call has to
  84. put them in the right place by looking at something. code obj? func obj?
  85. ------------
  86. closure binding:
  87. 1. need to handle converting from skulpt objects to js objects (for
  88. number, bool, string) maybe only handle those 3 and use something
  89. manual for others?
  90. 2. need to handle getting the return value to be an object that has a
  91. tp$getattr, so getting something out of it works
  92. 3. need to handle binding methods to their objects (creating something
  93. like a Sk.builtin.method) e.g. for g.drawRect
  94. 4. need to handle calling @constructor functions with 'new' because
  95. closure doesn't do return this; in its ctors.
  96. first 3 can do dynamically. there's no tag on ctors though, except in
  97. the comment annotations.
  98. - fork closure-compiler and generate a full set of wrappers offline?
  99. they could even be simple python
  100. seems like jsdoc-toolkit can handle parsing comments pretty well, seems
  101. like a reasonable approach. at least we could build a list of ctors.
  102. maybe do 1-3 dynamically, and just put ctors in a table and change .call
  103. to handle the 'new' stupid magic?
  104. can't quite build a useful table because all type objects won't be
  105. defined. could use string, but constructor.name is only the last and is
  106. non-standard anyway.
  107. here's a disgusting idea: after every goog.require() do
  108. if (goog && goog.ui && goog.ui.QueryData) goog.ui.QueryData.$isctor = true;
  109. for every one. blech.
  110. -----------
  111. ffi
  112. pretty simple with a helper .js file?
  113. - remap from dict <-> obj with helper
  114. - remap from long/number -> number and back
  115. - functions/methods can't just pass in the raw code object to js because
  116. they'll not have access to their globals. wrap a closure that calls
  117. tp$call around them.
  118. todo;
  119. more helpers for ffi
  120. verify that numbers are numbers, not longs (and maybe a compile mode to disable longs entirely?)
  121. ----------------
  122. bases and mro
  123. type(name, bases, dict)
  124. things are wrong with the ob$type vs. the actual JS type (i.e.
  125. Sk.builtin.object) vs the prototype.
  126. object is the name of a type. you can also call it, but that's pretty
  127. useless.
  128. trying to make the ctor function the type object means that the sneaky
  129. thing of putting the functions into the prototype so that they can be
  130. looked up as A.__init__ or a = A(); a.__init__() doesn't work because
  131. they would only be in one place.
  132. ------------------
  133. bespin:
  134. - python plugin for syntax hl doesn't work
  135. - can it do autoindent? i.e. indent after :?
  136. - home-home is wrong
  137. - ctrl-home/ctrl-end don't work
  138. - ctrl-arrow is wrong
  139. - pageup/down are wrong
  140. ===> Code Mirror is much better
  141. -----------------
  142. importing:
  143. - import is a statement, the load a create of a module has to happen
  144. synchronously so that it's available to the next line of code
  145. - xhrio is async, and without webworkers, can't be faked to be
  146. synchronous.
  147. - so, we have to pull all builtins/lib ahead of time, or otherwise pull
  148. from other sources, and then have all local code via a simple read that
  149. returns a string. since std lib is small this is ok for now. might have
  150. to subdivide it a bit eventually
  151. -----------------
  152. ah, damnit. closure is kind of a pain in the ass
  153. - trying to model type/object, so instances are types but types are
  154. also types, and type itself is also a type. but closure flattens
  155. everything that isn't a prototype. so Sk.builtin.object.inst$dict
  156. is getting flattened to just 'Sa', which means of course that when
  157. some generic code tries to look up something in an instance, or class,
  158. or the type type, there's no inst$dict.
  159. - maybe putting a non-function (i.e. inst$dict) in the .prototype,
  160. and then removing it from actual instances with a delete in the
  161. constructor?
  162. - or, switch to using ["$d"] or something instead of inst$dict. kind
  163. of sucks, but probably the easiest way.
  164. - blurgh. same for tp$repr, tp$name, ob$type just because of 'type'
  165. object. shit-tay. ['$r'] ['$n'] ['$t'] :(
  166. -----------------
  167. Test edit for review.
  168. -----------------
  169. # vim: set tw=72 formatoptions=croqln: