Number& Number::operator+=(const Number& num) { #ifndef PMP_DISABLE_VECTOR if (is_v() || num.is_v()) { vector_type vec; for (size_t i = 0; i < size(); ++i) { for (size_t j = 0; j < num.size(); ++j) { Number tmp((*this)[i]); tmp += num[j]; vec.push_back(tmp); } } assign(vec); return *this; } #endif // ndef PMP_DISABLE_VECTOR integer_type i; floating_type f; rational_type r; switch (type()) { case Number::INTEGER: switch (num.type()) { case Number::INTEGER: i = get_i(); i += num.get_i(); assign(i); break; case Number::FLOATING: f = to_f(); f += num.get_f(); assign(f); break; case Number::RATIONAL: r = to_r(); r += num.get_r(); assign(r); break; default: assert(0); break; } break; case Number::FLOATING: switch (num.type()) { case Number::INTEGER: f = get_f(); f += num.to_f(); assign(f); break; case Number::FLOATING: f = get_f(); f += num.get_f(); assign(f); break; case Number::RATIONAL: f = get_f(); f += num.to_f(); assign(f); break; default: assert(0); break; } break; case Number::RATIONAL: switch (num.type()) { case Number::INTEGER: r = get_r(); r += num.to_r(); assign(r); break; case Number::FLOATING: f = to_f(); f += num.get_f(); assign(f); break; case Number::RATIONAL: r = get_r(); r += num.get_r(); assign(r); break; default: assert(0); break; } break; default: assert(0); break; } return *this; }
static inline void forth_vm_execute_instruction(forth_context_type *fc, char cmd) { // printf("%c\n",cmd); // getchar(); switch(cmd) { case '0': push(fc,0); break; case '1': push(fc,1); break; case '2': push(fc,2); break; case '3': push(fc,3); break; case '4': push(fc,4); break; case '5': push(fc,5); break; case '6': push(fc,6); break; case '7': push(fc,7); break; case '8': push(fc,8); break; case '9': push(fc,9); break; case '@': at(fc); break; //@ case '!': to(fc); break; //! case 'd': fc->SP+=fc->cell; break; //drop case 'D': dup(fc); break; //dup case 's': swap_(fc); break; //swap case 'l': push(fc,next_cell(fc)); break; //lit case '+': add(fc); break; //+ case '-': sub(fc); break; //- case '*': mul(fc); break; //* case '/': div_(fc); break; // / case '%': mod(fc); break; //mod case '&': and(fc); break; // and case '|': or(fc); break; // or case '^': xor(fc); break; // xor case '>': more(fc); break; // > case '<': less(fc); break; // < case '=': eq(fc); break; // = case 'b': branch(fc); break; // branch case '?': cbranch(fc); break; // ?branch case 'c': call(fc); break; // call case 'r': ret(fc); break; // ret case 't': to_r(fc); break; // >R case 'f': from_r(fc); break; // R> case 'i': in(fc); break; // in case 'o': out(fc); break; // out case '_': fc->stop=1; break; // stop case 'A': adr0(fc); break; // @0 case 1: push(fc,fc->SP); break; // SP@ case 2: fc->SP=pop(fc); break; // SP! case 3: push(fc,fc->RP); break; // RP@ case 4: fc->RP=pop(fc); break; // RP! case 5: shl(fc); break; // << case 6: shr(fc); break; // >> case 7: push(fc,*(size_t *)(fc->mem+fc->RP)); break; // i case 8: cat(fc); break; // c@ case 9: cto(fc); break; // c! case 10: set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); break; // nop case 11: in_ready(fc); break; // ?in case 12: out_ready(fc); break; // ?out case 16: umod(fc); break; // umod case 17: udiv(fc); break; // u/ // kernel case 'K': kalsym_lookup(fc); break; // lookup kallsym address case 18: kcall(fc); break; // kcall } }
Number& Number::operator/=(const Number& num) { #ifndef PMP_DISABLE_VECTOR if (is_v() || num.is_v()) { vector_type vec; for (size_t i = 0; i < size(); ++i) { for (size_t j = 0; j < num.size(); ++j) { Number tmp((*this)[i]); tmp /= num[j]; vec.push_back(tmp); } } assign(vec); return *this; } #endif integer_type i; floating_type f; rational_type r; switch (type()) { case Number::INTEGER: switch (num.type()) { case Number::INTEGER: if (s_intdiv_type == Number::INTEGER) { i = get_i(); i /= num.get_i(); assign(i); } else if (s_intdiv_type == Number::FLOATING) { if (b_mp::fmod(to_f(), num.to_f()) != 0) { f = to_f(); f /= num.to_f(); assign(f); } else { i = get_i(); i /= num.get_i(); assign(i); } } else if (s_intdiv_type == Number::RATIONAL) { r = rational_type(get_i(), num.get_i()); assign(r); } else { assert(0); } break; case Number::FLOATING: f = to_f(); f /= num.get_f(); assign(f); break; case Number::RATIONAL: r = to_r(); r /= num.get_r(); assign(r); break; default: assert(0); break; } break; case Number::FLOATING: switch (num.type()) { case Number::INTEGER: f = get_f(); f /= num.to_f(); assign(f); break; case Number::FLOATING: f = get_f(); f /= num.get_f(); assign(f); break; case Number::RATIONAL: f = get_f(); f /= num.to_f(); assign(f); break; default: assert(0); break; } break; case Number::RATIONAL: switch (num.type()) { case Number::INTEGER: r = get_r(); r /= num.to_r(); assign(r); break; case Number::FLOATING: f = to_f(); f /= num.get_f(); assign(f); break; case Number::RATIONAL: r = get_r(); r /= num.get_r(); assign(r); break; default: assert(0); break; } break; default: assert(0); break; } return *this; }