📄 opcodes.c
字号:
offset = objoffset(op, index); if (offset < 0) { math_error("Non-existent element for object"); /*NOTREACHED*/ } vp = &op->o_table[offset]; break; case V_LIST: vp = listfindex(vp->v_list, index); if (vp == NULL) { math_error("Index out of bounds for list"); /*NOTREACHED*/ } break; default: math_error("Not initializing matrix, object or list"); /*NOTREACHED*/ } stack->v_type = V_ADDR; stack->v_addr = vp;}static voido_elemvalue(FUNC *fp, long index){ o_elemaddr(fp, index); copyvalue(stack->v_addr, stack);}/*ARGSUSED*/static voido_objcreate(FUNC UNUSED *fp, long arg){ stack++; stack->v_type = V_OBJ; stack->v_subtype = V_NOSUBTYPE; stack->v_obj = objalloc(arg);}static voido_assign(void){ VALUE *var; /* variable value */ VALUE *vp; VALUE tmp; unsigned short subtype; USB8 octet; /* * get what we will store into */ var = &stack[-1]; /* * If what we will store into is an OCTET, we must * handle this specially. Only the bottom 8 bits of * certain value types will be assigned ... not the * entire value. */ if (var->v_type == V_OCTET) { if (var->v_subtype & V_NOCOPYTO) { freevalue(stack--); *stack = error_value(E_ASSIGN1); return; } vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; if (vp->v_subtype & V_NOCOPYFROM || vp->v_type < 0) { freevalue(stack--); *stack = error_value(E_ASSIGN2); return; } copy2octet(vp, &octet); freevalue(stack--); if ((var->v_subtype & V_NONEWVALUE) && *var->v_octet != octet) { *stack = error_value(E_ASSIGN3); return; } *var->v_octet = octet; return; } if (var->v_type != V_ADDR) { freevalue(stack--); *stack = error_value(E_ASSIGN4); return; } var = var->v_addr; subtype = var->v_subtype; if (subtype & V_NOASSIGNTO) { freevalue(stack--); *stack = error_value(E_ASSIGN5); return; } vp = stack; if (var->v_type == V_OBJ) { if (vp->v_type == V_ADDR) vp = vp->v_addr; (void) objcall(OBJ_ASSIGN, var, vp, NULL_VALUE); freevalue(stack--); return; } stack--; /* * Get what we will store from * If what will store from is an address, make a copy * of the de-referenced address instead. */ if (vp->v_type == V_ADDR) { vp = vp->v_addr; if (vp == var) return; if (vp->v_subtype & V_NOASSIGNFROM) { *stack = error_value(E_ASSIGN6); return; } copyvalue(vp, &tmp); } else if (vp->v_type == V_OCTET) { copyvalue(vp, &tmp); } else { tmp = *vp; } /* * Check protection */ if ((subtype & V_NONEWVALUE) && comparevalue(var, &tmp)) { freevalue(&tmp); *stack = error_value(E_ASSIGN7); return; } if ((subtype & V_NONEWTYPE) && var->v_type != tmp.v_type) { freevalue(&tmp); *stack = error_value(E_ASSIGN8); return; } if ((subtype & V_NOERROR) && tmp.v_type < 0) { *stack = error_value(E_ASSIGN9); return; } /* * perform the assignment */ freevalue(var); *var = tmp; var->v_subtype |= subtype;}static voido_assignback(void){ VALUE tmp; tmp = stack[-1]; stack[-1] = stack[0]; stack[0] = tmp; o_assign();}static voido_assignpop(void){ o_assign(); stack--;}static voido_ptr(void){ switch (stack->v_type) { case V_ADDR: stack->v_type = V_VPTR; break; case V_OCTET: stack->v_type = V_OPTR; break; case V_STR: sfree(stack->v_str); stack->v_type = V_SPTR; break; case V_NUM: qfree(stack->v_num); stack->v_type = V_NPTR; break; default: math_error("Addressing non-addressable type"); /*NOTREACHED*/ }}static voido_deref(void){ VALUE *vp; vp = stack; if (stack->v_type == V_OCTET) { stack->v_num = itoq(*vp->v_octet); stack->v_type = V_NUM; return; } if (stack->v_type == V_OPTR) { stack->v_type = V_OCTET; return; } if (stack->v_type == V_VPTR) { stack->v_type = V_ADDR; return; } if (stack->v_type == V_SPTR) { stack->v_type = V_STR; return; } if (stack->v_type == V_NPTR) { if (stack->v_num->links == 0) { stack->v_type = V_NULL; return; } stack->v_type = V_NUM; stack->v_num->links++; return; } if (stack->v_type != V_ADDR) { math_error("Dereferencing a non-variable"); /*NOTREACHED*/ } vp = vp->v_addr; switch (vp->v_type) { case V_ADDR: case V_OCTET: *stack = *vp; break; case V_OPTR: *stack = *vp; stack->v_type = V_OCTET; break; case V_VPTR: *stack = *vp; stack->v_type = V_ADDR; break; case V_SPTR: *stack = *vp; stack->v_type = V_STR; break; case V_NPTR: if (vp->v_num->links == 0) { stack->v_type = V_NULL; break; } stack->v_type = V_NUM; stack->v_num = vp->v_num; stack->v_num->links++; break; default: copyvalue(vp, stack); }}static voido_swap(void){ VALUE *v1, *v2; /* variables to be swapped */ VALUE tmp; USB8 usb; v1 = stack--; v2 = stack; if (v1->v_type == V_OCTET && v2->v_type == V_OCTET) { if (v1->v_octet != v2->v_octet && ((v1->v_subtype | v2->v_subtype) & (V_NOCOPYTO | V_NOCOPYFROM))) { *stack = error_value(E_SWAP1); return; } usb = *v1->v_octet; *v1->v_octet = *v2->v_octet; *v2->v_octet = usb; } else if (v1->v_type == V_ADDR && v2->v_type == V_ADDR) { v1 = v1->v_addr; v2 = v2->v_addr; if (v1 != v2 && ((v1->v_subtype | v2->v_subtype) & (V_NOASSIGNTO | V_NOASSIGNFROM))) { *stack = error_value(E_SWAP2); return; } tmp = *v1; *v1 = *v2; *v2 = tmp; } else { *stack = error_value(E_SWAP3); return; } stack->v_type = V_NULL; stack->v_subtype = V_NOSUBTYPE;}static voido_add(void){ VALUE *v1, *v2; VALUE tmp; VALUE w1, w2; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; if (v1->v_type == V_OCTET) { w1.v_type = V_NUM; w1.v_subtype = V_NOSUBTYPE; w1.v_num = itoq(*v1->v_octet); v1 = &w1; } if (v2->v_type == V_OCTET) { w2.v_type = V_NUM; w2.v_subtype = V_NOSUBTYPE; w2.v_num = itoq(*v2->v_octet); v2 = &w2; } addvalue(v1, v2, &tmp); if (v1 == &w1) qfree(w1.v_num); if (v2 == &w2) qfree(w2.v_num); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_sub(void){ VALUE *v1, *v2; VALUE tmp; VALUE w1, w2; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; if (v1->v_type == V_OCTET) { w1.v_type = V_NUM; w1.v_subtype = V_NOSUBTYPE; w1.v_num = itoq((unsigned char) *v1->v_octet); v1 = &w1; } if (v2->v_type == V_OCTET) { w2.v_type = V_NUM; w2.v_subtype = V_NOSUBTYPE; w2.v_num = itoq((unsigned char) *v2->v_octet); v2 = &w2; } subvalue(v1, v2, &tmp); if (v1 == &w1) qfree(w1.v_num); if (v2 == &w2) qfree(w2.v_num); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_mul(void){ VALUE *v1, *v2; VALUE tmp; VALUE w1, w2; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; if (v1->v_type == V_OCTET) { w1.v_type = V_NUM; w1.v_subtype = V_NOSUBTYPE; w1.v_num = itoq(*v1->v_octet); v1 = &w1; } if (v2->v_type == V_OCTET) { w2.v_type = V_NUM; w2.v_subtype = V_NOSUBTYPE; w2.v_num = itoq(*v2->v_octet); v2 = &w2; } mulvalue(v1, v2, &tmp); if (v1 == &w1) qfree(w1.v_num); if (v2 == &w2) qfree(w2.v_num); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_power(void){ VALUE *v1, *v2; VALUE tmp; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; powivalue(v1, v2, &tmp); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_div(void){ VALUE *v1, *v2; VALUE tmp; VALUE w1, w2; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; if (v1->v_type == V_OCTET) { w1.v_type = V_NUM; w1.v_subtype = V_NOSUBTYPE; w1.v_num = itoq(*v1->v_octet); v1 = &w1; } if (v2->v_type == V_OCTET) { w2.v_type = V_NUM; w2.v_subtype = V_NOSUBTYPE; w2.v_num = itoq(*v2->v_octet); v2 = &w2; } divvalue(v1, v2, &tmp); if (v1 == &w1) qfree(w1.v_num); if (v2 == &w2) qfree(w2.v_num); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_quo(void){ VALUE *v1, *v2; VALUE tmp, null; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; null.v_type = V_NULL; null.v_subtype = V_NOSUBTYPE; quovalue(v1, v2, &null, &tmp); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_mod(void){ VALUE *v1, *v2; VALUE tmp, null; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; null.v_type = V_NULL; null.v_subtype = V_NOSUBTYPE; modvalue(v1, v2, &null, &tmp); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_and(void){ VALUE *v1, *v2; VALUE tmp; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; andvalue(v1, v2, &tmp); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_or(void){ VALUE *v1, *v2; VALUE tmp; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; orvalue(v1, v2, &tmp); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_xor (void){ VALUE *v1, *v2; VALUE tmp; v1 = &stack[-1]; v2 = &stack[0]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; xorvalue(v1, v2, &tmp); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_comp (void){ VALUE *vp; VALUE tmp; vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; compvalue(vp, &tmp); freevalue(stack); *stack = tmp;}static voido_not(void){ VALUE *vp; VALUE val; int r = 0; vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; if (vp->v_type == V_OBJ) { val = objcall(OBJ_NOT, vp, NULL_VALUE, NULL_VALUE); freevalue(stack); *stack = val; return; } r = testvalue(vp); freevalue(stack); stack->v_num = (r ? qlink(&_qzero_) : qlink(&_qone_)); stack->v_type = V_NUM; stack->v_subtype = V_NOSUBTYPE;}static voido_plus (void){ VALUE *vp; VALUE tmp; vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; tmp.v_type = V_NULL; tmp.v_subtype = V_NOSUBTYPE; switch (vp->v_type) { case V_OBJ: tmp = objcall(OBJ_PLUS, vp, NULL_VALUE, NULL_VALUE); break; case V_LIST: addlistitems(vp->v_list, &tmp); break; default: return; } freevalue(stack); *stack = tmp;}static voido_negate(void){ VALUE *vp; NUMBER *q; VALUE tmp; vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; if (vp->v_type == V_NUM) { q = qneg(vp->v_num); if (stack->v_type == V_NUM) qfree(stack->v_num); stack->v_num = q; stack->v_type = V_NUM; stack->v_subtype = V_NOSUBTYPE; return; } negvalue(vp, &tmp); freevalue(stack); *stack = tmp;}static voido_invert(void){ VALUE *vp; VALUE tmp; vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; invertvalue(vp, &tmp); freevalue(stack); *stack = tmp;}static voido_scale(void){ VALUE *v1, *v2; VALUE tmp; v1 = &stack[0]; v2 = &stack[-1]; if (v1->v_type == V_ADDR) v1 = v1->v_addr; if (v2->v_type == V_ADDR) v2 = v2->v_addr; scalevalue(v2, v1, &tmp); freevalue(stack--); freevalue(stack); *stack = tmp;}static voido_int(void){ VALUE *vp; VALUE tmp; vp = stack; if (vp->v_type == V_ADDR) vp = vp->v_addr; intvalue(vp, &tmp); freevalue(stack); *stack = tmp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -