Skip to content

Commit

Permalink
First steps to getting better slicing support.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaspervdg committed Sep 26, 2013
1 parent 73ce2f1 commit 0c59316
Show file tree
Hide file tree
Showing 7 changed files with 412 additions and 7 deletions.
16 changes: 14 additions & 2 deletions src/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,16 @@ Compiler.prototype.cslice = function(s)
return this._gr('slice', "new Sk.builtins['slice'](", low, ",", high, ",", step, ")");
};

Compiler.prototype.eslice = function(dims)
{
goog.asserts.assert(dims instanceof Array);
var dimSubs = [], subs;
for(var i = 0; i < dims.length; i++) {
dimSubs.push(this.vslicesub(dims[i]));
}
return this._gr('extslice', "new Sk.builtins['tuple']([", dimSubs, "])");
};

Compiler.prototype.vslicesub = function(s)
{
var subs;
Expand All @@ -401,8 +411,10 @@ Compiler.prototype.vslicesub = function(s)
subs = this.cslice(s);
break;
case Ellipsis:
goog.asserts.fail("todo compile.js Ellipsis;");
break;
case ExtSlice:
goog.asserts.fail("todo;");
subs = this.eslice(s.dims);
break;
default:
goog.asserts.fail("invalid subscript kind");
Expand Down Expand Up @@ -537,7 +549,7 @@ Compiler.prototype.vexpr = function(e, data, augstoreval)
out("Sk.abstr.sattr(", val, ",'", mangled, "',", data, ");");
break;
case Del:
goog.asserts.fail("todo;");
goog.asserts.fail("todo Del;");
break;
case Param:
default:
Expand Down
16 changes: 12 additions & 4 deletions src/misceval.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Sk.misceval.asIndex = function(o)
if (typeof o === "number") return o;
if (o.constructor === Sk.builtin.nmber) return o.v;
if (o.constructor === Sk.builtin.lng) return o.tp$index();
goog.asserts.fail("todo;");
goog.asserts.fail("todo asIndex;");
};

/**
Expand Down Expand Up @@ -130,8 +130,16 @@ Sk.misceval.richCompareBool = function(v, w, op)
// v and w must be Python objects. will return Javascript true or false for internal use only
// if you want to return a value from richCompareBool to Python you must wrap as Sk.builtin.bool first

goog.asserts.assert((v !== null) && (v !== undefined), "passed undefined or null parameter to Sk.misceval.richCompareBool");
goog.asserts.assert((w !== null) && (w !== undefined), "passed undefined or null parameter to Sk.misceval.richCompareBool");
goog.asserts.assert(v !== undefined, "passed undefined parameter to Sk.misceval.richCompareBool");
goog.asserts.assert(w !== undefined, "passed undefined parameter to Sk.misceval.richCompareBool");

// Compare null as if it was None.
if (v === null) v = new Sk.builtin.none();
if (w === null) w = new Sk.builtin.none();

// Compare numbers as nmbers.
if (typeof v === "number") v = new Sk.builtin.nmber(v, undefined);
if (typeof w === "number") w = new Sk.builtin.nmber(w, undefined);

var v_type = new Sk.builtin.type(v);
var w_type = new Sk.builtin.type(w);
Expand Down Expand Up @@ -352,7 +360,7 @@ Sk.misceval.richCompareBool = function(v, w, op)
return v.v !== w.v;
return v !== w;
}

var vname = Sk.abstr.typeName(v);
var wname = Sk.abstr.typeName(w);
throw new Sk.builtin.ValueError("don't know how to compare '" + vname + "' and '" + wname + "'");
Expand Down
25 changes: 24 additions & 1 deletion src/slice.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
*/
Sk.builtin.slice = function slice(start, stop, step)
{
if (!(this instanceof Sk.builtin.slice)) return new Sk.builtin.slice(start, stop, step);
start = Sk.builtin.asnum$(start);
stop = Sk.builtin.asnum$(stop);
step = Sk.builtin.asnum$(step);
if (!(this instanceof Sk.builtin.slice)) return new Sk.builtin.slice(start, stop, step);

if (stop === undefined && step === undefined)
{
Expand All @@ -29,6 +29,8 @@ Sk.builtin.slice = function slice(start, stop, step)
throw new Sk.builtin.TypeError("slice indices must be integers or None");
}

this.__class__ = Sk.builtin.slice;

return this;
};

