changes for complex and power (**) operator
diff --git a/Python/ceval.c b/Python/ceval.c
index 35c8998..fb3d1fe 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -82,6 +82,7 @@
 	PROTO((object **, object **, frameobject *, char *, object *));
 static object *add PROTO((object *, object *));
 static object *sub PROTO((object *, object *));
+static object *pow PROTO((object *, object *));
 static object *mul PROTO((object *, object *));
 static object *divide PROTO((object *, object *));
 static object *mod PROTO((object *, object *));
@@ -675,6 +676,15 @@
 			PUSH(x);
 			break;
 		
+		case BINARY_POWER:
+			w = POP();
+			v = POP();
+			x = pow(v, w);
+			DECREF(v);
+			DECREF(w);
+			PUSH(x);
+			break;
+		
 		case BINARY_MULTIPLY:
 			w = POP();
 			v = POP();
@@ -2205,6 +2215,34 @@
 }
 
 static object *
+pow(v, w)
+	object *v, *w;
+{
+	object *res;
+	BINOP("__pow__", "__rpow__", pow);
+	if (v->ob_type->tp_as_number == NULL ||
+	    w->ob_type->tp_as_number == NULL) {
+		err_setstr(TypeError, "pow() requires numeric arguments");
+		return NULL;
+	}
+	if (
+#ifndef WITHOUT_COMPLEX
+            !is_complexobject(v) && 
+#endif
+            is_floatobject(w) && getfloatvalue(v) < 0.0) {
+		if (!err_occurred())
+		    err_setstr(ValueError, "negative number to float power");
+		return NULL;
+	}
+	if (coerce(&v, &w) != 0)
+		return NULL;
+	res = (*v->ob_type->tp_as_number->nb_power)(v, w, None);
+	DECREF(v);
+	DECREF(w);
+	return res;
+}
+
+static object *
 neg(v)
 	object *v;
 {
diff --git a/Python/compile.c b/Python/compile.c
index 21a47f2..2f6c46b 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -287,6 +287,7 @@
 static void com_free PROTO((struct compiling *));
 static void com_done PROTO((struct compiling *));
 static void com_node PROTO((struct compiling *, struct _node *));
+static void com_factor PROTO((struct compiling *, struct _node *));
 static void com_addbyte PROTO((struct compiling *, int));
 static void com_addint PROTO((struct compiling *, int));
 static void com_addoparg PROTO((struct compiling *, int, int));
@@ -563,8 +564,16 @@
 	extern double atof PROTO((const char *));
 	char *end;
 	long x;
+#ifndef WITHOUT_COMPLEX
+	complex c;
+	int imflag;
+#endif
+
 	errno = 0;
 	end = s + strlen(s) - 1;
+#ifndef WITHOUT_COMPLEX
+	imflag = *end == 'i' || *end == 'I' || *end == 'j' || *end == 'J';
+#endif
 	if (*end == 'l' || *end == 'L')
 		return long_scan(s, 0);
 	if (s[0] == '0')
@@ -580,7 +589,15 @@
 		return newintobject(x);
 	}
 	/* XXX Huge floats may silently fail */
-	return newfloatobject(atof(s));
+#ifndef WITHOUT_COMPLEX
+	if (imflag) {
+		c.real = 0.;
+		c.imag = atof(s);
+		return newcomplexobject(c);
+	}
+	else
+#endif
+		return newfloatobject(atof(s));
 }
 
 static object *
@@ -810,15 +827,23 @@
 	node *n;
 {
 	REQ(n, subscript);
-	if (NCH(n) == 1 && TYPE(CHILD(n, 0)) != COLON) {
-		/* It's a single subscript */
-		com_node(c, CHILD(n, 0));
-		com_addbyte(c, BINARY_SUBSCR);
-	}
-	else {
+	if (TYPE(CHILD(n, 0)) == COLON || (NCH(n) > 1 && TYPE(CHILD(n, 1)) == COLON)) {
 		/* It's a slice: [expr] ':' [expr] */
 		com_slice(c, n, SLICE);
 	}
+	else {
+		/* It's a list of subscripts */
+		if (NCH(n) == 1)
+			com_node(c, CHILD(n, 0));
+		else {
+			int i;
+			int len = (NCH(n)+1)/2;
+			for (i = 0; i < NCH(n); i += 2)
+				com_node(c, CHILD(n, i));
+			com_addoparg(c, BUILD_TUPLE, len);
+		}
+		com_addbyte(c, BINARY_SUBSCR);
+	}
 }
 
 static int
@@ -922,6 +947,25 @@
 }
 
 static void
+com_power(c, n)
+	struct compiling *c;
+	node *n;
+{
+	int i;
+	REQ(n, power);
+	com_atom(c, CHILD(n, 0));
+	for (i = 1; i < NCH(n); i++) {
+		if (TYPE(CHILD(n, i)) == DOUBLESTAR) {
+			com_factor(c, CHILD(n, i+1));
+			com_addbyte(c, BINARY_POWER);
+			break;
+		}
+		else
+			com_apply_trailer(c, CHILD(n, i));
+	}
+}
+
+static void
 com_factor(c, n)
 	struct compiling *c;
 	node *n;
@@ -941,9 +985,7 @@
 		com_addbyte(c, UNARY_INVERT);
 	}
 	else {
-		com_atom(c, CHILD(n, 0));
-		for (i = 1; i < NCH(n); i++)
-			com_apply_trailer(c, CHILD(n, i));
+		com_power(c, CHILD(n, 0));
 	}
 }
 
