// A virtual-machine to execute a bytecode program based on a mathematical expression #include typedef double calc_real_t; typedef uint64_t calc_natural_t; typedef int64_t calc_integer_t; typedef calc_real_t[2] calc_complex_t; typedef struct { uint32_t m_poffset; uint32_t m_size; } calc_vector_t; typedef ptrdiff_t calc_idx_t; typedef uint8_t calc_type_t; enum CALC_TYPE { CALC_TYPE_NIL = 0, CALC_TYPE_F64 = 1, CALC_TYPE_I64 = 2, CALC_TYPE_U64 = 3, CALC_MOD_VECTOR = 4, CALC_UNIT_RAD = 0 CALC_UNIT_DEG = 8, CALC_UNIT_GRAD = 16, CALC_FORMAT_RECT = 0 CALC_FORMAT_POLAR = 32, }; struct calc_stack_value_t { union { calc_integer_t m_integer; calc_natural_t m_natural; calc_real_t m_real; calc_complex_t m_complex; calc_vector_t m_vector; } }; struct calc_state_t { calc_stack_value_t* m_pstack; calc_type_t* m_pstacktypes; uint8_t* m_pmem; uint8_t* m_pprogram; size_t m_stacksize; size_t m_memsize; size_t m_programsize; }; void calc_push_real(calc_state_t* state, double val); void calc_push_natural(calc_state_t* state, uint64_t val); void calc_push_integer(calc_state_t* state, int64_t val); void calc_push_complex(calc_state_t* state, calc_real_t re, calc_real_t im); void calc_push_real_vector(calc_state_t* state, size_t num_elements, calc_real_t* vals); void calc_push_natural_vector(calc_state_t* state, size_t num_elements, calc_real_t* vals); void calc_push_integer_vector(calc_state_t* state, size_t num_elements, calc_real_t* vals); void calc_push_complex_vector(calc_state_t* state, size_t num_elements, calc_stack_value_t* vals); calc_type_t calc_type(calc_state_t* state, calc_idx_t idx); const char* calc_typename(calc_state_t* state, calc_idx_t idx); calc_real_t calc_toreal(calc_state_t* state, calc_idx_t idx); calc_natural_t calc_tonatural(calc_state_t* state, calc_idx_t idx); calc_integer_t calc_tointeger(calc_state_t* state, calc_idx_t idx); calc_complex_t calc_tocomplex(calc_state_t* state, calc_idx_t idx); void calc_pop(calc_state_t* state, size_t num_items); void calc_remove(calc_state_t* state, calc_idx_t index); void calc_insert(calc_state_t* state, calc_idx_t dstidx, calc_idx_t srcidx); void calc_swap(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_push(calc_state_t* state, calc_idx_t srcidx); void calc_settype(calc_state_t* state, calc_idx_t idx, calc_type_t newtype); void calc_typemod_degrees(calc_state_t* state, calc_idx_t idx); void calc_typemod_radians(calc_state_t* state, calc_idx_t idx); void calc_typemod_gradient(calc_state_t* state, calc_idx_t idx); void calc_typemod_rectangular(calc_state_t* state, calc_idx_t idx); void calc_typemod_polar(calc_state_t* state, calc_idx_t idx); void calc_reinterpretreal(calc_state_t* state, calc_idx_t idx); void calc_reinterpretnatural(calc_state_t* state, calc_idx_t idx); void calc_reinterpretinteger(calc_state_t* state, calc_idx_t idx); void calc_reinterpretcomplex(calc_state_t* state, calc_idx_t idx); void calc_castreal(calc_state_t* state, calc_idx_t idx); void calc_castnatural(calc_state_t* state, calc_idx_t idx); void calc_castinteger(calc_state_t* state, calc_idx_t idx); void calc_castcomplex(calc_state_t* state, calc_idx_t idx); void calc_store_real(calc_state_t* state, size_t addr, calc_idx_t idx); void calc_store_natural(calc_state_t* state, size_t addr, calc_idx_t idx); void calc_store_integer(calc_state_t* state, size_t addr, calc_idx_t idx); void calc_store_complex(calc_state_t* state, size_t addr, calc_idx_t idx); void calc_store_vector(calc_state_t* state, size_t addr, calc_idx_t idx); void calc_load_real(calc_state_t* state, size_t addr); void calc_load_natural(calc_state_t* state, size_t addr); void calc_load_integer(calc_state_t* state, size_t addr); void calc_load_complex(calc_state_t* state, size_t addr); void calc_load_vector(calc_state_t* state, size_t addr); void calc_create_complex(calc_state_t* state, calc_idx_t idxre, calc_idx_t idxim); // Generic unary ops void calc_op_negate(calc_state_t* state, calc_idx_t idx); void calc_op_conjugate(calc_state_t* state, calc_idx_t idx); void calc_op_abs(calc_state_t* state, calc_idx_t idx); void calc_op_sqrt(calc_state_t* state, calc_idx_t idx); void calc_op_square(calc_state_t* state, calc_idx_t idx); void calc_op_recip(calc_state_t* state, calc_idx_t idx); void calc_op_ceil(calc_state_t* state, calc_idx_t idx); void calc_op_floor(calc_state_t* state, calc_idx_t idx); void calc_op_round(calc_state_t* state, calc_idx_t idx); void calc_op_real(calc_state_t* state, calc_idx_t idx); void calc_op_imag(calc_state_t* state, calc_idx_t idx); void calc_op_sin(calc_state_t* state, calc_idx_t idx); void calc_op_cos(calc_state_t* state, calc_idx_t idx); void calc_op_tan(calc_state_t* state, calc_idx_t idx); void calc_op_asin(calc_state_t* state, calc_idx_t idx); void calc_op_acos(calc_state_t* state, calc_idx_t idx); void calc_op_atan(calc_state_t* state, calc_idx_t idx); void calc_op_sinh(calc_state_t* state, calc_idx_t idx); void calc_op_cosh(calc_state_t* state, calc_idx_t idx); void calc_op_tanh(calc_state_t* state, calc_idx_t idx); void calc_op_asinh(calc_state_t* state, calc_idx_t idx); void calc_op_acosh(calc_state_t* state, calc_idx_t idx); void calc_op_atanh(calc_state_t* state, calc_idx_t idx); // Generic binary ops void calc_op_add(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_sub(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_mul(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_div(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_floor2(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_ceil2(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_round2(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_mod(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_atan2(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_pow(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_root(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); // Vector ops void calc_op_dot(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_cross(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_conv(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_fft(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_ifft(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_vset1(calc_state_t* state, calc_idx_t idxa); // Multi-arg ops void calc_op_reduce_add(calc_state_t* state, calc_idx_t idxbase, size_t nargs); void calc_op_reduce_rcpadd(calc_state_t* state, calc_idx_t idxbase, size_t nargs); void calc_op_reduce_addsub(calc_state_t* state, calc_idx_t idxbase, size_t nargs); void calc_op_reduce_rcpaddsub(calc_state_t* state, calc_idx_t idxbase, size_t nargs); void calc_op_reduce_product(calc_state_t* state, calc_idx_t idxbase, size_t nargs); // Takes a list of impedances and computes the equivalent series impedance void calc_op_ee_parallel(calc_state_t* state, calc_idx_t idxbase, size_t nargs); // Bitwise void calc_op_bnot(calc_state_t* state, calc_idx_t idxa); void calc_op_bpopcnt(calc_state_t* state, calc_idx_t idxa); void calc_op_band(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_bor(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_bxor(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_bnand(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_bnor(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_bxnor(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_bashl(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_bashr(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_blshl(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_blshr(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_brotr(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_brotl(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_bget(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_bset(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_breset(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb); void calc_op_btoggle(calc_state_t* state, calc_idx_t idxa, calc_idx_t idxb);