Expand All @@ -40,6 +42,27 @@ Sk.builtin.slice.prototype.tp$str = function()
return new Sk.builtin.str("slice(" + a + ", " + b + ", " + c + ")");
};

Sk.builtin.slice.prototype.tp$richcompare = function(w, op)
{
// w not a slice
if (!w.__class__ || w.__class__ != Sk.builtin.slice)
{
// shortcuts for eq/not
if (op === 'Eq') return false;
if (op === 'NotEq') return true;

// todo; other types should have an arbitrary order
return false;
}

// This is how CPython does it
var t1, t2;
t1 = new Sk.builtin.tuple([this.start,this.stop,this.step]);
t2 = new Sk.builtin.tuple([w.start,w.stop,w.step]);

return t1.tp$richcompare(t2, op);
};

Sk.builtin.slice.prototype.indices = function(length)
{
length = Sk.builtin.asnum$(length);
Expand Down
25 changes: 25 additions & 0 deletions test/run/t502.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class A:
def __getitem__(self, slices):
return slices

a = A()

print a[1]
print a[0:2]
print a[0,1:2]
print a[0:2,2:30:1]

assert(a[1]==1)
assert(a[0:2]==slice(0,2))
assert(a[0,1:2]==(0,slice(1,2)))
assert(a[0:2,2:30:1]==(slice(0,2), slice(2,30,1)))

# Python makes a distinction, not sure whether we need to: assert(slice(0,2)!=slice(2))
assert(slice(0,2) == slice(0,2))
assert(slice(0,2) < slice(1,2))
assert(slice(0,2) < slice(1,1))
assert(slice(1,2) < slice(1,2,3))
assert(slice(1,2,3) < slice(1,2,4))
assert(slice(1,-1) < slice(1,1))
assert(slice(0,1) < slice(1,-1))

4 changes: 4 additions & 0 deletions test/run/t502.py.real
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1
slice(0, 2, None)
(0, slice(1, 2, None))
(slice(0, 2, None), slice(2, 30, 1))
95 changes: 95 additions & 0 deletions test/run/t502.py.symtab
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
Sym_type: module
Sym_name: top
Sym_lineno: 0
Sym_nested: False
Sym_haschildren: True
-- Identifiers --
name: A
is_referenced: True
is_imported: False
is_parameter: False
is_global: False
is_declared_global: False
is_local: True
is_free: False
is_assigned: True
is_namespace: True
namespaces: [
Sym_type: class
Sym_name: A
Sym_lineno: 1
Sym_nested: False
Sym_haschildren: True
Class_methods: ['__getitem__']
-- Identifiers --
name: __getitem__
is_referenced: False
is_imported: False
is_parameter: False
is_global: False
is_declared_global: False
is_local: True
is_free: False
is_assigned: True
is_namespace: True
namespaces: [
Sym_type: function
Sym_name: __getitem__
Sym_lineno: 2
Sym_nested: False
Sym_haschildren: False
Func_params: ['self', 'slices']
Func_locals: ['self', 'slices']
Func_globals: []
Func_frees: []
-- Identifiers --
name: self
is_referenced: False
is_imported: False
is_parameter: True
is_global: False
is_declared_global: False
is_local: True
is_free: False
is_assigned: False
is_namespace: False
namespaces: [
]
name: slices
is_referenced: True
is_imported: False
is_parameter: True
is_global: False
is_declared_global: False
is_local: True
is_free: False
is_assigned: False
is_namespace: False
namespaces: [
]
]
]
name: a
is_referenced: True
is_imported: False
is_parameter: False
is_global: False
is_declared_global: False
is_local: True
is_free: False
is_assigned: True
is_namespace: False
namespaces: [
]
name: slice
is_referenced: True
is_imported: False
is_parameter: False
is_global: True
is_declared_global: False
is_local: False
is_free: False
is_assigned: False
is_namespace: False
namespaces: [
]
Loading

0 comments on commit 0c59316

Please sign in to comment.