diff options
Diffstat (limited to 'src/program.c')
-rw-r--r-- | src/program.c | 1108 |
1 files changed, 703 insertions, 405 deletions
diff --git a/src/program.c b/src/program.c index 7c38ef547a82..20121828fa92 100644 --- a/src/program.c +++ b/src/program.c @@ -54,7 +54,9 @@ * @param p The program. * @param f The new function. */ -static inline void bc_program_setVecs(BcProgram *p, BcFunc *f) { +static inline void +bc_program_setVecs(BcProgram* p, BcFunc* f) +{ BC_SIG_ASSERT_LOCKED; p->consts = &f->consts; p->strs = &f->strs; @@ -65,8 +67,9 @@ static inline void bc_program_setVecs(BcProgram *p, BcFunc *f) { * @param r The result that will be checked. * @param n The result's number. */ -static inline void bc_program_type_num(BcResult *r, BcNum *n) { - +static inline void +bc_program_type_num(BcResult* r, BcNum* n) +{ #if BC_ENABLED // This should have already been taken care of. @@ -84,7 +87,9 @@ static inline void bc_program_type_num(BcResult *r, BcNum *n) { * @param r The result to check. * @param t The type that the result should be. */ -static void bc_program_type_match(BcResult *r, BcType t) { +static void +bc_program_type_match(BcResult* r, BcType t) +{ if (BC_ERR((r->t != BC_RESULT_ARRAY) != (!t))) bc_err(BC_ERR_EXEC_TYPE); } #endif // BC_ENABLED @@ -98,12 +103,14 @@ static void bc_program_type_match(BcResult *r, BcType t) { * updated. * @return The index at @a bgn in the bytecode vector. */ -static size_t bc_program_index(const char *restrict code, size_t *restrict bgn) +static size_t +bc_program_index(const char* restrict code, size_t* restrict bgn) { uchar amt = (uchar) code[(*bgn)++], i = 0; size_t res = 0; - for (; i < amt; ++i, ++(*bgn)) { + for (; i < amt; ++i, ++(*bgn)) + { size_t temp = ((size_t) ((int) (uchar) code[*bgn]) & UCHAR_MAX); res |= (temp << (i * CHAR_BIT)); } @@ -117,8 +124,10 @@ static size_t bc_program_index(const char *restrict code, size_t *restrict bgn) * @param n The number tied to the result. * @return The string corresponding to the result and number. */ -static char* bc_program_string(BcProgram *p, const BcNum *n) { - BcFunc *f = bc_vec_item(&p->fns, n->rdx); +static char* +bc_program_string(BcProgram* p, const BcNum* n) +{ + BcFunc* f = bc_vec_item(&p->fns, n->rdx); return *((char**) bc_vec_item(&f->strs, n->scale)); } @@ -130,12 +139,15 @@ static char* bc_program_string(BcProgram *p, const BcNum *n) { * their respective stacks. * @param p The program. */ -static void bc_program_prepGlobals(BcProgram *p) { - +static void +bc_program_prepGlobals(BcProgram* p) +{ size_t i; for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) + { bc_vec_push(p->globals_v + i, p->globals + i); + } #if BC_ENABLE_EXTRA_MATH bc_rand_push(&p->rng); @@ -149,14 +161,16 @@ static void bc_program_prepGlobals(BcProgram *p) { * @param reset True if all but one item on each stack should be popped, false * otherwise. */ -static void bc_program_popGlobals(BcProgram *p, bool reset) { - +static void +bc_program_popGlobals(BcProgram* p, bool reset) +{ size_t i; BC_SIG_ASSERT_LOCKED; - for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) { - BcVec *v = p->globals_v + i; + for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) + { + BcVec* v = p->globals_v + i; bc_vec_npop(v, reset ? v->len - 1 : 1); p->globals[i] = BC_PROG_GLOBAL(v); } @@ -172,9 +186,10 @@ static void bc_program_popGlobals(BcProgram *p, bool reset) { * @param vec The reference vector. * @return A pointer to the desired array. */ -static BcVec* bc_program_dereference(const BcProgram *p, BcVec *vec) { - - BcVec *v; +static BcVec* +bc_program_dereference(const BcProgram* p, BcVec* vec) +{ + BcVec* v; size_t vidx, nidx, i = 0; // We want to be sure we have a reference vector. @@ -201,7 +216,8 @@ static BcVec* bc_program_dereference(const BcProgram *p, BcVec *vec) { * @param dig The BcBigDig to push onto the results stack. * @param type The type that the pushed result should be. */ -static void bc_program_pushBigdig(BcProgram *p, BcBigDig dig, BcResultType type) +static void +bc_program_pushBigdig(BcProgram* p, BcBigDig dig, BcResultType type) { BcResult res; @@ -215,11 +231,12 @@ static void bc_program_pushBigdig(BcProgram *p, BcBigDig dig, BcResultType type) BC_SIG_UNLOCK; } -size_t bc_program_addString(BcProgram *p, const char *str, size_t fidx) { - - BcFunc *f; - char **str_ptr; - BcVec *slabs; +size_t +bc_program_addString(BcProgram* p, const char* str, size_t fidx) +{ + BcFunc* f; + char** str_ptr; + BcVec* slabs; BC_SIG_ASSERT_LOCKED; @@ -229,16 +246,19 @@ size_t bc_program_addString(BcProgram *p, const char *str, size_t fidx) { // Figure out which slab vector to use. slabs = fidx == BC_PROG_MAIN || fidx == BC_PROG_READ ? - &vm.main_slabs : &vm.other_slabs; + &vm.main_slabs : + &vm.other_slabs; *str_ptr = bc_slabvec_strdup(slabs, str); return f->strs.len - 1; } -size_t bc_program_search(BcProgram *p, const char *id, bool var) { - - BcVec *v, *map; +size_t +bc_program_search(BcProgram* p, const char* id, bool var) +{ + BcVec* v; + BcVec* map; size_t i; BC_SIG_ASSERT_LOCKED; @@ -251,8 +271,9 @@ size_t bc_program_search(BcProgram *p, const char *id, bool var) { // the parser calls this function. If the insert succeeds, we create a stack // for the variable/array. But regardless, bc_map_insert() gives us the // index of the item in i. - if (bc_map_insert(map, id, v->len, &i)) { - BcVec *temp = bc_vec_pushEmpty(v); + if (bc_map_insert(map, id, v->len, &i)) + { + BcVec* temp = bc_vec_pushEmpty(v); bc_array_init(temp, var); } @@ -267,9 +288,10 @@ size_t bc_program_search(BcProgram *p, const char *id, bool var) { * @param type The type of vector to return. * @return A pointer to the variable or array stack. */ -static inline BcVec* bc_program_vec(const BcProgram *p, size_t idx, BcType type) +static inline BcVec* +bc_program_vec(const BcProgram* p, size_t idx, BcType type) { - const BcVec *v = (type == BC_TYPE_VAR) ? &p->vars : &p->arrs; + const BcVec* v = (type == BC_TYPE_VAR) ? &p->vars : &p->arrs; return bc_vec_item(v, idx); } @@ -284,9 +306,10 @@ static inline BcVec* bc_program_vec(const BcProgram *p, size_t idx, BcType type) * @param r The result whose number will be returned. * @return The BcNum corresponding to the result. */ -static BcNum* bc_program_num(BcProgram *p, BcResult *r) { - - BcNum *n; +static BcNum* +bc_program_num(BcProgram* p, BcResult* r) +{ + BcNum* n; #ifdef _WIN32 // Windows made it an error to not initialize this, so shut it up. @@ -296,8 +319,8 @@ static BcNum* bc_program_num(BcProgram *p, BcResult *r) { n = NULL; #endif // _WIN32 - switch (r->t) { - + switch (r->t) + { case BC_RESULT_STR: case BC_RESULT_TEMP: case BC_RESULT_IBASE: @@ -315,7 +338,7 @@ static BcNum* bc_program_num(BcProgram *p, BcResult *r) { case BC_RESULT_ARRAY: case BC_RESULT_ARRAY_ELEM: { - BcVec *v; + BcVec* v; BcType type = (r->t == BC_RESULT_VAR) ? BC_TYPE_VAR : BC_TYPE_ARRAY; // Get the correct variable or array vector. @@ -325,8 +348,8 @@ static BcNum* bc_program_num(BcProgram *p, BcResult *r) { // it's returning an array element. This is because we have to dig // deeper to get *to* the element. That's what the code inside this // if statement does. - if (r->t == BC_RESULT_ARRAY_ELEM) { - + if (r->t == BC_RESULT_ARRAY_ELEM) + { size_t idx = r->d.loc.idx; v = bc_vec_top(v); @@ -349,7 +372,8 @@ static BcNum* bc_program_num(BcProgram *p, BcResult *r) { // an element *way* out there, we have to preinitialize all // elements between the current last element and the actual // accessed element. - if (v->len <= idx) { + if (v->len <= idx) + { BC_SIG_LOCK; bc_array_expand(v, bc_vm_growSize(idx, 1)); BC_SIG_UNLOCK; @@ -385,7 +409,7 @@ static BcNum* bc_program_num(BcProgram *p, BcResult *r) { abort(); } #endif // NDEBUG - // Fallthrough + // Fallthrough case BC_RESULT_LAST: { n = &p->last; @@ -406,8 +430,8 @@ static BcNum* bc_program_num(BcProgram *p, BcResult *r) { * we care about. * @param idx The index of the result from the top of the results stack. */ -static void bc_program_operand(BcProgram *p, BcResult **r, - BcNum **n, size_t idx) +static void +bc_program_operand(BcProgram* p, BcResult** r, BcNum** n, size_t idx) { *r = bc_vec_item_rev(&p->results, idx); @@ -432,8 +456,9 @@ static void bc_program_operand(BcProgram *p, BcResult **r, * @param idx The starting index where the operands are in the results stack, * starting from the top. */ -static void bc_program_binPrep(BcProgram *p, BcResult **l, BcNum **ln, - BcResult **r, BcNum **rn, size_t idx) +static void +bc_program_binPrep(BcProgram* p, BcResult** l, BcNum** ln, BcResult** r, + BcNum** rn, size_t idx) { BcResultType lt; @@ -441,9 +466,12 @@ static void bc_program_binPrep(BcProgram *p, BcResult **l, BcNum **ln, #ifndef BC_PROG_NO_STACK_CHECK // Check the stack for dc. - if (BC_IS_DC) { + if (BC_IS_DC) + { if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 2))) + { bc_err(BC_ERR_EXEC_STACK); + } } #endif // BC_PROG_NO_STACK_CHECK @@ -464,7 +492,9 @@ static void bc_program_binPrep(BcProgram *p, BcResult **l, BcNum **ln, // reallocated out from under the BcNums or arrays we had. In other words, // this is to fix pointer invalidation. if (lt == (*r)->t && (lt == BC_RESULT_VAR || lt == BC_RESULT_ARRAY_ELEM)) + { *ln = bc_program_num(p, *l); + } if (BC_ERR(lt == BC_RESULT_STR)) bc_err(BC_ERR_EXEC_TYPE); } @@ -485,8 +515,9 @@ static void bc_program_binPrep(BcProgram *p, BcResult **l, BcNum **ln, * @param idx The starting index where the operands are in the results stack, * starting from the top. */ -static void bc_program_binOpPrep(BcProgram *p, BcResult **l, BcNum **ln, - BcResult **r, BcNum **rn, size_t idx) +static void +bc_program_binOpPrep(BcProgram* p, BcResult** l, BcNum** ln, BcResult** r, + BcNum** rn, size_t idx) { bc_program_binPrep(p, l, ln, r, rn, idx); bc_program_type_num(*l, *ln); @@ -505,8 +536,9 @@ static void bc_program_binOpPrep(BcProgram *p, BcResult **l, BcNum **ln, * @param rn An out parameter; this is set to the pointer to the number for the * right operand. */ -static void bc_program_assignPrep(BcProgram *p, BcResult **l, BcNum **ln, - BcResult **r, BcNum **rn) +static void +bc_program_assignPrep(BcProgram* p, BcResult** l, BcNum** ln, BcResult** r, + BcNum** rn) { BcResultType lt, min; @@ -541,15 +573,19 @@ static void bc_program_assignPrep(BcProgram *p, BcResult **l, BcNum **ln, * we care about. * @param idx The index of the result from the top of the results stack. */ -static void bc_program_prep(BcProgram *p, BcResult **r, BcNum **n, size_t idx) { - +static void +bc_program_prep(BcProgram* p, BcResult** r, BcNum** n, size_t idx) +{ assert(p != NULL && r != NULL && n != NULL); #ifndef BC_PROG_NO_STACK_CHECK // Check the stack for dc. - if (BC_IS_DC) { + if (BC_IS_DC) + { if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1))) + { bc_err(BC_ERR_EXEC_STACK); + } } #endif // BC_PROG_NO_STACK_CHECK @@ -566,9 +602,10 @@ static void bc_program_prep(BcProgram *p, BcResult **r, BcNum **n, size_t idx) { * @param p The program. * @return A clean result. */ -static BcResult* bc_program_prepResult(BcProgram *p) { - - BcResult *res = bc_vec_pushEmpty(&p->results); +static BcResult* +bc_program_prepResult(BcProgram* p) +{ + BcResult* res = bc_vec_pushEmpty(&p->results); bc_result_clear(res); @@ -584,19 +621,21 @@ static BcResult* bc_program_prepResult(BcProgram *p) { * @param bgn An in/out parameter; marks the start of the index in the * bytecode vector and will be updated to point to after the index. */ -static void bc_program_const(BcProgram *p, const char *code, size_t *bgn) { - +static void +bc_program_const(BcProgram* p, const char* code, size_t* bgn) +{ // I lied. I actually push the result first. I can do this because the // result will be popped on error. I also get the constant itself. - BcResult *r = bc_program_prepResult(p); - BcConst *c = bc_vec_item(p->consts, bc_program_index(code, bgn)); + BcResult* r = bc_program_prepResult(p); + BcConst* c = bc_vec_item(p->consts, bc_program_index(code, bgn)); BcBigDig base = BC_PROG_IBASE(p); // Only reparse if the base changed. - if (c->base != base) { - + if (c->base != base) + { // Allocate if we haven't yet. - if (c->num.num == NULL) { + if (c->num.num == NULL) + { BC_SIG_LOCK; bc_num_init(&c->num, BC_NUM_RDX(strlen(c->val))); BC_SIG_UNLOCK; @@ -620,10 +659,14 @@ static void bc_program_const(BcProgram *p, const char *code, size_t *bgn) { * @param p The program. * @param inst The instruction corresponding to the binary operator to execute. */ -static void bc_program_op(BcProgram *p, uchar inst) { - - BcResult *opd1, *opd2, *res; - BcNum *n1, *n2; +static void +bc_program_op(BcProgram* p, uchar inst) +{ + BcResult* opd1; + BcResult* opd2; + BcResult* res; + BcNum* n1; + BcNum* n2; size_t idx = inst - BC_INST_POWER; res = bc_program_prepResult(p); @@ -652,19 +695,21 @@ static void bc_program_op(BcProgram *p, uchar inst) { * Executes a read() or ? command. * @param p The program. */ -static void bc_program_read(BcProgram *p) { - +static void +bc_program_read(BcProgram* p) +{ BcStatus s; BcInstPtr ip; size_t i; const char* file; bool is_stdin; - BcFunc *f = bc_vec_item(&p->fns, BC_PROG_READ); + BcFunc* f = bc_vec_item(&p->fns, BC_PROG_READ); // If we are already executing a read, that is an error. So look for a read // and barf. - for (i = 0; i < p->stack.len; ++i) { - BcInstPtr *ip_ptr = bc_vec_item(&p->stack, i); + for (i = 0; i < p->stack.len; ++i) + { + BcInstPtr* ip_ptr = bc_vec_item(&p->stack, i); if (ip_ptr->func == BC_PROG_READ) bc_err(BC_ERR_EXEC_REC_READ); } @@ -678,8 +723,8 @@ static void bc_program_read(BcProgram *p) { // this to tell the lexer to not request more. We set it back later. vm.is_stdin = false; - if (!BC_PARSE_IS_INITED(&vm.read_prs, p)) { - + if (!BC_PARSE_IS_INITED(&vm.read_prs, p)) + { // We need to parse, but we don't want to use the existing parser // because it has state it needs to keep. (It could have a partial parse // state.) So we create a new parser. This parser is in the BcVm struct @@ -746,7 +791,8 @@ static void bc_program_read(BcProgram *p) { #if DC_ENABLED // We need a new tail call entry for dc. - if (BC_IS_DC) { + if (BC_IS_DC) + { size_t temp = 0; bc_vec_push(&p->tail_calls, &temp); } @@ -765,8 +811,9 @@ exec_err: * Execute a rand(). * @param p The program. */ -static void bc_program_rand(BcProgram *p) { - +static void +bc_program_rand(BcProgram* p) +{ BcRand rand = bc_rand_int(&p->rng); bc_program_pushBigdig(p, (BcBigDig) rand, BC_RESULT_TEMP); @@ -775,7 +822,7 @@ static void bc_program_rand(BcProgram *p) { // This is just to ensure that the generated number is correct. I also use // braces because I declare every local at the top of the scope. { - BcResult *r = bc_vec_top(&p->results); + BcResult* r = bc_vec_top(&p->results); assert(BC_NUM_RDX_VALID_NP(r->d.n)); } #endif // NDEBUG @@ -786,9 +833,10 @@ static void bc_program_rand(BcProgram *p) { * Prints a series of characters, without escapes. * @param str The string (series of characters). */ -static void bc_program_printChars(const char *str) { - - const char *nl; +static void +bc_program_printChars(const char* str) +{ + const char* nl; size_t len = vm.nchars + strlen(str); sig_atomic_t lock; @@ -811,37 +859,40 @@ static void bc_program_printChars(const char *str) { * Prints a string with escapes. * @param str The string. */ -static void bc_program_printString(const char *restrict str) { - +static void +bc_program_printString(const char* restrict str) +{ size_t i, len = strlen(str); #if DC_ENABLED // This is to ensure a nul byte is printed for dc's stream operation. - if (!len && BC_IS_DC) { + if (!len && BC_IS_DC) + { bc_vm_putchar('\0', bc_flush_save); return; } #endif // DC_ENABLED // Loop over the characters, processing escapes and printing the rest. - for (i = 0; i < len; ++i) { - + for (i = 0; i < len; ++i) + { int c = str[i]; // If we have an escape... - if (c == '\\' && i != len - 1) { - - const char *ptr; + if (c == '\\' && i != len - 1) + { + const char* ptr; // Get the escape character and its companion. c = str[++i]; ptr = strchr(bc_program_esc_chars, c); // If we have a companion character... - if (ptr != NULL) { - + if (ptr != NULL) + { // We need to specially handle a newline. - if (c == 'n') { + if (c == 'n') + { BC_SIG_LOCK; vm.nchars = UINT16_MAX; BC_SIG_UNLOCK; @@ -850,7 +901,8 @@ static void bc_program_printString(const char *restrict str) { // Grab the actual character. c = bc_program_esc_seqs[(size_t) (ptr - bc_program_esc_chars)]; } - else { + else + { // Just print the backslash if there is no companion character. // The following character will be printed later after the outer // if statement. @@ -868,19 +920,23 @@ static void bc_program_printString(const char *restrict str) { * @param inst The instruction for the type of print we are doing. * @param idx The index of the result that we are printing. */ -static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { - - BcResult *r; - char *str; - BcNum *n; +static void +bc_program_print(BcProgram* p, uchar inst, size_t idx) +{ + BcResult* r; + char* str; + BcNum* n; bool pop = (inst != BC_INST_PRINT); assert(p != NULL); #ifndef BC_PROG_NO_STACK_CHECK - if (BC_IS_DC) { + if (BC_IS_DC) + { if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1))) + { bc_err(BC_ERR_EXEC_STACK); + } } #endif // BC_PROG_NO_STACK_CHECK @@ -893,7 +949,8 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { // true because that means that we are executing a print statement, but // attempting to do a print on a lone void value is allowed because that's // exactly how we want void values used. - if (r->t == BC_RESULT_VOID) { + if (r->t == BC_RESULT_VOID) + { if (BC_ERR(pop)) bc_err(BC_ERR_EXEC_VOID_VAL); bc_vec_pop(&p->results); return; @@ -903,8 +960,8 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { n = bc_program_num(p, r); // If we have a number... - if (BC_PROG_NUM(r, n)) { - + if (BC_PROG_NUM(r, n)) + { #if BC_ENABLED assert(inst != BC_INST_PRINT_STR); #endif // BC_ENABLED @@ -917,8 +974,8 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { if (BC_IS_BC) bc_num_copy(&p->last, n); #endif // BC_ENABLED } - else { - + else + { // We want to flush any stuff in the stdout buffer first. bc_file_flush(&vm.fout, bc_flush_save); str = bc_program_string(p, n); @@ -931,8 +988,7 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { bc_program_printString(str); // Need to print a newline only in this case. - if (inst == BC_INST_PRINT) - bc_vm_putchar('\n', bc_flush_err); + if (inst == BC_INST_PRINT) bc_vm_putchar('\n', bc_flush_err); } } @@ -940,17 +996,23 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { if (BC_IS_BC || pop) bc_vec_pop(&p->results); } -void bc_program_negate(BcResult *r, BcNum *n) { +void +bc_program_negate(BcResult* r, BcNum* n) +{ bc_num_copy(&r->d.n, n); if (BC_NUM_NONZERO(&r->d.n)) BC_NUM_NEG_TGL_NP(r->d.n); } -void bc_program_not(BcResult *r, BcNum *n) { +void +bc_program_not(BcResult* r, BcNum* n) +{ if (!bc_num_cmpZero(n)) bc_num_one(&r->d.n); } #if BC_ENABLE_EXTRA_MATH -void bc_program_trunc(BcResult *r, BcNum *n) { +void +bc_program_trunc(BcResult* r, BcNum* n) +{ bc_num_copy(&r->d.n, n); bc_num_truncate(&r->d.n, n->scale); } @@ -961,10 +1023,12 @@ void bc_program_trunc(BcResult *r, BcNum *n) { * @param p The program. * @param inst The unary operation. */ -static void bc_program_unary(BcProgram *p, uchar inst) { - - BcResult *res, *ptr; - BcNum *num; +static void +bc_program_unary(BcProgram* p, uchar inst) +{ + BcResult* res; + BcResult* ptr; + BcNum* num; res = bc_program_prepResult(p); @@ -986,10 +1050,14 @@ static void bc_program_unary(BcProgram *p, uchar inst) { * @param p The program. * @param inst The operator. */ -static void bc_program_logical(BcProgram *p, uchar inst) { - - BcResult *opd1, *opd2, *res; - BcNum *n1, *n2; +static void +bc_program_logical(BcProgram* p, uchar inst) +{ + BcResult* opd1; + BcResult* opd2; + BcResult* res; + BcNum* n1; + BcNum* n2; bool cond = 0; ssize_t cmp; @@ -1002,16 +1070,20 @@ static void bc_program_logical(BcProgram *p, uchar inst) { // Boolean and and or are not short circuiting. This is why; they can be // implemented much easier this way. if (inst == BC_INST_BOOL_AND) + { cond = (bc_num_cmpZero(n1) && bc_num_cmpZero(n2)); + } else if (inst == BC_INST_BOOL_OR) + { cond = (bc_num_cmpZero(n1) || bc_num_cmpZero(n2)); - else { - + } + else + { // We have a relational operator, so do a comparison. cmp = bc_num_cmp(n1, n2); - switch (inst) { - + switch (inst) + { case BC_INST_REL_EQ: { cond = (cmp == 0); @@ -1077,9 +1149,10 @@ static void bc_program_logical(BcProgram *p, uchar inst) { * string from the results stack and push it onto the variable * stack. */ -static void bc_program_assignStr(BcProgram *p, BcNum *num, BcVec *v, bool push) +static void +bc_program_assignStr(BcProgram* p, BcNum* num, BcVec* v, bool push) { - BcNum *n; + BcNum* n; assert(BC_PROG_STACK(&p->results, 1 + !push)); assert(num != NULL && num->num == NULL && num->cap == 0); @@ -1093,6 +1166,7 @@ static void bc_program_assignStr(BcProgram *p, BcNum *num, BcVec *v, bool push) n = bc_vec_pushEmpty(v); // We can just copy because the num should not have allocated anything. + // NOLINTNEXTLINE memcpy(n, num, sizeof(BcNum)); } @@ -1109,16 +1183,18 @@ static void bc_program_assignStr(BcProgram *p, BcNum *num, BcVec *v, bool push) * named something like "x", and a variable "x" is passed to * another parameter. */ -static void bc_program_copyToVar(BcProgram *p, size_t idx, BcType t, bool last) +static void +bc_program_copyToVar(BcProgram* p, size_t idx, BcType t, bool last) { BcResult *ptr = NULL, r; - BcVec *vec; - BcNum *n = NULL; + BcVec* vec; + BcNum* n = NULL; bool var = (t == BC_TYPE_VAR); #if DC_ENABLED // Check the stack for dc. - if (BC_IS_DC) { + if (BC_IS_DC) + { if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_err(BC_ERR_EXEC_STACK); } #endif @@ -1137,7 +1213,9 @@ static void bc_program_copyToVar(BcProgram *p, size_t idx, BcType t, bool last) // Get the variable or array, taking care to get the real item. We take // care of last with arrays later. if (!last && var) + { n = bc_vec_item_rev(bc_program_vec(p, ptr->d.loc.loc, t), 1); + } } #endif // BC_ENABLED @@ -1145,8 +1223,8 @@ static void bc_program_copyToVar(BcProgram *p, size_t idx, BcType t, bool last) // We can shortcut in dc if it's assigning a string by using // bc_program_assignStr(). - if (ptr->t == BC_RESULT_STR) { - + if (ptr->t == BC_RESULT_STR) + { assert(BC_PROG_STR(n)); if (BC_ERR(!var)) bc_err(BC_ERR_EXEC_TYPE); @@ -1159,21 +1237,27 @@ static void bc_program_copyToVar(BcProgram *p, size_t idx, BcType t, bool last) BC_SIG_LOCK; // Just create and copy for a normal variable. - if (var) { - if (BC_PROG_STR(n)) memcpy(&r.d.n, n, sizeof(BcNum)); + if (var) + { + if (BC_PROG_STR(n)) + { + // NOLINTNEXTLINE + memcpy(&r.d.n, n, sizeof(BcNum)); + } else bc_num_createCopy(&r.d.n, n); } - else { - + else + { // If we get here, we are handling an array. This is one place we need // to cast the number from bc_program_num() to a vector. - BcVec *v = (BcVec*) n, *rv = &r.d.v; + BcVec* v = (BcVec*) n; + BcVec* rv = &r.d.v; #if BC_ENABLED - if (BC_IS_BC) { - - BcVec *parent; + if (BC_IS_BC) + { + BcVec* parent; bool ref, ref_size; // We need to figure out if the parameter is a reference or not and @@ -1197,14 +1281,14 @@ static void bc_program_copyToVar(BcProgram *p, size_t idx, BcType t, bool last) ref_size = (v->size == sizeof(uchar)); // If we *should* have a reference. - if (ref || (ref_size && t == BC_TYPE_REF)) { - + if (ref || (ref_size && t == BC_TYPE_REF)) + { // Create a new reference vector. bc_vec_init(rv, sizeof(uchar), BC_DTOR_NONE); // If this is true, then we need to construct a reference. - if (ref) { - + if (ref) + { assert(parent->len >= (size_t) (!last + 1)); // Make sure the pointer was not invalidated. @@ -1233,7 +1317,9 @@ static void bc_program_copyToVar(BcProgram *p, size_t idx, BcType t, bool last) // If we get here, we have a reference, but we need an array, so // dereference the array. else if (ref_size && t != BC_TYPE_REF) + { v = bc_program_dereference(p, v); + } } #endif // BC_ENABLED @@ -1250,16 +1336,83 @@ static void bc_program_copyToVar(BcProgram *p, size_t idx, BcType t, bool last) BC_SIG_UNLOCK; } +void +bc_program_assignBuiltin(BcProgram* p, bool scale, bool obase, BcBigDig val) +{ + BcVec* v; + BcBigDig* ptr; + BcBigDig* ptr_t; + BcBigDig max, min; + + assert(!scale || !obase); + + // Scale needs handling separate from ibase and obase. + if (scale) + { + // Set the min and max. + min = 0; + max = vm.maxes[BC_PROG_GLOBALS_SCALE]; + + // Get a pointer to the stack and to the current value. + v = p->globals_v + BC_PROG_GLOBALS_SCALE; + ptr_t = p->globals + BC_PROG_GLOBALS_SCALE; + } + else + { + // Set the min and max. + min = BC_NUM_MIN_BASE; + if (BC_ENABLE_EXTRA_MATH && obase && (BC_IS_DC || !BC_IS_POSIX)) + { + min = 0; + } + max = vm.maxes[obase + BC_PROG_GLOBALS_IBASE]; + + // Get a pointer to the stack and to the current value. + v = p->globals_v + BC_PROG_GLOBALS_IBASE + obase; + ptr_t = p->globals + BC_PROG_GLOBALS_IBASE + obase; + } + + // Check for error. + if (BC_ERR(val > max || val < min)) + { + BcErr e; + + // This grabs the right error. + if (scale) e = BC_ERR_EXEC_SCALE; + else if (obase) e = BC_ERR_EXEC_OBASE; + else e = BC_ERR_EXEC_IBASE; + + bc_verr(e, min, max); + } + + // Set the top of the stack and the actual global value. + ptr = bc_vec_top(v); + *ptr = val; + *ptr_t = val; +} + +#if BC_ENABLE_EXTRA_MATH +void +bc_program_assignSeed(BcProgram* p, BcNum* val) +{ + bc_num_rng(val, &p->rng); +} +#endif // BC_ENABLE_EXTRA_MATH + /** * Executes an assignment operator. * @param p The program. * @param inst The assignment operator to execute. */ -static void bc_program_assign(BcProgram *p, uchar inst) { - +static void +bc_program_assign(BcProgram* p, uchar inst) +{ // The local use_val is true when the assigned value needs to be copied. - BcResult *left, *right, res; - BcNum *l, *r; + BcResult* left; + BcResult* right; + BcResult res; + BcNum* l; + BcNum* r; bool ob, sc, use_val = BC_INST_USE_VAL(inst); bc_program_assignPrep(p, &left, &l, &right, &r); @@ -1268,23 +1421,26 @@ static void bc_program_assign(BcProgram *p, uchar inst) { assert(left->t != BC_RESULT_STR); // If we are assigning a string... - if (right->t == BC_RESULT_STR) { - + if (right->t == BC_RESULT_STR) + { assert(BC_PROG_STR(r)); #if BC_ENABLED if (inst != BC_INST_ASSIGN && inst != BC_INST_ASSIGN_NO_VAL) + { bc_err(BC_ERR_EXEC_TYPE); + } #endif // BC_ENABLED // If we are assigning to an array element... - if (left->t == BC_RESULT_ARRAY_ELEM) { - + if (left->t == BC_RESULT_ARRAY_ELEM) + { BC_SIG_LOCK; // We need to free the number and clear it. bc_num_free(l); + // NOLINTNEXTLINE memcpy(l, r, sizeof(BcNum)); // Now we can pop the results. @@ -1292,11 +1448,11 @@ static void bc_program_assign(BcProgram *p, uchar inst) { BC_SIG_UNLOCK; } - else { - + else + { // If we get here, we are assigning to a variable, which we can use // bc_program_assignStr() for. - BcVec *v = bc_program_vec(p, left->d.loc.loc, BC_TYPE_VAR); + BcVec* v = bc_program_vec(p, left->d.loc.loc, BC_TYPE_VAR); bc_program_assignStr(p, r, v, false); } @@ -1304,8 +1460,10 @@ static void bc_program_assign(BcProgram *p, uchar inst) { // If this is true, the value is going to be used again, so we want to // push a temporary with the string. - if (inst == BC_INST_ASSIGN) { + if (inst == BC_INST_ASSIGN) + { res.t = BC_RESULT_STR; + // NOLINTNEXTLINE memcpy(&res.d.n, r, sizeof(BcNum)); bc_vec_push(&p->results, &res); } @@ -1317,8 +1475,8 @@ static void bc_program_assign(BcProgram *p, uchar inst) { } // If we have a normal assignment operator, not a math one... - if (BC_INST_IS_ASSIGN(inst)) { - + if (BC_INST_IS_ASSIGN(inst)) + { // Assigning to a variable that has a string here is fine because there // is no math done on it. @@ -1328,11 +1486,12 @@ static void bc_program_assign(BcProgram *p, uchar inst) { // type of right to BC_RESULT_ZERO in order to prevent it from being // freed. We also don't have to worry about BC_RESULT_STR because it's // take care of above. - if (right->t == BC_RESULT_TEMP || right->t >= BC_RESULT_IBASE) { - + if (right->t == BC_RESULT_TEMP || right->t >= BC_RESULT_IBASE) + { BC_SIG_LOCK; bc_num_free(l); + // NOLINTNEXTLINE memcpy(l, r, sizeof(BcNum)); right->t = BC_RESULT_ZERO; @@ -1342,8 +1501,8 @@ static void bc_program_assign(BcProgram *p, uchar inst) { else bc_num_copy(l, r); } #if BC_ENABLED - else { - + else + { // If we get here, we are doing a math assignment (+=, -=, etc.). So // we need to prepare for a binary operator. BcBigDig scale = BC_PROG_SCALE(p); @@ -1356,7 +1515,9 @@ static void bc_program_assign(BcProgram *p, uchar inst) { // Get the right type of assignment operator, whether val is used or // NO_VAL for performance. if (!use_val) + { inst -= (BC_INST_ASSIGN_POWER_NO_VAL - BC_INST_ASSIGN_POWER); + } assert(BC_NUM_RDX_VALID(l)); assert(BC_NUM_RDX_VALID(r)); @@ -1372,62 +1533,24 @@ static void bc_program_assign(BcProgram *p, uchar inst) { // The globals need special handling, especially the non-seed ones. The // first part of the if statement handles them. - if (ob || sc || left->t == BC_RESULT_IBASE) { - - BcVec *v; - BcBigDig *ptr, *ptr_t, val, max, min; - + if (ob || sc || left->t == BC_RESULT_IBASE) + { // Get the actual value. - val = bc_num_bigdig(l); - - // Scale needs handling separate from ibase and obase. - if (sc) { + BcBigDig val = bc_num_bigdig(l); - // Set the min and max. - min = 0; - max = vm.maxes[BC_PROG_GLOBALS_SCALE]; - - // Get a pointer to the stack and to the current value. - v = p->globals_v + BC_PROG_GLOBALS_SCALE; - ptr_t = p->globals + BC_PROG_GLOBALS_SCALE; - } - else { - - // Set the min and max. - min = BC_NUM_MIN_BASE; - if (BC_ENABLE_EXTRA_MATH && ob && (BC_IS_DC || !BC_IS_POSIX)) - min = 0; - max = vm.maxes[ob + BC_PROG_GLOBALS_IBASE]; - - // Get a pointer to the stack and to the current value. - v = p->globals_v + BC_PROG_GLOBALS_IBASE + ob; - ptr_t = p->globals + BC_PROG_GLOBALS_IBASE + ob; - } - - // Check for error. - if (BC_ERR(val > max || val < min)) { - - // This grabs the right error. - BcErr e = left->t - BC_RESULT_IBASE + BC_ERR_EXEC_IBASE; - - bc_verr(e, min, max); - } - - // Set the top of the stack and the actual global value. - ptr = bc_vec_top(v); - *ptr = val; - *ptr_t = val; + bc_program_assignBuiltin(p, sc, ob, val); } #if BC_ENABLE_EXTRA_MATH // To assign to steed, let bc_num_rng() do its magic. - else if (left->t == BC_RESULT_SEED) bc_num_rng(l, &p->rng); + else if (left->t == BC_RESULT_SEED) bc_program_assignSeed(p, l); #endif // BC_ENABLE_EXTRA_MATH BC_SIG_LOCK; // If we needed to use the value, then we need to copy it. Otherwise, we can // pop indiscriminately. Oh, and the copy should be a BC_RESULT_TEMP. - if (use_val) { + if (use_val) + { bc_num_createCopy(&res.d.n, l); res.t = BC_RESULT_TEMP; bc_vec_npop(&p->results, 2); @@ -1449,8 +1572,9 @@ static void bc_program_assign(BcProgram *p, uchar inst) { * @param copy True if the variable's value should be copied to the results * stack. This is only used in dc. */ -static void bc_program_pushVar(BcProgram *p, const char *restrict code, - size_t *restrict bgn, bool pop, bool copy) +static void +bc_program_pushVar(BcProgram* p, const char* restrict code, + size_t* restrict bgn, bool pop, bool copy) { BcResult r; size_t idx = bc_program_index(code, bgn); @@ -1462,23 +1586,24 @@ static void bc_program_pushVar(BcProgram *p, const char *restrict code, #if DC_ENABLED // If this condition is true, then we have the hard case, where we have to // adjust dc registers. - if (BC_IS_DC && (pop || copy)) { - + if (BC_IS_DC && (pop || copy)) + { // Get the stack for the variable and the number at the top. - BcVec *v = bc_program_vec(p, idx, BC_TYPE_VAR); - BcNum *num = bc_vec_top(v); + BcVec* v = bc_program_vec(p, idx, BC_TYPE_VAR); + BcNum* num = bc_vec_top(v); // Ensure there are enough elements on the stack. - if (BC_ERR(!BC_PROG_STACK(v, 2 - copy))) { - const char *name = bc_map_name(&p->var_map, idx); + if (BC_ERR(!BC_PROG_STACK(v, 2 - copy))) + { + const char* name = bc_map_name(&p->var_map, idx); bc_verr(BC_ERR_EXEC_STACK_REGISTER, name); } assert(BC_PROG_STACK(v, 2 - copy)); // If the top of the stack is actually a number... - if (!BC_PROG_STR(num)) { - + if (!BC_PROG_STR(num)) + { BC_SIG_LOCK; // Create a copy to go onto the results stack as appropriate. @@ -1494,9 +1619,11 @@ static void bc_program_pushVar(BcProgram *p, const char *restrict code, return; } - else { + else + { // Set the string result. We can just memcpy because all of the // fields in the num should be cleared. + // NOLINTNEXTLINE memcpy(&r.d.n, num, sizeof(BcNum)); r.t = BC_RESULT_STR; } @@ -1517,18 +1644,21 @@ static void bc_program_pushVar(BcProgram *p, const char *restrict code, * vector, and will be updated to point after the index on return. * @param inst The instruction; whether to push an array or an array element. */ -static void bc_program_pushArray(BcProgram *p, const char *restrict code, - size_t *restrict bgn, uchar inst) +static void +bc_program_pushArray(BcProgram* p, const char* restrict code, + size_t* restrict bgn, uchar inst) { - BcResult r, *operand; - BcNum *num; + BcResult r; + BcResult* operand; + BcNum* num; BcBigDig temp; // Get the index of the array. r.d.loc.loc = bc_program_index(code, bgn); // Doing an array is easy; just set the result type and finish. - if (inst == BC_INST_ARRAY) { + if (inst == BC_INST_ARRAY) + { r.t = BC_RESULT_ARRAY; bc_vec_push(&p->results, &r); return; @@ -1560,10 +1690,11 @@ static void bc_program_pushArray(BcProgram *p, const char *restrict code, * @param p The program. * @param inst The instruction; whether to do an increment or decrement. */ -static void bc_program_incdec(BcProgram *p, uchar inst) { - +static void +bc_program_incdec(BcProgram* p, uchar inst) +{ BcResult *ptr, res, copy; - BcNum *num; + BcNum* num; uchar inst2; bc_program_prep(p, &ptr, &num, 0); @@ -1611,15 +1742,15 @@ exit: * vector, and will be updated to point after the indices on * return. */ -static void bc_program_call(BcProgram *p, const char *restrict code, - size_t *restrict bgn) +static void +bc_program_call(BcProgram* p, const char* restrict code, size_t* restrict bgn) { BcInstPtr ip; size_t i, nargs; - BcFunc *f; - BcVec *v; - BcAuto *a; - BcResult *arg; + BcFunc* f; + BcVec* v; + BcAuto* a; + BcResult* arg; // Pull the number of arguments out of the bytecode vector. nargs = bc_program_index(code, bgn); @@ -1632,7 +1763,9 @@ static void bc_program_call(BcProgram *p, const char *restrict code, // Error checking. if (BC_ERR(!f->code.len)) bc_verr(BC_ERR_EXEC_UNDEF_FUNC, f->name); if (BC_ERR(nargs != f->nparams)) + { bc_verr(BC_ERR_EXEC_PARAMS, f->nparams, nargs); + } // Set the length of the results stack. We discount the argument, of course. ip.len = p->results.len - nargs; @@ -1643,8 +1776,8 @@ static void bc_program_call(BcProgram *p, const char *restrict code, if (BC_G) bc_program_prepGlobals(p); // Push the arguments onto the stacks of their respective parameters. - for (i = 0; i < nargs; ++i) { - + for (i = 0; i < nargs; ++i) + { size_t j; bool last = true; @@ -1657,12 +1790,12 @@ static void bc_program_call(BcProgram *p, const char *restrict code, // If I have already pushed to a var, I need to make sure I // get the previous version, not the already pushed one. This condition // must be true for that to even be possible. - if (arg->t == BC_RESULT_VAR || arg->t == BC_RESULT_ARRAY) { - + if (arg->t == BC_RESULT_VAR || arg->t == BC_RESULT_ARRAY) + { // Loop through all of the previous parameters. - for (j = 0; j < i && last; ++j) { - - BcAuto *aptr = bc_vec_item(&f->autos, nargs - 1 - j); + for (j = 0; j < i && last; ++j) + { + BcAuto* aptr = bc_vec_item(&f->autos, nargs - 1 - j); // This condition is true if there is a previous parameter with // the same name *and* type because variables and arrays do not @@ -1679,20 +1812,21 @@ static void bc_program_call(BcProgram *p, const char *restrict code, BC_SIG_LOCK; // Push zeroes onto the stacks of the auto variables. - for (; i < f->autos.len; ++i) { - + for (; i < f->autos.len; ++i) + { // Get the auto and its stack. a = bc_vec_item(&f->autos, i); v = bc_program_vec(p, a->idx, a->type); // If a variable, just push a 0; otherwise, push an array. - if (a->type == BC_TYPE_VAR) { - BcNum *n = bc_vec_pushEmpty(v); + if (a->type == BC_TYPE_VAR) + { + BcNum* n = bc_vec_pushEmpty(v); bc_num_init(n, BC_NUM_DEF_SIZE); } - else { - - BcVec *v2; + else + { + BcVec* v2; assert(a->type == BC_TYPE_ARRAY); @@ -1713,11 +1847,12 @@ static void bc_program_call(BcProgram *p, const char *restrict code, * @param inst The return instruction. bc can return void, and we need to know * if it is. */ -static void bc_program_return(BcProgram *p, uchar inst) { - - BcResult *res; - BcFunc *f; - BcInstPtr *ip; +static void +bc_program_return(BcProgram* p, uchar inst) +{ + BcResult* res; + BcFunc* f; + BcInstPtr* ip; size_t i, nresults; // Get the instruction pointer. @@ -1740,25 +1875,26 @@ static void bc_program_return(BcProgram *p, uchar inst) { res = bc_program_prepResult(p); // If we are returning normally... - if (inst == BC_INST_RET) { - - BcNum *num; - BcResult *operand; + if (inst == BC_INST_RET) + { + BcNum* num; + BcResult* operand; // Prepare and copy the return value. bc_program_operand(p, &operand, &num, 1); - if (BC_PROG_STR(num)) { - + if (BC_PROG_STR(num)) + { // We need to set this because otherwise, it will be a // BC_RESULT_TEMP, and BC_RESULT_TEMP needs an actual number to make // it easier to do type checking. res->t = BC_RESULT_STR; + // NOLINTNEXTLINE memcpy(&res->d.n, num, sizeof(BcNum)); } - else { - + else + { BC_SIG_LOCK; bc_num_createCopy(&res->d.n, num); @@ -1766,8 +1902,8 @@ static void bc_program_return(BcProgram *p, uchar inst) { } // Void is easy; set the result. else if (inst == BC_INST_RET_VOID) res->t = BC_RESULT_VOID; - else { - + else + { BC_SIG_LOCK; // If we get here, the instruction is for returning a zero, so do that. @@ -1777,10 +1913,10 @@ static void bc_program_return(BcProgram *p, uchar inst) { BC_SIG_MAYUNLOCK; // We need to pop items off of the stacks of arguments and autos as well. - for (i = 0; i < f->autos.len; ++i) { - - BcAuto *a = bc_vec_item(&f->autos, i); - BcVec *v = bc_program_vec(p, a->idx, a->type); + for (i = 0; i < f->autos.len; ++i) + { + BcAuto* a = bc_vec_item(&f->autos, i); + BcVec* v = bc_program_vec(p, a->idx, a->type); bc_vec_pop(v); } @@ -1805,10 +1941,12 @@ static void bc_program_return(BcProgram *p, uchar inst) { * @param p The program. * @param inst The builtin to execute. */ -static void bc_program_builtin(BcProgram *p, uchar inst) { - - BcResult *opd, *res; - BcNum *num; +static void +bc_program_builtin(BcProgram* p, uchar inst) +{ + BcResult* opd; + BcResult* res; + BcNum* num; bool len = (inst == BC_INST_LENGTH); // Ensure we have a valid builtin. @@ -1821,7 +1959,9 @@ static void bc_program_builtin(BcProgram *p, uchar inst) { #ifndef BC_PROG_NO_STACK_CHECK // Check stack for dc. if (BC_IS_DC && BC_ERR(!BC_PROG_STACK(&p->results, 1))) + { bc_err(BC_ERR_EXEC_STACK); + } #endif // BC_PROG_NO_STACK_CHECK assert(BC_PROG_STACK(&p->results, 1)); @@ -1835,14 +1975,16 @@ static void bc_program_builtin(BcProgram *p, uchar inst) { // We need to ensure that strings and arrays aren't passed to most builtins. // The scale function can take strings in dc. if (!len && (inst != BC_INST_SCALE_FUNC || BC_IS_BC)) + { bc_program_type_num(opd, num); + } // Square root is easy. if (inst == BC_INST_SQRT) bc_num_sqrt(num, &res->d.n, BC_PROG_SCALE(p)); // Absolute value is easy. - else if (inst == BC_INST_ABS) { - + else if (inst == BC_INST_ABS) + { BC_SIG_LOCK; bc_num_createCopy(&res->d.n, num); @@ -1853,8 +1995,8 @@ static void bc_program_builtin(BcProgram *p, uchar inst) { } #if BC_ENABLE_EXTRA_MATH // irand() is easy. - else if (inst == BC_INST_IRAND) { - + else if (inst == BC_INST_IRAND) + { BC_SIG_LOCK; bc_num_init(&res->d.n, num->len - BC_NUM_RDX_VAL(num)); @@ -1866,36 +2008,38 @@ static void bc_program_builtin(BcProgram *p, uchar inst) { #endif // BC_ENABLE_EXTRA_MATH // Everything else is...not easy. - else { - + else + { BcBigDig val = 0; // Well, scale() is easy, but length() is not. - if (len) { - + if (len) + { // If we are bc and we have an array... - if (opd->t == BC_RESULT_ARRAY) { - + if (opd->t == BC_RESULT_ARRAY) + { // Yes, this is one place where we need to cast the number from // bc_program_num() to a vector. - BcVec *v = (BcVec*) num; + BcVec* v = (BcVec*) num; #if BC_ENABLED // Dereference the array, if necessary. if (BC_IS_BC && v->size == sizeof(uchar)) + { v = bc_program_dereference(p, v); + } #endif // BC_ENABLED assert(v->size == sizeof(BcNum)); val = (BcBigDig) v->len; } - else { - + else + { // If the item is a string... - if (!BC_PROG_NUM(opd, num)) { - - char *str; + if (!BC_PROG_NUM(opd, num)) + { + char* str; // Get the string, then get the length. str = bc_program_string(p, num); @@ -1911,7 +2055,9 @@ static void bc_program_builtin(BcProgram *p, uchar inst) { // Like I said; scale() is actually easy. It just also needs the integer // conversion that length() does. else if (BC_IS_BC || BC_PROG_NUM(opd, num)) + { val = (BcBigDig) bc_num_scale(num); + } BC_SIG_LOCK; @@ -1928,10 +2074,15 @@ static void bc_program_builtin(BcProgram *p, uchar inst) { * Executes a divmod. * @param p The program. */ -static void bc_program_divmod(BcProgram *p) { - - BcResult *opd1, *opd2, *res, *res2; - BcNum *n1, *n2; +static void +bc_program_divmod(BcProgram* p) +{ + BcResult* opd1; + BcResult* opd2; + BcResult* res; + BcResult* res2; + BcNum* n1; + BcNum* n2; size_t req; // We grow first to avoid pointer invalidation. @@ -1965,16 +2116,24 @@ static void bc_program_divmod(BcProgram *p) { * Executes modular exponentiation. * @param p The program. */ -static void bc_program_modexp(BcProgram *p) { - - BcResult *r1, *r2, *r3, *res; - BcNum *n1, *n2, *n3; +static void +bc_program_modexp(BcProgram* p) +{ + BcResult* r1; + BcResult* r2; + BcResult* r3; + BcResult* res; + BcNum* n1; + BcNum* n2; + BcNum* n3; #if DC_ENABLED // Check the stack. if (BC_IS_DC && BC_ERR(!BC_PROG_STACK(&p->results, 3))) + { bc_err(BC_ERR_EXEC_STACK); + } #endif // DC_ENABLED @@ -1992,7 +2151,9 @@ static void bc_program_modexp(BcProgram *p) { // Make sure that the values have their pointers updated, if necessary. // Only array elements are possible because this is dc. if (r1->t == BC_RESULT_ARRAY_ELEM && (r1->t == r2->t || r1->t == r3->t)) + { n1 = bc_program_num(p, r1); + } BC_SIG_LOCK; @@ -2010,8 +2171,9 @@ static void bc_program_modexp(BcProgram *p) { * @param p The program. * @param n The number to asciify. */ -static uchar bc_program_asciifyNum(BcProgram *p, BcNum *n) { - +static uchar +bc_program_asciifyNum(BcProgram* p, BcNum* n) +{ BcNum num; BcBigDig val; @@ -2055,11 +2217,13 @@ num_err: * @param p The program. * @param fidx The index of the current function. */ -static void bc_program_asciify(BcProgram *p, size_t fidx) { - +static void +bc_program_asciify(BcProgram* p, size_t fidx) +{ BcResult *r, res; - BcNum *n; - char str[2], *str2; + BcNum* n; + char str[2]; + char* str2; uchar c; size_t idx; @@ -2075,8 +2239,8 @@ static void bc_program_asciify(BcProgram *p, size_t fidx) { // Asciify. if (BC_PROG_NUM(r, n)) c = bc_program_asciifyNum(p, n); - else { - + else + { // Get the string itself, then the first character. str2 = bc_program_string(p, n); c = (uchar) str2[0]; @@ -2106,10 +2270,11 @@ static void bc_program_asciify(BcProgram *p, size_t fidx) { * Streams a number or a string to stdout. * @param p The program. */ -static void bc_program_printStream(BcProgram *p) { - - BcResult *r; - BcNum *n; +static void +bc_program_printStream(BcProgram* p) +{ + BcResult* r; + BcNum* n; // Check the stack. if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_err(BC_ERR_EXEC_STACK); @@ -2138,11 +2303,12 @@ static void bc_program_printStream(BcProgram *p) { * @param bgn An in/out parameter; the start of the index in the bytecode * vector, and will be updated to point after the index on return. */ -static void bc_program_regStackLen(BcProgram *p, const char *restrict code, - size_t *restrict bgn) +static void +bc_program_regStackLen(BcProgram* p, const char* restrict code, + size_t* restrict bgn) { size_t idx = bc_program_index(code, bgn); - BcVec *v = bc_program_vec(p, idx, BC_TYPE_VAR); + BcVec* v = bc_program_vec(p, idx, BC_TYPE_VAR); bc_program_pushBigdig(p, (BcBigDig) v->len, BC_RESULT_TEMP); } @@ -2151,7 +2317,9 @@ static void bc_program_regStackLen(BcProgram *p, const char *restrict code, * Pushes the length of the results stack onto the results stack. * @param p The program. */ -static void bc_program_stackLen(BcProgram *p) { +static void +bc_program_stackLen(BcProgram* p) +{ bc_program_pushBigdig(p, (BcBigDig) p->results.len, BC_RESULT_TEMP); } @@ -2162,10 +2330,11 @@ static void bc_program_stackLen(BcProgram *p) { * 2, and one to pop the amount equal to the number at the top of * the results stack. */ -static void bc_program_nquit(BcProgram *p, uchar inst) { - - BcResult *opnd; - BcNum *num; +static void +bc_program_nquit(BcProgram* p, uchar inst) +{ + BcResult* opnd; + BcNum* num; BcBigDig val; size_t i; @@ -2174,8 +2343,8 @@ static void bc_program_nquit(BcProgram *p, uchar inst) { // Get the number of executions to pop. if (inst == BC_INST_QUIT) val = 2; - else { - + else + { bc_program_prep(p, &opnd, &num, 0); val = bc_num_bigdig(num); @@ -2183,8 +2352,8 @@ static void bc_program_nquit(BcProgram *p, uchar inst) { } // Loop over the tail call stack and adjust the quit value appropriately. - for (i = 0; val && i < p->tail_calls.len; ++i) { - + for (i = 0; val && i < p->tail_calls.len; ++i) + { // Get the number of tail calls for this one. size_t calls = *((size_t*) bc_vec_item_rev(&p->tail_calls, i)) + 1; @@ -2194,11 +2363,13 @@ static void bc_program_nquit(BcProgram *p, uchar inst) { } // If we don't have enough executions, just quit. - if (i == p->stack.len) { + if (i == p->stack.len) + { vm.status = BC_STATUS_QUIT; BC_JMP; } - else { + else + { // We can always pop the last item we reached on the tail call stack // because these are for tail calls. That means that any executions that // we would not have quit in that position on the stack would have quit @@ -2214,14 +2385,17 @@ static void bc_program_nquit(BcProgram *p, uchar inst) { * Pushes the depth of the execution stack onto the stack. * @param p The program. */ -static void bc_program_execStackLen(BcProgram *p) { - +static void +bc_program_execStackLen(BcProgram* p) +{ size_t i, amt, len = p->tail_calls.len; amt = len; for (i = 0; i < len; ++i) + { amt += *((size_t*) bc_vec_item(&p->tail_calls, i)); + } bc_program_pushBigdig(p, (BcBigDig) amt, BC_RESULT_TEMP); } @@ -2235,15 +2409,16 @@ static void bc_program_execStackLen(BcProgram *p) { * @param cond True if the execution is conditional, false otherwise. * @param len The number of bytes in the bytecode vector. */ -static void bc_program_execStr(BcProgram *p, const char *restrict code, - size_t *restrict bgn, bool cond, size_t len) +static void +bc_program_execStr(BcProgram* p, const char* restrict code, + size_t* restrict bgn, bool cond, size_t len) { - BcResult *r; - char *str; - BcFunc *f; + BcResult* r; + char* str; + BcFunc* f; BcInstPtr ip; size_t fidx; - BcNum *n; + BcNum* n; assert(p->stack.len == p->tail_calls.len); @@ -2256,8 +2431,8 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code, bc_program_operand(p, &r, &n, 0); // If execution is conditional... - if (cond) { - + if (cond) + { bool exec; size_t idx, then_idx, else_idx; @@ -2278,7 +2453,9 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code, // not exist, we don't execute. The goto skips all of the setup for the // execution. if (exec || (else_idx != SIZE_MAX)) + { n = bc_vec_top(bc_program_vec(p, idx, BC_TYPE_VAR)); + } else goto exit; if (BC_ERR(!BC_PROG_STR(n))) bc_err(BC_ERR_EXEC_TYPE); @@ -2286,8 +2463,8 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code, BC_UNSETJMP; BC_SIG_UNLOCK; } - else { - + else + { // In non-conditional situations, only the top of stack can be executed, // and in those cases, variables are not allowed to be "on the stack"; // they are only put on the stack to be assigned to. @@ -2308,12 +2485,12 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code, f = bc_vec_item(&p->fns, fidx); // If the function has not been parsed yet... - if (!f->code.len) { - + if (!f->code.len) + { BC_SIG_LOCK; - if (!BC_PARSE_IS_INITED(&vm.read_prs, p)) { - + if (!BC_PARSE_IS_INITED(&vm.read_prs, p)) + { bc_parse_init(&vm.read_prs, p, fidx); // Initialize this too because bc_vm_shutdown() expects them to be @@ -2358,9 +2535,9 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code, // Tail call processing. This condition means that there is more on the // execution stack, and we are at the end of the bytecode vector, and the // last instruction is just a BC_INST_POP_EXEC, which would return. - if (p->stack.len > 1 && *bgn == len - 1 && code[*bgn] == BC_INST_POP_EXEC) { - - size_t *call_ptr = bc_vec_top(&p->tail_calls); + if (p->stack.len > 1 && *bgn == len - 1 && code[*bgn] == BC_INST_POP_EXEC) + { + size_t* call_ptr = bc_vec_top(&p->tail_calls); // Add one to the tail call. *call_ptr += 1; @@ -2396,12 +2573,15 @@ exit: * Prints every item on the results stack, one per line. * @param p The program. */ -static void bc_program_printStack(BcProgram *p) { - +static void +bc_program_printStack(BcProgram* p) +{ size_t idx; for (idx = 0; idx < p->results.len; ++idx) + { bc_program_print(p, BC_INST_PRINT, idx); + } } #endif // DC_ENABLED @@ -2410,8 +2590,9 @@ static void bc_program_printStack(BcProgram *p) { * @param p The program. * @param inst Which global to push, as an instruction. */ -static void bc_program_pushGlobal(BcProgram *p, uchar inst) { - +static void +bc_program_pushGlobal(BcProgram* p, uchar inst) +{ BcResultType t; // Make sure the instruction is valid. @@ -2427,8 +2608,9 @@ static void bc_program_pushGlobal(BcProgram *p, uchar inst) { * @param p The program. * @param inst Which global setting to push, as an instruction. */ -static void bc_program_globalSetting(BcProgram *p, uchar inst) { - +static void +bc_program_globalSetting(BcProgram* p, uchar inst) +{ BcBigDig val; // Make sure the instruction is valid. @@ -2450,9 +2632,10 @@ static void bc_program_globalSetting(BcProgram *p, uchar inst) { * Pushes the value of seed on the stack. * @param p The program. */ -static void bc_program_pushSeed(BcProgram *p) { - - BcResult *res; +static void +bc_program_pushSeed(BcProgram* p) +{ + BcResult* res; res = bc_program_prepResult(p); res->t = BC_RESULT_SEED; @@ -2475,10 +2658,11 @@ static void bc_program_pushSeed(BcProgram *p) { * @param p The program. * @param id_ptr The ID of the function as inserted into the map. */ -static void bc_program_addFunc(BcProgram *p, BcId *id_ptr) { - - BcInstPtr *ip; - BcFunc *f; +static void +bc_program_addFunc(BcProgram* p, BcId* id_ptr) +{ + BcInstPtr* ip; + BcFunc* f; BC_SIG_ASSERT_LOCKED; @@ -2487,15 +2671,17 @@ static void bc_program_addFunc(BcProgram *p, BcId *id_ptr) { bc_func_init(f, id_ptr->name); // This is to make sure pointers are updated if the array was moved. - if (p->stack.len) { + if (p->stack.len) + { ip = bc_vec_top(&p->stack); bc_program_setVecs(p, (BcFunc*) bc_vec_item(&p->fns, ip->func)); } } -size_t bc_program_insertFunc(BcProgram *p, const char *name) { - - BcId *id_ptr; +size_t +bc_program_insertFunc(BcProgram* p, const char* name) +{ + BcId* id_ptr; bool new; size_t idx; @@ -2509,15 +2695,16 @@ size_t bc_program_insertFunc(BcProgram *p, const char *name) { idx = id_ptr->idx; // If the function is new... - if (new) { - + if (new) + { // Add the function to the fns array. bc_program_addFunc(p, id_ptr); } #if BC_ENABLED // bc has to reset the function because it's about to be redefined. - else if (BC_IS_BC) { - BcFunc *func = bc_vec_item(&p->fns, idx); + else if (BC_IS_BC) + { + BcFunc* func = bc_vec_item(&p->fns, idx); bc_func_reset(func); } #endif // BC_ENABLED @@ -2526,8 +2713,9 @@ size_t bc_program_insertFunc(BcProgram *p, const char *name) { } #ifndef NDEBUG -void bc_program_free(BcProgram *p) { - +void +bc_program_free(BcProgram* p) +{ size_t i; BC_SIG_ASSERT_LOCKED; @@ -2535,7 +2723,10 @@ void bc_program_free(BcProgram *p) { assert(p != NULL); // Free the globals stacks. - for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) bc_vec_free(p->globals_v + i); + for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) + { + bc_vec_free(p->globals_v + i); + } bc_vec_free(&p->fns); bc_vec_free(&p->fn_map); @@ -2560,8 +2751,9 @@ void bc_program_free(BcProgram *p) { } #endif // NDEBUG -void bc_program_init(BcProgram *p) { - +void +bc_program_init(BcProgram* p) +{ BcInstPtr ip; size_t i; @@ -2570,11 +2762,12 @@ void bc_program_init(BcProgram *p) { assert(p != NULL); // We want this clear. + // NOLINTNEXTLINE memset(&ip, 0, sizeof(BcInstPtr)); // Setup the globals stacks and the current values. - for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) { - + for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) + { BcBigDig val = i == BC_PROG_GLOBALS_SCALE ? 0 : BC_BASE; bc_vec_init(p->globals_v + i, sizeof(BcBigDig), BC_DTOR_NONE); @@ -2585,8 +2778,8 @@ void bc_program_init(BcProgram *p) { #if DC_ENABLED // dc-only setup. - if (BC_IS_DC) { - + if (BC_IS_DC) + { bc_vec_init(&p->tail_calls, sizeof(size_t), BC_DTOR_NONE); // We want an item for the main function on the tail call stack. @@ -2636,10 +2829,11 @@ void bc_program_init(BcProgram *p) { assert(p->consts != NULL && p->strs != NULL); } -void bc_program_reset(BcProgram *p) { - - BcFunc *f; - BcInstPtr *ip; +void +bc_program_reset(BcProgram* p) +{ + BcFunc* f; + BcInstPtr* ip; BC_SIG_ASSERT_LOCKED; @@ -2659,28 +2853,31 @@ void bc_program_reset(BcProgram *p) { // Reset the instruction pointer. ip = bc_vec_top(&p->stack); bc_program_setVecs(p, f); + // NOLINTNEXTLINE memset(ip, 0, sizeof(BcInstPtr)); // Write the ready message for a signal, and clear the signal. - if (vm.sig) { - bc_file_write(&vm.fout, bc_flush_none, bc_program_ready_msg, - bc_program_ready_msg_len); + if (vm.sig) + { + bc_file_printf(&vm.fout, "%s", bc_program_ready_msg); bc_file_flush(&vm.fout, bc_flush_err); vm.sig = 0; } } -void bc_program_exec(BcProgram *p) { - +void +bc_program_exec(BcProgram* p) +{ size_t idx; - BcResult r, *ptr; - BcInstPtr *ip; - BcFunc *func; - char *code; + BcResult r; + BcResult* ptr; + BcInstPtr* ip; + BcFunc* func; + char* code; bool cond = false; uchar inst; #if BC_ENABLED - BcNum *num; + BcNum* num; #endif // BC_ENABLED #if !BC_HAS_COMPUTED_GOTO #ifndef NDEBUG @@ -2740,11 +2937,12 @@ void bc_program_exec(BcProgram *p) { switch (inst) #endif // !BC_HAS_COMPUTED_GOTO { - #if BC_ENABLED // This just sets up the condition for the unconditional jump below, // which checks the condition, if necessary. + // clang-format off BC_PROG_LBL(BC_INST_JUMP_ZERO): + // clang-format on { bc_program_prep(p, &ptr, &num, 0); @@ -2756,15 +2954,17 @@ void bc_program_exec(BcProgram *p) { // Fallthrough. BC_PROG_FALLTHROUGH + // clang-format off BC_PROG_LBL(BC_INST_JUMP): + // clang-format on { idx = bc_program_index(code, &ip->idx); // If a jump is required... - if (inst == BC_INST_JUMP || cond) { - + if (inst == BC_INST_JUMP || cond) + { // Get the address to jump to. - size_t *addr = bc_vec_item(&func->labels, idx); + size_t* addr = bc_vec_item(&func->labels, idx); // If this fails, then the parser failed to set up the // labels correctly. @@ -2777,7 +2977,9 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_CALL): + // clang-format on { assert(BC_IS_BC); @@ -2795,14 +2997,18 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_INC): BC_PROG_LBL(BC_INST_DEC): + // clang-format on { bc_program_incdec(p, inst); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_HALT): + // clang-format on { vm.status = BC_STATUS_QUIT; @@ -2812,9 +3018,11 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_RET): BC_PROG_LBL(BC_INST_RET0): BC_PROG_LBL(BC_INST_RET_VOID): + // clang-format on { bc_program_return(p, inst); @@ -2831,6 +3039,7 @@ void bc_program_exec(BcProgram *p) { } #endif // BC_ENABLED + // clang-format off BC_PROG_LBL(BC_INST_BOOL_OR): BC_PROG_LBL(BC_INST_BOOL_AND): BC_PROG_LBL(BC_INST_REL_EQ): @@ -2839,12 +3048,15 @@ void bc_program_exec(BcProgram *p) { BC_PROG_LBL(BC_INST_REL_NE): BC_PROG_LBL(BC_INST_REL_LT): BC_PROG_LBL(BC_INST_REL_GT): + // clang-format on { bc_program_logical(p, inst); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_READ): + // clang-format on { // We want to flush output before // this in case there is a prompt. @@ -2865,64 +3077,79 @@ void bc_program_exec(BcProgram *p) { } #if BC_ENABLE_EXTRA_MATH + // clang-format off BC_PROG_LBL(BC_INST_RAND): + // clang-format on { bc_program_rand(p); BC_PROG_JUMP(inst, code, ip); } #endif // BC_ENABLE_EXTRA_MATH + // clang-format off BC_PROG_LBL(BC_INST_MAXIBASE): BC_PROG_LBL(BC_INST_MAXOBASE): BC_PROG_LBL(BC_INST_MAXSCALE): #if BC_ENABLE_EXTRA_MATH BC_PROG_LBL(BC_INST_MAXRAND): #endif // BC_ENABLE_EXTRA_MATH + // clang-format on { BcBigDig dig = vm.maxes[inst - BC_INST_MAXIBASE]; bc_program_pushBigdig(p, dig, BC_RESULT_TEMP); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_LINE_LENGTH): #if BC_ENABLED BC_PROG_LBL(BC_INST_GLOBAL_STACKS): #endif // BC_ENABLED BC_PROG_LBL(BC_INST_LEADING_ZERO): + // clang-format on { bc_program_globalSetting(p, inst); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_VAR): + // clang-format on { bc_program_pushVar(p, code, &ip->idx, false, false); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_ARRAY_ELEM): BC_PROG_LBL(BC_INST_ARRAY): + // clang-format on { bc_program_pushArray(p, code, &ip->idx, inst); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_IBASE): BC_PROG_LBL(BC_INST_SCALE): BC_PROG_LBL(BC_INST_OBASE): + // clang-format on { bc_program_pushGlobal(p, inst); BC_PROG_JUMP(inst, code, ip); } #if BC_ENABLE_EXTRA_MATH + // clang-format off BC_PROG_LBL(BC_INST_SEED): + // clang-format on { bc_program_pushSeed(p); BC_PROG_JUMP(inst, code, ip); } #endif // BC_ENABLE_EXTRA_MATH + // clang-format off BC_PROG_LBL(BC_INST_LENGTH): BC_PROG_LBL(BC_INST_SCALE_FUNC): BC_PROG_LBL(BC_INST_SQRT): @@ -2930,12 +3157,15 @@ void bc_program_exec(BcProgram *p) { #if BC_ENABLE_EXTRA_MATH BC_PROG_LBL(BC_INST_IRAND): #endif // BC_ENABLE_EXTRA_MATH + // clang-format on { bc_program_builtin(p, inst); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_ASCIIFY): + // clang-format on { bc_program_asciify(p, ip->func); @@ -2951,28 +3181,34 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_NUM): + // clang-format on { bc_program_const(p, code, &ip->idx); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_ZERO): BC_PROG_LBL(BC_INST_ONE): #if BC_ENABLED BC_PROG_LBL(BC_INST_LAST): #endif // BC_ENABLED + // clang-format on { r.t = BC_RESULT_ZERO + (inst - BC_INST_ZERO); bc_vec_push(&p->results, &r); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_PRINT): BC_PROG_LBL(BC_INST_PRINT_POP): #if BC_ENABLED BC_PROG_LBL(BC_INST_PRINT_STR): #endif // BC_ENABLED + // clang-format on { bc_program_print(p, inst, 0); @@ -2983,7 +3219,9 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_STR): + // clang-format on { // Set up the result and push. r.t = BC_RESULT_STR; @@ -2994,6 +3232,7 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_POWER): BC_PROG_LBL(BC_INST_MULTIPLY): BC_PROG_LBL(BC_INST_DIVIDE): @@ -3005,21 +3244,25 @@ void bc_program_exec(BcProgram *p) { BC_PROG_LBL(BC_INST_LSHIFT): BC_PROG_LBL(BC_INST_RSHIFT): #endif // BC_ENABLE_EXTRA_MATH + // clang-format on { bc_program_op(p, inst); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_NEG): BC_PROG_LBL(BC_INST_BOOL_NOT): #if BC_ENABLE_EXTRA_MATH BC_PROG_LBL(BC_INST_TRUNC): #endif // BC_ENABLE_EXTRA_MATH + // clang-format on { bc_program_unary(p, inst); BC_PROG_JUMP(inst, code, ip); } + // clang-format off #if BC_ENABLED BC_PROG_LBL(BC_INST_ASSIGN_POWER): BC_PROG_LBL(BC_INST_ASSIGN_MULTIPLY): @@ -3046,18 +3289,24 @@ void bc_program_exec(BcProgram *p) { #endif // BC_ENABLE_EXTRA_MATH #endif // BC_ENABLED BC_PROG_LBL(BC_INST_ASSIGN_NO_VAL): + // clang-format on { bc_program_assign(p, inst); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_POP): + // clang-format on { #ifndef BC_PROG_NO_STACK_CHECK // dc must do a stack check, but bc does not. - if (BC_IS_DC) { + if (BC_IS_DC) + { if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) + { bc_err(BC_ERR_EXEC_STACK); + } } #endif // BC_PROG_NO_STACK_CHECK @@ -3068,13 +3317,17 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_SWAP): + // clang-format on { - BcResult *ptr2; + BcResult* ptr2; // Check the stack. if (BC_ERR(!BC_PROG_STACK(&p->results, 2))) + { bc_err(BC_ERR_EXEC_STACK); + } assert(BC_PROG_STACK(&p->results, 2)); @@ -3083,33 +3336,44 @@ void bc_program_exec(BcProgram *p) { ptr2 = bc_vec_item_rev(&p->results, 1); // Swap. It's just easiest to do it this way. + // NOLINTNEXTLINE memcpy(&r, ptr, sizeof(BcResult)); + // NOLINTNEXTLINE memcpy(ptr, ptr2, sizeof(BcResult)); + // NOLINTNEXTLINE memcpy(ptr2, &r, sizeof(BcResult)); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_MODEXP): + // clang-format on { bc_program_modexp(p); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_DIVMOD): + // clang-format on { bc_program_divmod(p); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_PRINT_STREAM): + // clang-format on { bc_program_printStream(p); BC_PROG_JUMP(inst, code, ip); } #if DC_ENABLED + // clang-format off BC_PROG_LBL(BC_INST_POP_EXEC): + // clang-format on { // If this fails, the dc parser got something wrong. assert(BC_PROG_STACK(&p->stack, 2)); @@ -3130,8 +3394,10 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_EXECUTE): BC_PROG_LBL(BC_INST_EXEC_COND): + // clang-format on { cond = (inst == BC_INST_EXEC_COND); @@ -3149,35 +3415,47 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_PRINT_STACK): + // clang-format on { bc_program_printStack(p); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_CLEAR_STACK): + // clang-format on { bc_vec_popAll(&p->results); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_REG_STACK_LEN): + // clang-format on { bc_program_regStackLen(p, code, &ip->idx); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_STACK_LEN): + // clang-format on { bc_program_stackLen(p); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_DUPLICATE): + // clang-format on { // Check the stack. if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) + { bc_err(BC_ERR_EXEC_STACK); + } assert(BC_PROG_STACK(&p->results, 1)); @@ -3195,23 +3473,29 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_LOAD): BC_PROG_LBL(BC_INST_PUSH_VAR): + // clang-format on { bool copy = (inst == BC_INST_LOAD); bc_program_pushVar(p, code, &ip->idx, true, copy); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_PUSH_TO_VAR): + // clang-format on { idx = bc_program_index(code, &ip->idx); bc_program_copyToVar(p, idx, BC_TYPE_VAR, true); BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_QUIT): BC_PROG_LBL(BC_INST_NQUIT): + // clang-format on { bc_program_nquit(p, inst); @@ -3227,7 +3511,9 @@ void bc_program_exec(BcProgram *p) { BC_PROG_JUMP(inst, code, ip); } + // clang-format off BC_PROG_LBL(BC_INST_EXEC_STACK_LEN): + // clang-format on { bc_program_execStackLen(p); BC_PROG_JUMP(inst, code, ip); @@ -3235,7 +3521,9 @@ void bc_program_exec(BcProgram *p) { #endif // DC_ENABLED #if BC_HAS_COMPUTED_GOTO + // clang-format off BC_PROG_LBL(BC_INST_INVALID): + // clang-format on { return; } @@ -3263,19 +3551,22 @@ void bc_program_exec(BcProgram *p) { #if BC_DEBUG_CODE #if BC_ENABLED && DC_ENABLED -void bc_program_printStackDebug(BcProgram *p) { +void +bc_program_printStackDebug(BcProgram* p) +{ bc_file_puts(&vm.fout, bc_flush_err, "-------------- Stack ----------\n"); bc_program_printStack(p); bc_file_puts(&vm.fout, bc_flush_err, "-------------- Stack End ------\n"); } -static void bc_program_printIndex(const char *restrict code, - size_t *restrict bgn) +static void +bc_program_printIndex(const char* restrict code, size_t* restrict bgn) { uchar byte, i, bytes = (uchar) code[(*bgn)++]; ulong val = 0; - for (byte = 1, i = 0; byte && i < bytes; ++i) { + for (byte = 1, i = 0; byte && i < bytes; ++i) + { byte = (uchar) code[(*bgn)++]; if (byte) val |= ((ulong) byte) << (CHAR_BIT * i); } @@ -3283,24 +3574,26 @@ static void bc_program_printIndex(const char *restrict code, bc_vm_printf(" (%lu) ", val); } -static void bc_program_printStr(const BcProgram *p, const char *restrict code, - size_t *restrict bgn) +static void +bc_program_printStr(const BcProgram* p, const char* restrict code, + size_t* restrict bgn) { size_t idx = bc_program_index(code, bgn); - char *s; + char* s; s = *((char**) bc_vec_item(p->strs, idx)); bc_vm_printf(" (\"%s\") ", s); } -void bc_program_printInst(const BcProgram *p, const char *restrict code, - size_t *restrict bgn) +void +bc_program_printInst(const BcProgram* p, const char* restrict code, + size_t* restrict bgn) { uchar inst = (uchar) code[(*bgn)++]; - bc_vm_printf("Inst[%zu]: %s [%lu]; ", *bgn - 1, - bc_inst_names[inst], (unsigned long) inst); + bc_vm_printf("Inst[%zu]: %s [%lu]; ", *bgn - 1, bc_inst_names[inst], + (unsigned long) inst); if (inst == BC_INST_VAR || inst == BC_INST_ARRAY_ELEM || inst == BC_INST_ARRAY) @@ -3308,9 +3601,10 @@ void bc_program_printInst(const BcProgram *p, const char *restrict code, bc_program_printIndex(code, bgn); } else if (inst == BC_INST_STR) bc_program_printStr(p, code, bgn); - else if (inst == BC_INST_NUM) { + else if (inst == BC_INST_NUM) + { size_t idx = bc_program_index(code, bgn); - BcConst *c = bc_vec_item(p->consts, idx); + BcConst* c = bc_vec_item(p->consts, idx); bc_vm_printf("(%s)", c->val); } else if (inst == BC_INST_CALL || @@ -3323,15 +3617,16 @@ void bc_program_printInst(const BcProgram *p, const char *restrict code, bc_vm_putchar('\n', bc_flush_err); } -void bc_program_code(const BcProgram* p) { - - BcFunc *f; - char *code; +void +bc_program_code(const BcProgram* p) +{ + BcFunc* f; + char* code; BcInstPtr ip; size_t i; - for (i = 0; i < p->fns.len; ++i) { - + for (i = 0; i < p->fns.len; ++i) + { ip.idx = ip.len = 0; ip.func = i; @@ -3339,7 +3634,10 @@ void bc_program_code(const BcProgram* p) { code = f->code.v; bc_vm_printf("func[%zu]:\n", ip.func); - while (ip.idx < f->code.len) bc_program_printInst(p, code, &ip.idx); + while (ip.idx < f->code.len) + { + bc_program_printInst(p, code, &ip.idx); + } bc_file_puts(&vm.fout, bc_flush_err, "\n\n"); } } |