123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- todo:
- object genericgetattr is wrong. should be looking up bases, not types. dummy
- 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)
- genexpr with free vars test
- generator func repr test
- __builtin__ needs work
- test for __bases__ and __mro__ of list/str/dict/etc
- IfExp: a if a < b else b
- why aren't the methods in .js's actually method? (have to pass 'self' to loadIdentity)
- final mode:
- make a build mode that compiles all py
- removes all goog.exportSymbol
- then compiles all resulting .js for final dist type builds
- generated code will make closure v unhappy right now though
- add line/col numbers to all error messages
- change .tp$name to ['$n'] so external module tpnames work
- ide:
- - load shaders
- - switch btwn files and set defaulttext
- - perspective matrix
- - matrix lib
- - basic procedural objects
- -------------------
- notes:
- both the type object's slots, and the tp_dict elements of a CPython
- typeobject are handled by the prototype object in js. ob$type, tp$xyz,
- sq$xyz, etc. correspond to slots, and non-$-containing ones are entries
- in tp$dict (that is methods, etc defined on the class).
- there is still a __dict__ object on instances (corresponding to dict at
- tp_dictoffset in CPython) which holds the attributes for the instance.
- these are not stored in the "object" js storage because objects in js
- are only string->obj, not obj->obj mappings. we might want to revisit
- that at some point, depending on whether anything other than strings
- really goes on the lhs. the __dict__ is accessible as inst.inst$dict on
- instances.
- having the prototype be the type object is slightly not good. when we
- want to get the type of a list, we do:
- listinst = []
- listinst.ob$type == list.prototype; // <- great
- listinst.ob$type.ob$type == list.prototype; // <- bad!
- we want the second one to be type.prototype because the type of the type
- of a list instance is infact 'type'. this is just a silly artifact of
- how javascript inheritance works: by copying that prototype object. so,
- if we make a new thing based on the object that's using that as its
- prototype, we can't tell the difference between the copy and the
- prototype itself.
- what if we made the type object for a list instance be a "new list()"
- i.e. based on the prototype, but then with its ob$type set?
- todo;;;
- prototype should contain pyfunction objects, not just typeof x ===
- 'function'. in lookup, the 'descr' from type lookup should be a function
- object so that it can get its ob$type (which would be the function type)
- would have a descriptor on it, so it can wrap (or not) the function into
- a bound method.
- ??? how does cpython work? they're obviously just regular c functions in the slots.
- -- ah. tp_methods is a list of the methods which is some data that gets
- wrapped into appropriate method objects on startup to build the type
- up.
- descriptor lookup:
- looking up 'name' on obj
- get obj.ob_type, pass to type_lookup (e.g. Sk.builtin.list.ob$type, which is basically the prototype obj of list)
- descr = obj.ob_type[name] (a builtin.func object)
- f = descr.ob_type.tp_descr_get
- result = f(descr, obj, obj.ob_type)
- so, the functions on list (say, 'extend') are actually descriptors
-
- SO!
- - for the builtin types, the 'slot' functions tp$stuff are just js
- functions. but, the accessible functions like list.extend are
- builtin.func's. that way they have the various methods, they have an
- ob$type, and they have a tp$descr_get which does appropriate binding.
- oh, ffs I hate JS.
- klass = new Object();
- klass.prototype.x = function(){};
- new klass();
- assigning keyword arguments:
- - place all positional into array
- - for each keyword, figure out what it's position would be
- - if there's nothing there, then insert
- - otherwise, throw TypeError multiple values
- Oh wait, no, that's dumb. We don't know the target we're calling so the
- binding has to be in the call not at the call site (though it could look
- in the function object that's being called.)
- So, just build up a list of name/value for keywords, and .call has to
- put them in the right place by looking at something. code obj? func obj?
- ------------
- closure binding:
- 1. need to handle converting from skulpt objects to js objects (for
- number, bool, string) maybe only handle those 3 and use something
- manual for others?
- 2. need to handle getting the return value to be an object that has a
- tp$getattr, so getting something out of it works
- 3. need to handle binding methods to their objects (creating something
- like a Sk.builtin.method) e.g. for g.drawRect
- 4. need to handle calling @constructor functions with 'new' because
- closure doesn't do return this; in its ctors.
- first 3 can do dynamically. there's no tag on ctors though, except in
- the comment annotations.
- - fork closure-compiler and generate a full set of wrappers offline?
- they could even be simple python
- seems like jsdoc-toolkit can handle parsing comments pretty well, seems
- like a reasonable approach. at least we could build a list of ctors.
- maybe do 1-3 dynamically, and just put ctors in a table and change .call
- to handle the 'new' stupid magic?
- can't quite build a useful table because all type objects won't be
- defined. could use string, but constructor.name is only the last and is
- non-standard anyway.
- here's a disgusting idea: after every goog.require() do
- if (goog && goog.ui && goog.ui.QueryData) goog.ui.QueryData.$isctor = true;
- for every one. blech.
- -----------
- ffi
- pretty simple with a helper .js file?
- - remap from dict <-> obj with helper
- - remap from long/number -> number and back
- - functions/methods can't just pass in the raw code object to js because
- they'll not have access to their globals. wrap a closure that calls
- tp$call around them.
- todo;
- more helpers for ffi
- verify that numbers are numbers, not longs (and maybe a compile mode to disable longs entirely?)
- ----------------
- bases and mro
- type(name, bases, dict)
- things are wrong with the ob$type vs. the actual JS type (i.e.
- Sk.builtin.object) vs the prototype.
- object is the name of a type. you can also call it, but that's pretty
- useless.
- trying to make the ctor function the type object means that the sneaky
- thing of putting the functions into the prototype so that they can be
- looked up as A.__init__ or a = A(); a.__init__() doesn't work because
- they would only be in one place.
- ------------------
- bespin:
- - python plugin for syntax hl doesn't work
- - can it do autoindent? i.e. indent after :?
- - home-home is wrong
- - ctrl-home/ctrl-end don't work
- - ctrl-arrow is wrong
- - pageup/down are wrong
- ===> Code Mirror is much better
- -----------------
- importing:
- - import is a statement, the load a create of a module has to happen
- synchronously so that it's available to the next line of code
- - xhrio is async, and without webworkers, can't be faked to be
- synchronous.
- - so, we have to pull all builtins/lib ahead of time, or otherwise pull
- from other sources, and then have all local code via a simple read that
- returns a string. since std lib is small this is ok for now. might have
- to subdivide it a bit eventually
- -----------------
- ah, damnit. closure is kind of a pain in the ass
- - trying to model type/object, so instances are types but types are
- also types, and type itself is also a type. but closure flattens
- everything that isn't a prototype. so Sk.builtin.object.inst$dict
- is getting flattened to just 'Sa', which means of course that when
- some generic code tries to look up something in an instance, or class,
- or the type type, there's no inst$dict.
- - maybe putting a non-function (i.e. inst$dict) in the .prototype,
- and then removing it from actual instances with a delete in the
- constructor?
- - or, switch to using ["$d"] or something instead of inst$dict. kind
- of sucks, but probably the easiest way.
- - blurgh. same for tp$repr, tp$name, ob$type just because of 'type'
- object. shit-tay. ['$r'] ['$n'] ['$t'] :(
- -----------------
- Test edit for review.
- -----------------
- # vim: set tw=72 formatoptions=croqln:
|