Permalink
Browse files

Dart backend: translate operator overloading including inplace assign…

…ement operators to Dart.
  • Loading branch information...
hartsantler committed Dec 11, 2013
1 parent 5831872 commit 95ea574c1be979e202d8938d585ff8f8f936dd2c
Showing with 252 additions and 1 deletion.
  1. +30 −1 pythonjs/python_to_pythonjs.py
  2. +43 −0 pythonjs/pythonjs_to_dart.py
  3. +179 −0 tests/test_vector3_operator_overloading.html
@@ -506,7 +506,36 @@ def visit_AugAssign(self, node):
a = '%s = Math.floor(%s/%s)' %(target, target, self.visit(node.value))
writer.write(a)
- elif self._with_js or self._with_dart:
+ elif self._with_dart:
+ if op == '+=':
+ a = '%s.__iadd__(%s)' %(target, self.visit(node.value))
+ elif op == '-=':
+ a = '%s.__isub__(%s)' %(target, self.visit(node.value))
+ elif op == '*=':
+ a = '%s.__imul__(%s)' %(target, self.visit(node.value))
+ elif op == '/=':
+ a = '%s.__idiv__(%s)' %(target, self.visit(node.value))
+ elif op == '%=':
+ a = '%s.__imod__(%s)' %(target, self.visit(node.value))
+ elif op == '&=':
+ a = '%s.__iand__(%s)' %(target, self.visit(node.value))
+ elif op == '|=':
+ a = '%s.__ior__(%s)' %(target, self.visit(node.value))
+ elif op == '^=':
+ a = '%s.__ixor__(%s)' %(target, self.visit(node.value))
+ elif op == '<<=':
+ a = '%s.__ilshift__(%s)' %(target, self.visit(node.value))
+ elif op == '>>=':
+ a = '%s.__irshift__(%s)' %(target, self.visit(node.value))
+ else:
+ raise NotImplementedError
+
+ b = '%s %s %s' %(target, op, self.visit(node.value))
+ ## dart2js is smart enough to optimize this if/else away ##
+ writer.write('if instanceof(%s, Number) or instanceof(%s, String): %s' %(target,target,b) )
+ writer.write('else: %s' %a)
+
+ elif self._with_js: ## no operator overloading in with-js mode
a = '%s %s %s' %(target, op, self.visit(node.value))
writer.write(a)
@@ -129,6 +129,29 @@ def visit_ClassDef(self, node):
elif b.name == '__setitem__':
b.name = ''
b._prefix = 'void operator []='
+ elif b.name == '__add__':
+ b.name = ''
+ b._prefix = 'operator +'
+ elif b.name == '__iadd__':
+ b.name = ''
+ b._prefix = 'void operator +='
+ elif b.name == '__sub__':
+ b.name = ''
+ b._prefix = 'operator -'
+ elif b.name == '__mul__':
+ b.name = ''
+ b._prefix = 'operator *'
+ elif b.name == '__div__':
+ b.name = ''
+ b._prefix = 'operator /'
+
+ elif b.name == '__or__':
+ b.name = ''
+ b._prefix = 'operator |'
+ elif b.name == '__xor__':
+ b.name = ''
+ b._prefix = 'operator ^'
+
line = self.visit(b)
@@ -158,6 +181,24 @@ def visit_ClassDef(self, node):
operator = 'operator []'
elif b.name == '__setitem__':
operator = 'operator []='
+ elif b.name == '__add__':
+ operator = 'operator +'
+ elif b.name == '__sub__':
+ operator = 'operator -'
+ elif b.name == '__mul__':
+ operator = 'operator *'
+ elif b.name == '__div__':
+ operator = 'operator /'
+ elif b.name == '__and__':
+ operator = 'operator &'
+ elif b.name == '__or__':
+ operator = 'operator |'
+ elif b.name == '__xor__':
+ operator = 'operator ^'
+ elif b.name == '__lshift__':
+ operator = 'operator <<'
+ elif b.name == '__rshift__':
+ operator = 'operator >>'
args = [self.visit(a) for a in b.args.args][1:]
args = ','.join(args)
@@ -302,6 +343,8 @@ def visit_Is(self, node):
def _visit_call_helper_instanceof(self, node):
args = map(self.visit, node.args)
if len(args) == 2:
+ if args[1] == 'Number':
+ args[1] = 'num'
return '%s is %s' %tuple(args)
else:
raise SyntaxError( args )
@@ -0,0 +1,179 @@
+<html>
+<head>
+<script src="pythonscript.js"></script>
+
+<script type="text/python">
+
+class Vector3:
+ def __init__(self, x=0, y=0, z=0 ):
+ self._x = x
+ self._y = y
+ self._z = z
+
+ def set(self, x,y,z):
+ self._x = x
+ self._y = y
+ self._z = z
+
+ @property
+ def x(self):
+ return self._x
+ @x.setter
+ def x(self, value):
+ print 'x setter', value
+ self._x = value
+
+ @property
+ def y(self):
+ return self._y
+ @y.setter
+ def y(self, value):
+ print 'y setter', value
+ self._y = value
+
+ @property
+ def z(self):
+ return self._z
+ @z.setter
+ def z(self, value):
+ print 'z setter', value
+ self._z = value
+
+
+ def add(self, other):
+ self.set( self.x+other.x, self.y+other.y, self.z+other.z )
+ return self
+
+ def __add__(self, other):
+ if instanceof(other, Number):
+ return Vector3( self.x+other, self.y+other, self.z+other )
+ else:
+ return Vector3( self.x+other.x, self.y+other.y, self.z+other.z )
+
+ def __iadd__(self, other):
+ if instanceof(other, Number):
+ self.addScalar( other )
+ else:
+ self.add( other )
+
+ def addScalar(self, s):
+ self.set( self.x+s, self.y+s, self.z+s )
+ return self
+
+
+ def sub(self, other):
+ self.set( self.x-other.x, self.y-other.y, self.z-other.z )
+ return self
+
+ def __sub__(self, other):
+ if instanceof(other, Number):
+ return Vector3( self.x-other, self.y-other, self.z-other )
+ else:
+ return Vector3( self.x-other.x, self.y-other.y, self.z-other.z )
+
+ def __isub__(self, other):
+ if instanceof(other, Number):
+ self.set( self.x-other, self.y-other, self.z-other )
+ else:
+ self.sub( other )
+
+
+ def multiply(self, other):
+ self.set( self.x*other.x, self.y*other.y, self.z*other.z )
+ return self
+
+ def __mul__(self, other):
+ if instanceof(other, Number):
+ return Vector3( self.x*other, self.y*other, self.z*other )
+ else:
+ return Vector3( self.x*other.x, self.y*other.y, self.z*other.z )
+
+ def __imul__(self, other):
+ if instanceof(other, Number):
+ self.multiplyScalar( other )
+ else:
+ self.multiply( other )
+
+ def multiplyScalar(self, s):
+ self.set( self.x*s, self.y*s, self.z*s )
+ return self
+
+ def divide(self, other):
+ self.set( self.x/other.x, self.y/other.y, self.z/other.z )
+ return self
+
+ def divideScalar(self, s):
+ self.set( self.x/s, self.y/s, self.z/s )
+ return self
+
+ def __div__(self, other):
+ if instanceof(other, Number):
+ return Vector3( self.x/other, self.y/other, self.z/other )
+ else:
+ return Vector3( self.x/other.x, self.y/other.y, self.z/other.z )
+
+ def __idiv__(self, other):
+ if instanceof(other, Number):
+ self.divideScalar( other )
+ else:
+ self.divide( other )
+
+
+ def __xor__(self, s): ## ^
+ self.set( self.x^s, self.y^s, self.z^s )
+ return self
+
+def show_vec(v):
+ print '-------------'
+ print v.x
+ print v.y
+ print v.z
+
+def main():
+ n = 1
+ n += 2
+ print n
+
+ v1 = Vector3(1, 2, 3)
+ v2 = Vector3(10, 0, 10)
+ print v1, v2
+ print 'testing +'
+ a = v1 + v2
+ show_vec(a)
+
+ print 'testing +='
+ a += 2.5
+ show_vec(a)
+ a += v1
+ show_vec(a)
+
+ print 'testing -='
+ a -= v1
+ show_vec(a)
+ a -= 100
+ show_vec(a)
+
+ print 'testing *'
+ b = v1 * v2
+ show_vec(b)
+
+ print 'testing *='
+ b *= 10.0
+ show_vec(b)
+ b *= v2
+ show_vec(b)
+
+ print 'testing setters'
+ b.x = 1
+ b.y = 2
+ b.z = 3
+
+
+
+</script>
+</head>
+
+<body>
+<button onclick="main()">click me</button>
+</body>
+</html>

0 comments on commit 95ea574

Please sign in to comment.