diff --git a/src/alu.c b/src/alu.c index ba90d38..5c7caba 100644 --- a/src/alu.c +++ b/src/alu.c @@ -61,11 +61,11 @@ enum op_id { OPID_OPENING, // (v '(', starts subexpression (handled like monadic) OPID_CLOSING, // v) ')', ends subexpression (handled like dyadic) // monadic operators (including functions): - OPID_NOT, // !v NOT v bit-wise NOT - OPID_NEGATE, // -v Negate - OPID_LOWBYTEOF, // v Highbyte of - OPID_BANKBYTEOF, // ^v Bankbyte of + OPID_NOT, // !v NOT v bit-wise NOT + OPID_NEGATE, // -v negation + OPID_LOWBYTEOF, // v high byte of + OPID_BANKBYTEOF, // ^v bank byte of OPID_ADDRESS, // addr(v) FIXME - add nonaddr()? OPID_INT, // int(v) OPID_FLOAT, // float(v) @@ -78,18 +78,18 @@ enum op_id { // dyadic operators: OPID_POWEROF, // v^w OPID_MULTIPLY, // v*w - OPID_DIVIDE, // v/w (Integer) Division - OPID_INTDIV, // v/w v DIV w Integer Division - OPID_MODULO, // v%w v MOD w Remainder - OPID_SL, // v<>w v ASR w Arithmetic shift right - OPID_LSR, // v>>>w v LSR w Logical shift right + OPID_DIVIDE, // v/w division + OPID_INTDIV, // v/w v DIV w integer division + OPID_MODULO, // v%w v MOD w remainder + OPID_SHIFTLEFT, // v<>w v ASR w arithmetic shift right + OPID_LSR, // v>>>w v LSR w logical shift right OPID_ADD, // v+w OPID_SUBTRACT, // v-w OPID_EQUALS, // v=w - OPID_LE, // v<=w + OPID_LESSOREQUAL, // v<=w OPID_LESSTHAN, // v< w - OPID_GE, // v>=w + OPID_GREATEROREQUAL, // v>=w OPID_GREATERTHAN, // v> w OPID_NOTEQUAL, // v!=w v<>w v>': // HIGHBYTE operator - op = &ops_highbyteof; + op = &ops_high_byte_of; goto get_byte_and_push_monadic; case '^': // BANKBYTE operator - op = &ops_bankbyteof; + op = &ops_bank_byte_of; goto get_byte_and_push_monadic; // Faked monadic operators @@ -871,7 +871,7 @@ static void expect_dyadic_operator(void) // Multi-character dyadic operators case '!': // "!=" if (GetByte() == '=') { - op = &ops_notequal; + op = &ops_not_equal; goto get_byte_and_push_dyadic; } @@ -881,19 +881,19 @@ static void expect_dyadic_operator(void) case '<': // "<", "<=", "<<" and "<>" switch (GetByte()) { case '=': // "<=", less or equal - op = &ops_le; + op = &ops_less_or_equal; goto get_byte_and_push_dyadic; case '<': // "<<", shift left - op = &ops_sl; + op = &ops_shift_left; goto get_byte_and_push_dyadic; case '>': // "<>", not equal - op = &ops_notequal; + op = &ops_not_equal; goto get_byte_and_push_dyadic; default: // "<", less than - op = &ops_lessthan; + op = &ops_less_than; goto push_dyadic_op; } @@ -901,11 +901,11 @@ static void expect_dyadic_operator(void) case '>': // ">", ">=", ">>", ">>>" and "><" switch (GetByte()) { case '=': // ">=", greater or equal - op = &ops_ge; + op = &ops_greater_or_equal; goto get_byte_and_push_dyadic; case '<': // "><", not equal - op = &ops_notequal; + op = &ops_not_equal; goto get_byte_and_push_dyadic; case '>': // ">>" or ">>>", shift right @@ -917,7 +917,7 @@ static void expect_dyadic_operator(void) goto get_byte_and_push_dyadic; default: // ">", greater than - op = &ops_greaterthan; + op = &ops_greater_than; goto push_dyadic_op; } @@ -955,6 +955,22 @@ push_dyadic_op: } +// helper function: don't know how to handle that ARG OP combination +static void unsupported_monadic(struct op *op, struct object *arg) +{ + if (op->group != OPGROUP_MONADIC) + Bug_found("OperatorIsNotMonadic", op->id); + Throw_error("Unsupported combination of monadic operator and argument type"); // FIXME - make dynamic, add text versions of op/arg, add to docs +} +// helper function: don't know how to handle that ARG1 OP ARG2 combination +static void unsupported_dyadic(struct object *self, struct op *op, struct object *other) +{ + if (op->group != OPGROUP_DYADIC) + Bug_found("OperatorIsNotDyadic", op->id); + Throw_error("Unsupported combination of arguments and operator"); // FIXME - make dynamic, add text versions of self/op/other, add to docs +} + + // int/float @@ -1041,10 +1057,9 @@ static void int_handle_monadic_operator(struct object *self, struct op *op) break; // add new monadic operators here // case OPID_: -// Throw_error("'int' type does not support this operation"); // break; default: - Bug_found("IllegalOperatorIdIM", op->id); + unsupported_monadic(op, self); } self->u.number.addr_refs = refs; // update address refs with local copy } @@ -1112,10 +1127,9 @@ static void float_handle_monadic_operator(struct object *self, struct op *op) // add new monadic operators here // case OPID_: -// Throw_error("'float' type does not support this operation"); // break; default: - Bug_found("IllegalOperatorIdFM", op->id); + unsupported_monadic(op, self); } self->u.number.addr_refs = refs; // update address refs with local copy } @@ -1134,13 +1148,6 @@ static void number_fix_result_after_dyadic(struct object *self, struct object *o } -// helper function: don't know how to handle that ARG1 OP ARG2 combination -static void unsupported_dyadic(struct object *self, struct op *op, struct object *other) -{ - Throw_error("Unsupported combination of argument(s) and operator"); // FIXME - make dynamic, add text versions of self/op/other, add to docs -} - - // int: // handle dyadic operator static void int_handle_dyadic_operator(struct object *self, struct op *op, struct object *other) @@ -1160,9 +1167,9 @@ static void int_handle_dyadic_operator(struct object *self, struct op *op, struc case OPID_ADD: case OPID_SUBTRACT: case OPID_EQUALS: - case OPID_LE: + case OPID_LESSOREQUAL: case OPID_LESSTHAN: - case OPID_GE: + case OPID_GREATEROREQUAL: case OPID_GREATERTHAN: case OPID_NOTEQUAL: // become float, delegate to float handler @@ -1171,7 +1178,7 @@ static void int_handle_dyadic_operator(struct object *self, struct op *op, struc return; // float handler has done everything case OPID_MODULO: - case OPID_SL: + case OPID_SHIFTLEFT: case OPID_ASR: // convert other to int float_to_int(other); @@ -1243,7 +1250,7 @@ static void int_handle_dyadic_operator(struct object *self, struct op *op, struc self->u.number.val.intval -= other->u.number.val.intval; refs = self->u.number.addr_refs - other->u.number.addr_refs; // subtract address references break; - case OPID_SL: + case OPID_SHIFTLEFT: self->u.number.val.intval <<= other->u.number.val.intval; break; case OPID_ASR: @@ -1252,13 +1259,13 @@ static void int_handle_dyadic_operator(struct object *self, struct op *op, struc case OPID_LSR: self->u.number.val.intval = ((uintval_t) (self->u.number.val.intval)) >> other->u.number.val.intval; break; - case OPID_LE: + case OPID_LESSOREQUAL: self->u.number.val.intval = (self->u.number.val.intval <= other->u.number.val.intval); break; case OPID_LESSTHAN: self->u.number.val.intval = (self->u.number.val.intval < other->u.number.val.intval); break; - case OPID_GE: + case OPID_GREATEROREQUAL: self->u.number.val.intval = (self->u.number.val.intval >= other->u.number.val.intval); break; case OPID_GREATERTHAN: @@ -1315,9 +1322,9 @@ static void float_handle_dyadic_operator(struct object *self, struct op *op, str case OPID_INTDIV: case OPID_ADD: case OPID_SUBTRACT: - case OPID_LE: + case OPID_LESSOREQUAL: case OPID_LESSTHAN: - case OPID_GE: + case OPID_GREATEROREQUAL: case OPID_GREATERTHAN: case OPID_NOTEQUAL: case OPID_EQUALS: @@ -1332,7 +1339,7 @@ static void float_handle_dyadic_operator(struct object *self, struct op *op, str case OPID_EOR: case OPID_XOR: // these actually want a float and an int - case OPID_SL: + case OPID_SHIFTLEFT: case OPID_ASR: break; // add new dyadic operators here @@ -1397,7 +1404,7 @@ static void float_handle_dyadic_operator(struct object *self, struct op *op, str self->u.number.val.fpval -= other->u.number.val.fpval; refs = self->u.number.addr_refs - other->u.number.addr_refs; // subtract address references break; - case OPID_SL: + case OPID_SHIFTLEFT: if (other->type == &type_float) float_to_int(other); self->u.number.val.fpval *= pow(2.0, other->u.number.val.intval); @@ -1407,7 +1414,7 @@ static void float_handle_dyadic_operator(struct object *self, struct op *op, str float_to_int(other); self->u.number.val.fpval /= (1 << other->u.number.val.intval); // FIXME - why not use pow() as in SL above? break; - case OPID_LE: + case OPID_LESSOREQUAL: self->u.number.val.intval = (self->u.number.val.fpval <= other->u.number.val.fpval); self->type = &type_int; // result is int break; @@ -1415,7 +1422,7 @@ static void float_handle_dyadic_operator(struct object *self, struct op *op, str self->u.number.val.intval = (self->u.number.val.fpval < other->u.number.val.fpval); self->type = &type_int; // result is int break; - case OPID_GE: + case OPID_GREATEROREQUAL: self->u.number.val.intval = (self->u.number.val.fpval >= other->u.number.val.fpval); self->type = &type_int; // result is int break; @@ -1515,7 +1522,7 @@ static void float_print(struct object *self, struct dynabuf *db) } struct type type_int = { - //"Integer", + "integer", number_is_defined, int_handle_monadic_operator, int_handle_dyadic_operator, @@ -1523,7 +1530,7 @@ struct type type_int = { int_print }; struct type type_float = { - //"Float", + "float", number_is_defined, float_handle_monadic_operator, float_handle_dyadic_operator, @@ -1532,10 +1539,10 @@ struct type type_float = { }; /* struct type type_string = { - //"String", + "string", }; struct type type_list = { - //"List", + "list", }; */ diff --git a/src/alu.h b/src/alu.h index 2f02421..d69aaa0 100644 --- a/src/alu.h +++ b/src/alu.h @@ -13,7 +13,7 @@ struct op; struct dynabuf; struct type { - //const char *name; + const char *name; boolean (*is_defined)(struct object *self); void (*handle_monadic_operator)(struct object *self, struct op *op); void (*handle_dyadic_operator)(struct object *self, struct op *op, struct object *other);