// sine struct variable *sys_sin(struct context *context) // radians { struct variable *arguments = (struct variable*)stack_pop(context->operand_stack); const int32_t n = ((struct variable*)array_get(arguments->list.ordered, 1))->integer; double s = sin(n); return variable_new_float(context, s); }
static void push_float(struct context *context, struct byte_array *program) { null_check(program); float num = serial_decode_float(program); VM_DEBUGPRINT("FLT %f\n", num); struct variable* var = variable_new_float(context, num); variable_push(context, var); }
static void unary_op(struct context *context, enum Opcode op) { if (!context->runtime) VM_DEBUGPRINT("%s\n", NUM_TO_STRING(opcodes, op)); struct variable *v = (struct variable*)variable_pop(context); struct variable *result = NULL; switch (v->type) { case VAR_NIL: { switch (op) { case VM_NEG: result = variable_new_nil(context); break; case VM_NOT: result = variable_new_bool(context, true); break; default: vm_exit_message(context, "bad math operator"); break; } } break; case VAR_INT: { int32_t n = v->integer; switch (op) { case VM_NEG: result = variable_new_int(context, -n); break; case VM_NOT: result = variable_new_bool(context, !n); break; case VM_INV: result = variable_new_int(context, ~n); break; default: vm_exit_message(context, "bad math operator"); break; } } break; case VAR_FLT: { float n = v->floater; switch (op) { case VM_NEG: result = variable_new_float(context, -n); break; case VM_NOT: result = variable_new_bool(context, !n); break; default: vm_exit_message(context, "bad math operator"); break; } } break; default: if (op == VM_NOT) result = variable_new_bool(context, false); else vm_exit_message(context, "bad math type"); break; } variable_push(context, result); DEBUGPRINT("%s(%s) = %s\n", NUM_TO_STRING(opcodes, op), variable_value_str(context, v), variable_value_str(context, result)); }
static struct variable *binary_op_float(struct context *context, enum Opcode op, const struct variable *u, const struct variable *v) { float m = u->floater; float n = v->floater; float f = 0; switch (op) { case VM_MUL: f = m * n; break; case VM_DIV: f = m / n; break; case VM_ADD: f = m + n; break; case VM_SUB: f = m - n; break; case VM_NEQ: f = m != n; break; case VM_GTN: return variable_new_int(context, n > m); case VM_LTN: return variable_new_int(context, n < m); case VM_GRQ: return variable_new_int(context, n >= m); case VM_LEQ: return variable_new_int(context, n <= m); default: return (struct variable*)vm_exit_message(context, "bad math float operator"); } return variable_new_float(context, f); }