@@ -1338,7 +1380,15 @@
 	node *n;
 	int assigning;
 {
-	com_node(c, n);
+	if (NCH(n) == 1)
+		com_node(c, CHILD(n, 0));
+	else {
+		int i;
+		int len = (NCH(n)+1)/2;
+		for (i = 0; i < NCH(n); i += 2)
+			com_node(c, CHILD(n, i));
+		com_addoparg(c, BUILD_TUPLE, len);
+	}
 	com_addbyte(c, assigning ? STORE_SUBSCR : DELETE_SUBSCR);
 }
 
@@ -1359,11 +1409,11 @@
 		break;
 	case LSQB: /* '[' subscript ']' */
 		n = CHILD(n, 1);
-		REQ(n, subscript); /* subscript: expr | [expr] ':' [expr] */
-		if (NCH(n) > 1 || TYPE(CHILD(n, 0)) == COLON)
+		REQ(n, subscript); /* subscript: expr (',' expr)* | [expr] ':' [expr] */
+		if (TYPE(CHILD(n, 0)) == COLON || (NCH(n) > 1 && TYPE(CHILD(n, 1)) == COLON))
 			com_assign_slice(c, n, assigning);
 		else
-			com_assign_subscript(c, CHILD(n, 0), assigning);
+			com_assign_subscript(c, n, assigning);
 		break;
 	default:
 		err_setstr(SystemError, "unknown trailer type");
@@ -1438,6 +1488,7 @@
 		case shift_expr:
 		case arith_expr:
 		case term:
+		case factor:
 			if (NCH(n) > 1) {
 				err_setstr(SyntaxError,
 					"can't assign to operator");
@@ -1447,17 +1498,24 @@
 			n = CHILD(n, 0);
 			break;
 		
-		case factor: /* ('+'|'-'|'~') factor | atom trailer* */
-			if (TYPE(CHILD(n, 0)) != atom) { /* '+'|'-'|'~' */
+		case power: /* atom trailer* ('**' power)* */
+/* ('+'|'-'|'~') factor | atom trailer* */
+			if (TYPE(CHILD(n, 0)) != atom) {
 				err_setstr(SyntaxError,
 					"can't assign to operator");
 				c->c_errors++;
 				return;
 			}
-			if (NCH(n) > 1) { /* trailer present */
+			if (NCH(n) > 1) { /* trailer or exponent present */
 				int i;
 				com_node(c, CHILD(n, 0));
 				for (i = 1; i+1 < NCH(n); i++) {
+					if (TYPE(CHILD(n, i)) == DOUBLESTAR) {
+						err_setstr(SyntaxError,
+							"can't assign to operator");
+						c->c_errors++;
+						return;
+					}
 					com_apply_trailer(c, CHILD(n, i));
 				} /* NB i is still alive */
 				com_assign_trailer(c,
@@ -2059,6 +2117,7 @@
 	case arith_expr:
 	case term:
 	case factor:
+	case power:
 		if (NCH(n) == 1)
 			return get_docstring(CHILD(n, 0));
 		break;
@@ -2136,7 +2195,7 @@
 	ndefs = 0;
 	for (i = 0; i < nch; i++) {
 		int t;
-		if (TYPE(CHILD(n, i)) == STAR)
+		if (TYPE(CHILD(n, i)) == STAR || TYPE(CHILD(n, i)) == DOUBLESTAR)
 			break;
 		nargs++;
 		i++;
@@ -2373,6 +2432,9 @@
 	case factor:
 		com_factor(c, n);
 		break;
+	case power:
+		com_power(c, n);
+		break;
 	case atom:
 		com_atom(c, n);
 		break;
@@ -2431,7 +2493,7 @@
 		node *ch = CHILD(n, i);
 		node *fp;
 		char *name;
-		if (TYPE(ch) == STAR)
+		if (TYPE(ch) == STAR || TYPE(ch) == DOUBLESTAR)
 			break;
 		REQ(ch, fpdef); /* fpdef: NAME | '(' fplist ')' */
 		fp = CHILD(ch, 0);
@@ -2455,22 +2517,28 @@
 	if (i < nch) {
 		node *ch;
 		ch = CHILD(n, i);
-		REQ(ch, STAR);
-		ch = CHILD(n, i+1);
-		if (TYPE(ch) == NAME) {
-			c->c_flags |= CO_VARARGS;
-			i += 3;
-			com_newlocal(c, STR(ch));
+		if (TYPE(ch) != DOUBLESTAR) {
+			REQ(ch, STAR);
+			ch = CHILD(n, i+1);
+			if (TYPE(ch) == NAME) {
+				c->c_flags |= CO_VARARGS;
+				i += 3;
+				com_newlocal(c, STR(ch));
+			}
 		}
 	}
 	/* Handle **keywords */
 	if (i < nch) {
 		node *ch;
 		ch = CHILD(n, i);
-		REQ(ch, STAR);
-		ch = CHILD(n, i+1);
-		REQ(ch, STAR);
-		ch = CHILD(n, i+2);
+		if (TYPE(ch) != DOUBLESTAR) {
+			REQ(ch, STAR);
+			ch = CHILD(n, i+1);
+			REQ(ch, STAR);
+			ch = CHILD(n, i+2);
+		}
+		else
+			ch = CHILD(n, i+1);
 		REQ(ch, NAME);
 		c->c_flags |= CO_VARKEYWORDS;
 		com_newlocal(c, STR(ch));
@@ -2482,7 +2550,7 @@
 		for (i = 0; i < nch; i++) {
 			node *ch = CHILD(n, i);
 			node *fp;
-			if (TYPE(ch) == STAR)
+			if (TYPE(ch) == STAR || TYPE(ch) == DOUBLESTAR)
 				break;
 			REQ(ch, fpdef); /* fpdef: NAME | '(' fplist ')' */
 			fp = CHILD(ch, 0);