summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1991-10-24 14:59:31 (GMT)
committerGuido van Rossum <guido@python.org>1991-10-24 14:59:31 (GMT)
commit7928cd7636060c09da613d6f226a54903b86740a (patch)
treea098fc51fb6d3beb0efc3a7905c762190443b183 /Python
parent7a6dfa7d79597f29866033ecf648457fe7572a8f (diff)
downloadcpython-7928cd7636060c09da613d6f226a54903b86740a.zip
cpython-7928cd7636060c09da613d6f226a54903b86740a.tar.gz
cpython-7928cd7636060c09da613d6f226a54903b86740a.tar.bz2
Added shift and mask ops.
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c170
-rw-r--r--Python/compile.c159
2 files changed, 296 insertions, 33 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 76869ff..7399623 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -51,6 +51,12 @@ static object *rem();
static object *neg();
static object *pos();
static object *not();
+static object *invert();
+static object *lshift();
+static object *rshift();
+static object *and();
+static object *xor();
+static object *or();
static object *call_builtin();
static object *call_function();
static object *apply_subscript();
@@ -273,6 +279,13 @@ eval_code(co, globals, locals, arg)
DECREF(v);
PUSH(x);
break;
+
+ case UNARY_INVERT:
+ v = POP();
+ x = invert(v);
+ DECREF(v);
+ PUSH(x);
+ break;
case BINARY_MULTIPLY:
w = POP();
@@ -340,6 +353,51 @@ eval_code(co, globals, locals, arg)
PUSH(x);
break;
+ case BINARY_LSHIFT:
+ w = POP();
+ v = POP();
+ x = lshift(v, w);
+ DECREF(v);
+ DECREF(w);
+ PUSH(x);
+ break;
+
+ case BINARY_RSHIFT:
+ w = POP();
+ v = POP();
+ x = rshift(v, w);
+ DECREF(v);
+ DECREF(w);
+ PUSH(x);
+ break;
+
+ case BINARY_AND:
+ w = POP();
+ v = POP();
+ x = and(v, w);
+ DECREF(v);
+ DECREF(w);
+ PUSH(x);
+ break;
+
+ case BINARY_XOR:
+ w = POP();
+ v = POP();
+ x = xor(v, w);
+ DECREF(v);
+ DECREF(w);
+ PUSH(x);
+ break;
+
+ case BINARY_OR:
+ w = POP();
+ v = POP();
+ x = or(v, w);
+ DECREF(v);
+ DECREF(w);
+ PUSH(x);
+ break;
+
case SLICE+0:
case SLICE+1:
case SLICE+2:
@@ -1002,6 +1060,106 @@ testbool(v)
}
static object *
+or(v, w)
+ object *v, *w;
+{
+ if (v->ob_type->tp_as_number != NULL) {
+ object *x;
+ object * (*f) FPROTO((object *, object *));
+ if (coerce(&v, &w) != 0)
+ return NULL;
+ if ((f = v->ob_type->tp_as_number->nb_or) != NULL)
+ x = (*f)(v, w);
+ DECREF(v);
+ DECREF(w);
+ if (f != NULL)
+ return x;
+ }
+ err_setstr(TypeError, "bad operand type(s) for |");
+ return NULL;
+}
+
+static object *
+xor(v, w)
+ object *v, *w;
+{
+ if (v->ob_type->tp_as_number != NULL) {
+ object *x;
+ object * (*f) FPROTO((object *, object *));
+ if (coerce(&v, &w) != 0)
+ return NULL;
+ if ((f = v->ob_type->tp_as_number->nb_xor) != NULL)
+ x = (*f)(v, w);
+ DECREF(v);
+ DECREF(w);
+ if (f != NULL)
+ return x;
+ }
+ err_setstr(TypeError, "bad operand type(s) for ^");
+ return NULL;
+}
+
+static object *
+and(v, w)
+ object *v, *w;
+{
+ if (v->ob_type->tp_as_number != NULL) {
+ object *x;
+ object * (*f) FPROTO((object *, object *));
+ if (coerce(&v, &w) != 0)
+ return NULL;
+ if ((f = v->ob_type->tp_as_number->nb_and) != NULL)
+ x = (*f)(v, w);
+ DECREF(v);
+ DECREF(w);
+ if (f != NULL)
+ return x;
+ }
+ err_setstr(TypeError, "bad operand type(s) for &");
+ return NULL;
+}
+
+static object *
+lshift(v, w)
+ object *v, *w;
+{
+ if (v->ob_type->tp_as_number != NULL) {
+ object *x;
+ object * (*f) FPROTO((object *, object *));
+ if (coerce(&v, &w) != 0)
+ return NULL;
+ if ((f = v->ob_type->tp_as_number->nb_lshift) != NULL)
+ x = (*f)(v, w);
+ DECREF(v);
+ DECREF(w);
+ if (f != NULL)
+ return x;
+ }
+ err_setstr(TypeError, "bad operand type(s) for <<");
+ return NULL;
+}
+
+static object *
+rshift(v, w)
+ object *v, *w;
+{
+ if (v->ob_type->tp_as_number != NULL) {
+ object *x;
+ object * (*f) FPROTO((object *, object *));
+ if (coerce(&v, &w) != 0)
+ return NULL;
+ if ((f = v->ob_type->tp_as_number->nb_rshift) != NULL)
+ x = (*f)(v, w);
+ DECREF(v);
+ DECREF(w);
+ if (f != NULL)
+ return x;
+ }
+ err_setstr(TypeError, "bad operand type(s) for >>");
+ return NULL;
+}
+
+static object *
add(v, w)
object *v, *w;
{
@@ -1128,6 +1286,18 @@ pos(v)
}
static object *
+invert(v)
+ object *v;
+{
+ object * (*f) FPROTO((object *, object *));
+ if (v->ob_type->tp_as_number != NULL &&
+ (f = v->ob_type->tp_as_number->nb_invert) != NULL)
+ return (*f)(v);
+ err_setstr(TypeError, "bad operand type(s) for unary ~");
+ return NULL;
+}
+
+static object *
not(v)
object *v;
{
diff --git a/Python/compile.c b/Python/compile.c
index 5939196..09d461a 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -689,6 +689,10 @@ com_factor(c, n)
com_factor(c, CHILD(n, 1));
com_addbyte(c, UNARY_NEGATIVE);
}
+ else if (TYPE(CHILD(n, 0)) == TILDE) {
+ com_factor(c, CHILD(n, 1));
+ com_addbyte(c, UNARY_INVERT);
+ }
else {
com_atom(c, CHILD(n, 0));
for (i = 1; i < NCH(n); i++)
@@ -719,7 +723,7 @@ com_term(c, n)
break;
default:
err_setstr(SystemError,
- "com_term: term operator not *, / or %");
+ "com_term: operator not *, / or %");
c->c_errors++;
op = 255;
}
@@ -728,13 +732,13 @@ com_term(c, n)
}
static void
-com_expr(c, n)
+com_arith_expr(c, n)
struct compiling *c;
node *n;
{
int i;
int op;
- REQ(n, expr);
+ REQ(n, arith_expr);
com_term(c, CHILD(n, 0));
for (i = 2; i < NCH(n); i += 2) {
com_term(c, CHILD(n, i));
@@ -747,7 +751,107 @@ com_expr(c, n)
break;
default:
err_setstr(SystemError,
- "com_expr: expr operator not + or -");
+ "com_arith_expr: operator not + or -");
+ c->c_errors++;
+ op = 255;
+ }
+ com_addbyte(c, op);
+ }
+}
+
+static void
+com_shift_expr(c, n)
+ struct compiling *c;
+ node *n;
+{
+ int i;
+ int op;
+ REQ(n, shift_expr);
+ com_arith_expr(c, CHILD(n, 0));
+ for (i = 2; i < NCH(n); i += 2) {
+ com_arith_expr(c, CHILD(n, i));
+ switch (TYPE(CHILD(n, i-1))) {
+ case LEFTSHIFT:
+ op = BINARY_LSHIFT;
+ break;
+ case RIGHTSHIFT:
+ op = BINARY_RSHIFT;
+ break;
+ default:
+ err_setstr(SystemError,
+ "com_shift_expr: operator not << or >>");
+ c->c_errors++;
+ op = 255;
+ }
+ com_addbyte(c, op);
+ }
+}
+
+static void
+com_and_expr(c, n)
+ struct compiling *c;
+ node *n;
+{
+ int i;
+ int op;
+ REQ(n, and_expr);
+ com_shift_expr(c, CHILD(n, 0));
+ for (i = 2; i < NCH(n); i += 2) {
+ com_shift_expr(c, CHILD(n, i));
+ if (TYPE(CHILD(n, i-1)) == AMPER) {
+ op = BINARY_AND;
+ }
+ else {
+ err_setstr(SystemError,
+ "com_and_expr: operator not &");
+ c->c_errors++;
+ op = 255;
+ }
+ com_addbyte(c, op);
+ }
+}
+
+static void
+com_xor_expr(c, n)
+ struct compiling *c;
+ node *n;
+{
+ int i;
+ int op;
+ REQ(n, xor_expr);
+ com_and_expr(c, CHILD(n, 0));
+ for (i = 2; i < NCH(n); i += 2) {
+ com_and_expr(c, CHILD(n, i));
+ if (TYPE(CHILD(n, i-1)) == CIRCUMFLEX) {
+ op = BINARY_XOR;
+ }
+ else {
+ err_setstr(SystemError,
+ "com_xor_expr: operator not ^");
+ c->c_errors++;
+ op = 255;
+ }
+ com_addbyte(c, op);
+ }
+}
+
+static void
+com_expr(c, n)
+ struct compiling *c;
+ node *n;
+{
+ int i;
+ int op;
+ REQ(n, expr);
+ com_xor_expr(c, CHILD(n, 0));
+ for (i = 2; i < NCH(n); i += 2) {
+ com_xor_expr(c, CHILD(n, i));
+ if (TYPE(CHILD(n, i-1)) == VBAR) {
+ op = BINARY_OR;
+ }
+ else {
+ err_setstr(SystemError,
+ "com_expr: expr operator not |");
c->c_errors++;
op = 255;
}
@@ -1065,35 +1169,12 @@ com_assign(c, n, assigning)
case test:
case and_test:
case not_test:
- if (NCH(n) > 1) {
- err_setstr(TypeError,
- "can't assign to operator");
- c->c_errors++;
- return;
- }
- n = CHILD(n, 0);
- break;
-
case comparison:
- if (NCH(n) > 1) {
- err_setstr(TypeError,
- "can't assign to operator");
- c->c_errors++;
- return;
- }
- n = CHILD(n, 0);
- break;
-
case expr:
- if (NCH(n) > 1) {
- err_setstr(TypeError,
- "can't assign to operator");
- c->c_errors++;
- return;
- }
- n = CHILD(n, 0);
- break;
-
+ case xor_expr:
+ case and_expr:
+ case shift_expr:
+ case arith_expr:
case term:
if (NCH(n) > 1) {
err_setstr(TypeError,
@@ -1104,8 +1185,8 @@ com_assign(c, n, assigning)
n = CHILD(n, 0);
break;
- case factor: /* ('+'|'-') factor | atom trailer* */
- if (TYPE(CHILD(n, 0)) != atom) { /* '+' | '-' */
+ case factor: /* ('+'|'-'|'~') factor | atom trailer* */
+ if (TYPE(CHILD(n, 0)) != atom) { /* '+'|'-'|'~' */
err_setstr(TypeError,
"can't assign to operator");
c->c_errors++;
@@ -1728,6 +1809,18 @@ com_node(c, n)
case expr:
com_expr(c, n);
break;
+ case xor_expr:
+ com_xor_expr(c, n);
+ break;
+ case and_expr:
+ com_and_expr(c, n);
+ break;
+ case shift_expr:
+ com_shift_expr(c, n);
+ break;
+ case arith_expr:
+ com_arith_expr(c, n);
+ break;
case term:
com_term(c, n);
break;