Permalink
Browse files

Remove non-standard arg in shebang. Make the distinction between boos…

…trap-level and python-level more clear. Improve __getattribute__ and __setattr__.
  • Loading branch information...
1 parent e8fa404 commit d0a12338140b91477e6c0f4ea65e5726a745f7ff @lucian1900 committed Aug 1, 2011
View
0 bin/puffinc 100755 → 100644
No changes.
View
@@ -1,4 +1,4 @@
-#!/usr/bin/env winxed --nowarn
+#!/usr/bin/env winxed
using extern "io_ops";
@@ -7,17 +7,17 @@ function id(obj) {
}
function get_mro(cls) {
- var list = [cls];
-
- // add the classes in the first level
- for(var i in cls.__bases__)
- list.push(i);
-
- // recurse down
- for(var i in cls.__bases__)
- list.append(get_mro(i));
-
- return list;
+ var bases = cls.__dict__['__bases__'];
+ var result = [cls];
+
+ //say(typeof(bases));
+
+ for(int i=0; i < length(bases); i++) {
+ //say(i);
+ result.append(get_mro(bases[i]));
+ }
+
+ return result;
}
class instance {
@@ -30,23 +30,27 @@ class instance {
}
function invoke[vtable](var p [slurpy], var n [slurpy,named]) {
- var sub = self.__call__;
- if (self.__call__ == null) say('object not callable');
+ var sub;
- // if sub is a parrot sub, it'll get executed
- // if sub is an instance with __call__, this invoke will get called
- // all the way down to a sub
+ if(self.__class__ != null)
+ sub = self.__class__.__call__;
+
+ // if sub is a parrot Sub, it'll get executed
+ // if sub is an instance with __call__, this invoke will get called,
+ // all the way down to a Sub somewhere
return sub(p:[flat], n:[flat,named]);
}
-/*
+
function find_method[vtable](string name) {
- var fn = name;
-
- return function(obj, p[slurpy], n[slurpy,named]) {
-
- }
+ // likely broken
+ var method = self.__dict__[name];
+
+ // closure to soak up the obj
+ return function(var obj, var p[slurpy], var n[slurpy,named]) {
+ return method(p:[flat], n:[flat,named]);
+ };
}
-*/
+
function get_pmc_keyed_str[vtable,nsentry](string name) {
var dict;
var protoclass = class Python.instance;
@@ -56,15 +60,16 @@ class instance {
if(i == name && exists dict[i])
return dict[i];
- // let objects override it
+ // let object classes override it
+ // since this is only used for boostrapping, bases are ignored
if(exists dict['__class__']) {
- var mro = get_mro(dict['__class__']);
+ var cls = dict['__class__'];
- for(var i in mro)
- if(exists i.__dict__['__getattribute__'])
- return i.__dict__['__getattribute__'](self, name);
+ if(exists cls.__dict__['__getattribute__'])
+ return cls.__dict__['__getattribute__'](self, name);
}
+
//TODO check for missing
return dict[name];
}
@@ -74,14 +79,17 @@ class instance {
var protoclass = class Python.instance;
${ getattribute dict, self, protoclass, '__dict__' };
- // __dict__ short-circuit
- if(name == '__dict__')
- dict = value; //TODO use setattribute to swap dict
- // let objects override it
- else if(exists dict['__setattr__'])
- dict['__setattr__'](self, name, value);
- else
- dict[name] = value;
+ // let object classes override it
+ if(exists dict['__class__']) {
+ var cls = dict['__class__'];
+
+ if(exists cls.__dict__['__setattr__'])
+ cls.__dict__['__setattr__'](self, name, value);
+
+ return;
+ }
+
+ dict[name] = value;
}
function get_attr_str[vtable] (string name) {
@@ -9,7 +9,7 @@ function object(type) {
t.__name__ = 'object';
t.__module__ = 'builtins';
- type.__bases__.push(t);
+ type.__bases__ = [t];
t.__new__ = function(cls) {
var o = new Python.instance;
View
@@ -4,7 +4,6 @@ function type() {
var t = new Python.instance;
t.__class__ = t;
- t.__bases__ = [];
t.__name__ = 'type';
t.__module__ = 'builtins';
@@ -47,37 +46,56 @@ function type() {
t.__getattribute__ = function(obj, key) {
var cls = obj.__dict__['__class__'];
- //first try descriptor
+ // first try descriptor among class attrs
if(exists cls.__dict__[key]) {
var attr = cls.__dict__[key];
+
+ // if data-descriptor
+ if(exists attr.__dict__['__get__'] &&
+ exists attr.__dict__['__set__']) {
+ return attr.__dict__['__get__'](attr, obj);
+ }
+ }
- if(typeof(attr) == 'Python;instance' &&
- exists attr.__dict__['__get__']) {
+ // then attr on actual obj
+ if(exists obj.__dict__[key]) {
+ var attr = obj.__dict__[key];
- var descriptor = attr.__dict__['__get__'];
- return descriptor(attr, obj);
+ // if obj is a class
+ if(id(cls) == id(t)) {
+
+ // TODO check the class, also for descriptors
+ // TODO also check its bases
}
- }
- //TODO then descriptors of parents
- // then try instance
- if(exists obj.__dict__[key])
- return obj.__dict__[key];
+ return attr;
+ }
- // then class
- if(exists cls.__dict__[key])
- return cls.__dict__[key];
+ // then on the obj's class
+ // TODO also base classes
+ if(exists cls.__dict__[key]) {
+ var attr = cls.__dict__[key];
+
+ // if non-data descriptor
+ if(exists attr.__dict__['__get__'])
+ return attr.__dict__['__get__'](attr, obj);
- //TODO then parent classes
- for(var i in cls.__dict__['__bases__']) {
- if(exists i.__dict__[key])
- return i.__dict__[key];
+ return attr;
}
// throw AttributeError
};
t.__setattr__ = function(obj, key, val) {
+ var cls = obj.__dict__['__class__'];
+
+ if(exists cls.__dict__[key]) {
+ var attr = cls.__dict__[key];
+
+ if(exists attr.__dict__['__set__'])
+ attr.__dict__['__set__'](attr, obj, val);
+ }
+
obj.__dict__[key] = val;
};
View
@@ -2,6 +2,32 @@ $load 'rosella/test.pbc';
$load 'puffin/builtins.pbc';
class instance {
+ function get_mro() {
+ /* a, b, c, d are all classes
+ Inheritance chain looks like this"
+ d
+ | \
+ b c
+ \ |
+ a
+ */
+ var a = new Python.instance;
+ var b = new Python.instance;
+ var c = new Python.instance;
+ var d = new Python.instance;
+
+ d.__bases__ = [];
+ b.__bases__ = [d];
+ c.__bases__ = [c];
+ a.__bases__ = [b, c];
+
+ using Python.get_mro;
+ var mro = get_mro(a);
+ say(mro);
+
+ self.assert.equal(mro, [a, b, c, d]);
+ }
+
function set_get_attr() {
var i = new Python.instance;
i.a = 2;
@@ -16,29 +42,48 @@ class instance {
self.assert.equal(i.__bases__, [1, 2]);
}
- function getattribute() {
+ function get_attr_override() {
var i = new Python.instance;
- i.__getattribute__ = function(obj, name) {
+ var c = new Python.instance;
+
+ i.__class__ = c;
+
+ c.__getattribute__ = function(obj, name) {
return 42;
};
-
+
self.assert.equal(i.a, 42);
}
+
+ function set_attr_override() {
+ var i = new Python.instance;
+ var c = new Python.instance;
+
+ i.__class__ = c;
+
+ c.__setattr__ = function(obj, name, value) {
+ obj.__dict__[name] = 42;
+ };
+
+ i.a = 2;
+
+ self.assert.equal(i.a, 42);
+ }
function call_func() {
var i = new Python.instance;
i.b = function(){return 42;};
var func = i.b;
- self.assert.equal(func(), 42);
+ self.assert.equal(i.b(), 42);
}
function call_func_attr() {
var i = new Python.instance;
i.f = function(a, b){return a + b;};
var func = i.f;
- self.assert.equal(func(1, 2), 3);
+ self.assert.equal(i.f(1, 2), 3);
}
function get_string() {
@@ -50,14 +95,12 @@ class instance {
function call() {
var i = new Python.instance;
- i.__call__ = function(){return 42;};
+ var c = new Python.instance;
- self.assert.equal(i(), 42);
- }
+ i.__class__ = c;
+ c.__call__ = function(){return 42;};
- function get_mro() {
- self.status.unimplemented('writeme');
- using Python.get_mro;
+ self.assert.equal(i(), 42);
}
}
View
@@ -12,12 +12,29 @@ function boot() {
}
class type {
+
function boot() {
self.assert.throws_nothing(function(){
:(var t, var o) = boot();
});
}
+ function set_attr() {
+ :(var t, var o) = boot();
+
+ o.a = 42;
+ say(o.__dict__['__name__']);
+ self.assert.equal(o.__dict__['a'], 42);
+ }
+
+ function get_attr() {
+ :(var t, var o) = boot();
+
+ o.a = 42;
+ self.assert.equal(o.a, 42);
+ }
+
+
function type_init() {
:(var t, var o) = boot();
View
0 puffin/compiler.py 100755 → 100644
No changes.
View
0 setup.py 100755 → 100644
No changes.

0 comments on commit d0a1233

Please sign in to comment.