diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/args.c | 8 | ||||
-rw-r--r-- | src/bc/bc.c | 4 | ||||
-rw-r--r-- | src/bc/lex.c | 4 | ||||
-rw-r--r-- | src/bc/parse.c | 56 | ||||
-rw-r--r-- | src/data.c | 81 | ||||
-rw-r--r-- | src/dc/dc.c | 4 | ||||
-rw-r--r-- | src/dc/lex.c | 4 | ||||
-rw-r--r-- | src/dc/parse.c | 6 | ||||
-rw-r--r-- | src/file.c | 4 | ||||
-rw-r--r-- | src/history/history.c | 12 | ||||
-rw-r--r-- | src/lang.c | 41 | ||||
-rw-r--r-- | src/lex.c | 4 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/num.c | 9 | ||||
-rw-r--r-- | src/opt.c | 8 | ||||
-rw-r--r-- | src/parse.c | 25 | ||||
-rw-r--r-- | src/program.c | 218 | ||||
-rw-r--r-- | src/rand/rand.c | 10 | ||||
-rw-r--r-- | src/read.c | 29 | ||||
-rw-r--r-- | src/vector.c | 74 | ||||
-rw-r--r-- | src/vm.c | 123 |
21 files changed, 424 insertions, 304 deletions
diff --git a/src/args.c b/src/args.c index d3735178fc48c..1626ad4944e4e 100644 --- a/src/args.c +++ b/src/args.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -184,7 +184,7 @@ void bc_args(int argc, char *argv[]) { #if DC_ENABLED case 'x': { - assert(!BC_IS_BC); + assert(BC_IS_DC); vm.flags |= DC_FLAG_X; break; } @@ -205,7 +205,7 @@ void bc_args(int argc, char *argv[]) { if (version) bc_vm_info(NULL); if (do_exit) exit((int) vm.status); - if (vm.exprs.len > 1 || !BC_IS_BC) vm.flags |= BC_FLAG_Q; + if (vm.exprs.len > 1 || BC_IS_DC) vm.flags |= BC_FLAG_Q; if (opts.optind < (size_t) argc) bc_vec_init(&vm.files, sizeof(char*), NULL); diff --git a/src/bc/bc.c b/src/bc/bc.c index 86d8f81dd4011..ef0fc3d6865dc 100644 --- a/src/bc/bc.c +++ b/src/bc/bc.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/bc/lex.c b/src/bc/lex.c index d4c6bd4c192e8..cc780e0d6278b 100644 --- a/src/bc/lex.c +++ b/src/bc/lex.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/bc/parse.c b/src/bc/parse.c index fb00447ee6bca..2aa9d97468ffb 100644 --- a/src/bc/parse.c +++ b/src/bc/parse.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -399,8 +399,10 @@ static void bc_parse_incdec(BcParse *p, BcInst *prev, bool *can_assign, // right here, we need to increment this. *nexs = *nexs + 1; - if (type == BC_LEX_NAME) - bc_parse_name(p, prev, can_assign, flags | BC_PARSE_NOCALL); + if (type == BC_LEX_NAME) { + uint8_t flags2 = flags & ~BC_PARSE_ARRAY; + bc_parse_name(p, prev, can_assign, flags2 | BC_PARSE_NOCALL); + } else if (type >= BC_LEX_KW_LAST && type <= BC_LEX_KW_OBASE) { bc_parse_push(p, type - BC_LEX_KW_LAST + BC_INST_LAST); bc_lex_next(&p->l); @@ -1006,24 +1008,24 @@ static void bc_parse_stmt(BcParse *p) { case BC_LEX_KW_LENGTH: case BC_LEX_KW_OBASE: case BC_LEX_KW_SCALE: -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_SEED: -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_SQRT: case BC_LEX_KW_ABS: -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_IRAND: -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_READ: -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_RAND: -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_MAXIBASE: case BC_LEX_KW_MAXOBASE: case BC_LEX_KW_MAXSCALE: -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_MAXRAND: -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND { bc_parse_expr_status(p, BC_PARSE_PRINT, bc_parse_next_expr); break; @@ -1092,9 +1094,9 @@ static void bc_parse_stmt(BcParse *p) { bc_vm_printf("BC_STRING_MAX = %lu\n", BC_MAX_STRING); bc_vm_printf("BC_NAME_MAX = %lu\n", BC_MAX_NAME); bc_vm_printf("BC_NUM_MAX = %lu\n", BC_MAX_NUM); -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND bc_vm_printf("BC_RAND_MAX = %lu\n", BC_MAX_RAND); -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND bc_vm_printf("MAX Exponent = %lu\n", BC_MAX_EXP); bc_vm_printf("Number of vars = %lu\n", BC_MAX_VARS); @@ -1161,7 +1163,8 @@ void bc_parse_parse(BcParse *p) { exit: BC_SIG_MAYLOCK; - if (BC_ERR((vm.status && vm.status != BC_STATUS_QUIT))) bc_parse_reset(p); + if (BC_ERR(((vm.status && vm.status != BC_STATUS_QUIT) || vm.sig))) + bc_parse_reset(p); BC_LONGJMP_CONT; } @@ -1212,7 +1215,7 @@ static BcParseStatus bc_parse_expr_err(BcParse *p, uint8_t flags, // I can just add the instruction because // negative will already be taken care of. bc_parse_push(p, BC_INST_TRUNC); - rprn = can_assign = false; + rprn = can_assign = incdec = false; get_token = true; flags &= ~(BC_PARSE_ARRAY); break; @@ -1355,9 +1358,9 @@ static BcParseStatus bc_parse_expr_err(BcParse *p, uint8_t flags, case BC_LEX_KW_IBASE: case BC_LEX_KW_LAST: case BC_LEX_KW_OBASE: -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_SEED: -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND { if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn))) bc_parse_err(p, BC_ERROR_PARSE_EXPR); @@ -1376,9 +1379,9 @@ static BcParseStatus bc_parse_expr_err(BcParse *p, uint8_t flags, case BC_LEX_KW_LENGTH: case BC_LEX_KW_SQRT: case BC_LEX_KW_ABS: -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_IRAND: -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND { if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn))) bc_parse_err(p, BC_ERROR_PARSE_EXPR); @@ -1392,15 +1395,15 @@ static BcParseStatus bc_parse_expr_err(BcParse *p, uint8_t flags, } case BC_LEX_KW_READ: -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_RAND: -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_MAXIBASE: case BC_LEX_KW_MAXOBASE: case BC_LEX_KW_MAXSCALE: -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_LEX_KW_MAXRAND: -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND { if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn))) bc_parse_err(p, BC_ERROR_PARSE_EXPR); @@ -1455,6 +1458,8 @@ static BcParseStatus bc_parse_expr_err(BcParse *p, uint8_t flags, nexprs -= !BC_PARSE_OP_PREFIX(top); bc_vec_pop(&p->ops); + + incdec = false; } if (BC_ERR(nexprs != 1)) bc_parse_err(p, BC_ERROR_PARSE_EXPR); @@ -1482,7 +1487,8 @@ static BcParseStatus bc_parse_expr_err(BcParse *p, uint8_t flags, inst != BC_INST_ASSIGN_PLUS); } - if (inst >= BC_INST_ASSIGN_PLUS_NO_VAL && inst <= BC_INST_ASSIGN_NO_VAL) + if (inst >= BC_INST_ASSIGN_POWER_NO_VAL && + inst <= BC_INST_ASSIGN_NO_VAL) { bc_vec_pop(&p->func->code); if (incdec) bc_parse_push(p, BC_INST_ONE); diff --git a/src/data.c b/src/data.c index 3dae137634709..2556f795eed6d 100644 --- a/src/data.c +++ b/src/data.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -588,6 +588,7 @@ const char* bc_inst_names[] = { "BC_INST_ARRAY", #endif // BC_ENABLED + "BC_INST_ZERO", "BC_INST_ONE", #if BC_ENABLED @@ -663,11 +664,11 @@ const char* bc_inst_names[] = { }; #endif // BC_DEBUG_CODE -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND const BcRandState bc_rand_multiplier = BC_RAND_MULTIPLIER; -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND #if BC_ENABLED const BcLexKeyword bc_lex_kws[] = { @@ -685,27 +686,27 @@ const BcLexKeyword bc_lex_kws[] = { BC_LEX_KW_ENTRY("ibase", 5, true), BC_LEX_KW_ENTRY("obase", 5, true), BC_LEX_KW_ENTRY("scale", 5, true), -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_ENTRY("seed", 4, false), -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_ENTRY("length", 6, true), BC_LEX_KW_ENTRY("print", 5, false), BC_LEX_KW_ENTRY("sqrt", 4, true), BC_LEX_KW_ENTRY("abs", 3, false), -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_ENTRY("irand", 5, false), -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_ENTRY("quit", 4, true), BC_LEX_KW_ENTRY("read", 4, false), -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_ENTRY("rand", 4, false), -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_ENTRY("maxibase", 8, false), BC_LEX_KW_ENTRY("maxobase", 8, false), BC_LEX_KW_ENTRY("maxscale", 8, false), -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_ENTRY("maxrand", 7, false), -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_ENTRY("else", 4, false), }; @@ -719,7 +720,7 @@ const uint8_t bc_parse_exprs[] = { BC_PARSE_EXPR_ENTRY(false, false, true, true, true, true, true, true), BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true), BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true), -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true), BC_PARSE_EXPR_ENTRY(true, true, false, false, true, true, false, false), BC_PARSE_EXPR_ENTRY(false, false, false, false, false, true, true, false), @@ -727,7 +728,14 @@ const uint8_t bc_parse_exprs[] = { BC_PARSE_EXPR_ENTRY(false, true, true, true, true, true, true, false), BC_PARSE_EXPR_ENTRY(true, true, true, false, true, true, true, true), BC_PARSE_EXPR_ENTRY(true, true, false, 0, 0, 0, 0, 0) -#else // BC_ENABLE_EXTRA_MATH +#elif BC_ENABLE_EXTRA_MATH // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND + BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true), + BC_PARSE_EXPR_ENTRY(true, true, false, false, true, true, false, false), + BC_PARSE_EXPR_ENTRY(false, false, false, false, false, true, true, false), + BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, false, false), + BC_PARSE_EXPR_ENTRY(false, true, true, true, true, true, false, true), + BC_PARSE_EXPR_ENTRY(true, false, true, true, true, true, false, 0), +#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_PARSE_EXPR_ENTRY(true, true, true, false, false, true, true, false), BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, true, true), BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, false, false), @@ -786,11 +794,11 @@ const uint8_t dc_lex_regs[] = { const size_t dc_lex_regs_len = sizeof(dc_lex_regs) / sizeof(uint8_t); const uchar dc_lex_tokens[] = { -#if BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_IRAND, -#else // BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_INVALID, -#endif // BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_INVALID, #if BC_ENABLE_EXTRA_MATH BC_LEX_OP_TRUNC, @@ -798,11 +806,11 @@ const uchar dc_lex_tokens[] = { BC_LEX_INVALID, #endif // BC_ENABLE_EXTRA_MATH BC_LEX_OP_MODULUS, BC_LEX_INVALID, -#if BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_RAND, -#else // BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_INVALID, -#endif // BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_LPAREN, BC_LEX_RPAREN, BC_LEX_OP_MULTIPLY, BC_LEX_OP_PLUS, BC_LEX_INVALID, BC_LEX_OP_MINUS, BC_LEX_INVALID, BC_LEX_OP_DIVIDE, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, @@ -823,20 +831,20 @@ const uchar dc_lex_tokens[] = { BC_LEX_INVALID, #endif // BC_ENABLE_EXTRA_MATH BC_LEX_KW_IBASE, -#if BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_SEED, -#else // BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_INVALID, -#endif // BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_SCALE, BC_LEX_LOAD_POP, BC_LEX_OP_BOOL_AND, BC_LEX_OP_BOOL_NOT, BC_LEX_KW_OBASE, BC_LEX_PRINT_STREAM, BC_LEX_NQUIT, BC_LEX_POP, BC_LEX_STORE_PUSH, BC_LEX_KW_MAXIBASE, BC_LEX_KW_MAXOBASE, BC_LEX_KW_MAXSCALE, -#if BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_KW_MAXRAND, -#else // BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_INVALID, -#endif // BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_SCALE_FACTOR, BC_LEX_INVALID, BC_LEX_KW_LENGTH, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_OP_POWER, BC_LEX_NEG, BC_LEX_INVALID, @@ -848,11 +856,11 @@ const uchar dc_lex_tokens[] = { BC_LEX_INVALID, #endif // BC_ENABLE_EXTRA_MATH BC_LEX_STORE_IBASE, -#if BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_STORE_SEED, -#else // BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_INVALID, -#endif // BC_ENABLE_EXTRA_MATH && DC_ENABLE_RAND +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_LEX_STORE_SCALE, BC_LEX_LOAD, BC_LEX_OP_BOOL_OR, BC_LEX_PRINT_POP, BC_LEX_STORE_OBASE, BC_LEX_KW_PRINT, BC_LEX_KW_QUIT, BC_LEX_SWAP, BC_LEX_OP_ASSIGN, BC_LEX_INVALID, @@ -898,21 +906,21 @@ const uchar dc_parse_insts[] = { BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, #endif // BC_ENABLED BC_INST_IBASE, BC_INST_OBASE, BC_INST_SCALE, -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_INST_SEED, -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_INST_LENGTH, BC_INST_PRINT, BC_INST_SQRT, BC_INST_ABS, -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_INST_IRAND, -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_INST_QUIT, BC_INST_INVALID, -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_INST_RAND, -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_INST_MAXIBASE, BC_INST_MAXOBASE, BC_INST_MAXSCALE, -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_INST_MAXRAND, #endif // BC_ENABLE_EXTRA_MATH BC_INST_INVALID, @@ -945,6 +953,7 @@ const BcDig bc_num_bigdigMax[] = { const size_t bc_num_bigdigMax_size = sizeof(bc_num_bigdigMax) / sizeof(BcDig); +const char bc_parse_zero[] = "0"; const char bc_parse_one[] = "1"; const char bc_num_hex_digits[] = "0123456789ABCDEF"; diff --git a/src/dc/dc.c b/src/dc/dc.c index 0e0774b5322a1..21d7bfbd4385a 100644 --- a/src/dc/dc.c +++ b/src/dc/dc.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/dc/lex.c b/src/dc/lex.c index 663a828dfe7c3..b17f01bc990dd 100644 --- a/src/dc/lex.c +++ b/src/dc/lex.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/dc/parse.c b/src/dc/parse.c index 9ec746b96f7f4..86edc5f665059 100644 --- a/src/dc/parse.c +++ b/src/dc/parse.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -230,7 +230,7 @@ void dc_parse_parse(BcParse *p) { exit: BC_SIG_MAYLOCK; - if (BC_ERR(vm.status)) bc_parse_reset(p); + if (BC_ERR(vm.status || vm.sig)) bc_parse_reset(p); BC_LONGJMP_CONT; } #endif // DC_ENABLED diff --git a/src/file.c b/src/file.c index ce878a018ca56..01997399f4520 100644 --- a/src/file.c +++ b/src/file.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/history/history.c b/src/history/history.c index ad917e65ba08d..b94fbb7b3fdfc 100644 --- a/src/history/history.c +++ b/src/history/history.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -47,8 +47,6 @@ * Copyright (c) 2010-2016, Salvatore Sanfilippo <antirez at gmail dot com> * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com> * - * All rights reserved. - * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: @@ -482,15 +480,17 @@ static void bc_history_enableRaw(BcHistory *h) { static void bc_history_disableRaw(BcHistory *h) { + sig_atomic_t lock; + // Don't even check the return value as it's too late. if (!h->rawMode) return; - BC_SIG_LOCK; + BC_SIG_TRYLOCK(lock); if (BC_ERR(tcsetattr(STDIN_FILENO, TCSAFLUSH, &h->orig_termios) != -1)) h->rawMode = false; - BC_SIG_UNLOCK; + BC_SIG_TRYUNLOCK(lock); } /** diff --git a/src/lang.c b/src/lang.c index 6959af80fbfeb..bd287c75ee78f 100644 --- a/src/lang.c +++ b/src/lang.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -96,37 +96,41 @@ void bc_func_init(BcFunc *f, const char *name) { bc_vec_init(&f->code, sizeof(uchar), NULL); - // This is necessary for not allocating memory where it isn't used. - // dc does not use strings except in the main function. The else part - // is necessary to stop uninitiazed data errors in valgrind. - if (BC_IS_BC || !strcmp(name, bc_func_main)) - bc_vec_init(&f->strs, sizeof(char*), bc_string_free); -#if BC_ENABLE_FUNC_FREE - else bc_vec_clear(&f->strs); -#endif // BC_ENABLE_FUNC_FREE - bc_vec_init(&f->consts, sizeof(BcConst), bc_const_free); + #if BC_ENABLED if (BC_IS_BC) { + + bc_vec_init(&f->strs, sizeof(char*), bc_string_free); + bc_vec_init(&f->autos, sizeof(BcLoc), NULL); bc_vec_init(&f->labels, sizeof(size_t), NULL); + f->nparams = 0; f->voidfn = false; } #endif // BC_ENABLED + f->name = name; } void bc_func_reset(BcFunc *f) { + BC_SIG_ASSERT_LOCKED; assert(f != NULL); + bc_vec_npop(&f->code, f->code.len); - bc_vec_npop(&f->strs, f->strs.len); + bc_vec_npop(&f->consts, f->consts.len); + #if BC_ENABLED if (BC_IS_BC) { + + bc_vec_npop(&f->strs, f->strs.len); + bc_vec_npop(&f->autos, f->autos.len); bc_vec_npop(&f->labels, f->labels.len); + f->nparams = 0; f->voidfn = false; } @@ -134,17 +138,24 @@ void bc_func_reset(BcFunc *f) { } void bc_func_free(void *func) { + #if BC_ENABLE_FUNC_FREE BcFunc *f = (BcFunc*) func; + BC_SIG_ASSERT_LOCKED; assert(f != NULL); + bc_vec_free(&f->code); - bc_vec_free(&f->strs); + bc_vec_free(&f->consts); + #if BC_ENABLED #ifndef NDEBUG if (BC_IS_BC) { + + bc_vec_free(&f->strs); + bc_vec_free(&f->autos); bc_vec_free(&f->labels); } @@ -245,13 +256,13 @@ void bc_result_copy(BcResult *d, BcResult *src) { break; } - case BC_RESULT_CONSTANT: case BC_RESULT_STR: { memcpy(&d->d.n, &src->d.n, sizeof(BcNum)); break; } + case BC_RESULT_ZERO: case BC_RESULT_ONE: { // Do nothing. @@ -299,7 +310,7 @@ void bc_result_free(void *result) { #endif // BC_ENABLED case BC_RESULT_ARRAY_ELEM: case BC_RESULT_STR: - case BC_RESULT_CONSTANT: + case BC_RESULT_ZERO: case BC_RESULT_ONE: #if BC_ENABLED case BC_RESULT_VOID: diff --git a/src/lex.c b/src/lex.c index 8bbc694c161f3..2b705c8bc71b3 100644 --- a/src/lex.c +++ b/src/lex.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/main.c b/src/main.c index 68941c5e24a52..7e5e2905cf759 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/src/num.c b/src/num.c index ac255295e9709..05b4654f21f53 100644 --- a/src/num.c +++ b/src/num.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -2012,7 +2012,6 @@ void bc_num_init(BcNum *restrict n, size_t req) { if (req == BC_NUM_DEF_SIZE && vm.temps.len) { BcNum *nptr = bc_vec_top(&vm.temps); num = nptr->num; - req = nptr->cap; bc_vec_pop(&vm.temps); } else num = bc_vm_malloc(BC_NUM_SIZE(req)); @@ -2184,7 +2183,7 @@ void bc_num_bigdig2num(BcNum *restrict n, BcBigDig val) { n->len = i; } -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND void bc_num_rng(const BcNum *restrict n, BcRNG *rng) { BcNum pow, temp, temp2, intn, frac; @@ -2465,7 +2464,7 @@ err: bc_num_free(&cp); BC_LONGJMP_CONT; } -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND size_t bc_num_addReq(const BcNum *a, const BcNum *b, size_t scale) { diff --git a/src/opt.c b/src/opt.c index 730b1cd51f19d..3a01a2657f159 100644 --- a/src/opt.c +++ b/src/opt.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -102,7 +102,7 @@ static int bc_opt_parseShort(BcOpt *o, const BcOptLong *longopts) { case BC_OPT_BC_ONLY: case BC_OPT_DC_ONLY: { - if (type == -1 || (type == BC_OPT_BC_ONLY && !BC_IS_BC) || + if (type == -1 || (type == BC_OPT_BC_ONLY && BC_IS_DC) || (type == BC_OPT_DC_ONLY && BC_IS_BC)) { char str[2] = {0, 0}; @@ -212,7 +212,7 @@ int bc_opt_parse(BcOpt *o, const BcOptLong *longopts) { o->optopt = longopts[i].val; arg = bc_opt_longoptsArg(option); - if ((longopts[i].type == BC_OPT_BC_ONLY && !BC_IS_BC) || + if ((longopts[i].type == BC_OPT_BC_ONLY && BC_IS_DC) || (longopts[i].type == BC_OPT_DC_ONLY && BC_IS_BC)) { bc_opt_error(BC_ERROR_FATAL_OPTION, o->optopt, name); diff --git a/src/parse.c b/src/parse.c index 5d35fe66d3b63..a48f5807e9cef 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -64,25 +64,20 @@ static void bc_parse_update(BcParse *p, uchar inst, size_t idx) { void bc_parse_addString(BcParse *p) { - BcFunc *f = BC_IS_BC ? p->func : bc_vec_item(&p->prog->fns, BC_PROG_MAIN); + BcVec *strs = BC_IS_BC ? &p->func->strs : p->prog->strs; size_t idx; BC_SIG_LOCK; if (BC_IS_BC) { const char *str = bc_vm_strdup(p->l.str.v); - idx = f->strs.len; - bc_vec_push(&f->strs, &str); + idx = strs->len; + bc_vec_push(strs, &str); } #if DC_ENABLED else idx = bc_program_insertFunc(p->prog, p->l.str.v) - BC_PROG_REQ_FUNCS; #endif // DC_ENABLED -#ifndef NDEBUG - f = BC_IS_BC ? p->func : bc_vec_item(&p->prog->fns, BC_PROG_MAIN); - assert(f->strs.len > idx); -#endif // NDEBUG - bc_parse_update(p, BC_INST_STR, idx); BC_SIG_UNLOCK; @@ -90,16 +85,20 @@ void bc_parse_addString(BcParse *p) { static void bc_parse_addNum(BcParse *p, const char *string) { - BcFunc *f = BC_IS_BC ? p->func : bc_vec_item(&p->prog->fns, BC_PROG_MAIN); + BcVec *consts = &p->func->consts; size_t idx; BcConst c; + if (bc_parse_zero[0] == string[0] && bc_parse_zero[1] == string[1]) { + bc_parse_push(p, BC_INST_ZERO); + return; + } if (bc_parse_one[0] == string[0] && bc_parse_one[1] == string[1]) { bc_parse_push(p, BC_INST_ONE); return; } - idx = f->consts.len; + idx = consts->len; BC_SIG_LOCK; @@ -107,7 +106,7 @@ static void bc_parse_addNum(BcParse *p, const char *string) { c.base = BC_NUM_BIGDIG_MAX; bc_num_clear(&c.num); - bc_vec_push(&f->consts, &c); + bc_vec_push(consts, &c); bc_parse_update(p, BC_INST_NUM, idx); diff --git a/src/program.c b/src/program.c index 8f2270f5e71de..1a8176c76f968 100644 --- a/src/program.c +++ b/src/program.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -52,10 +52,10 @@ static void bc_program_addFunc(BcProgram *p, BcFunc *f, BcId *id_ptr); static inline void bc_program_setVecs(BcProgram *p, BcFunc *f) { p->consts = &f->consts; - p->strs = &f->strs; + if (BC_IS_BC) p->strs = &f->strs; } -static void bc_program_type_num(BcResult *r, BcNum *n) { +static inline void bc_program_type_num(BcResult *r, BcNum *n) { #if BC_ENABLED assert(r->t != BC_RESULT_VOID); @@ -68,7 +68,7 @@ static void bc_program_type_num(BcResult *r, BcNum *n) { static void bc_program_type_match(BcResult *r, BcType t) { #if DC_ENABLED - assert(!BC_IS_BC || BC_NO_ERR(r->t != BC_RESULT_STR)); + assert(BC_IS_DC || BC_NO_ERR(r->t != BC_RESULT_STR)); #endif // DC_ENABLED if (BC_ERR((r->t != BC_RESULT_ARRAY) != (!t))) @@ -89,6 +89,7 @@ static size_t bc_program_index(const char *restrict code, size_t *restrict bgn) return res; } +#if BC_ENABLED static void bc_program_prepGlobals(BcProgram *p) { size_t i; @@ -96,9 +97,9 @@ static void bc_program_prepGlobals(BcProgram *p) { for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) bc_vec_push(p->globals_v + i, p->globals + i); -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND bc_rand_push(&p->rng); -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND } static void bc_program_popGlobals(BcProgram *p, bool reset) { @@ -111,10 +112,11 @@ static void bc_program_popGlobals(BcProgram *p, bool reset) { p->globals[i] = BC_PROG_GLOBAL(v); } -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND bc_rand_pop(&p->rng, reset); -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND } +#endif // BC_ENABLED static void bc_program_pushBigdig(BcProgram *p, BcBigDig dig, BcResultType type) { @@ -182,38 +184,6 @@ static BcNum* bc_program_num(BcProgram *p, BcResult *r) { switch (r->t) { - case BC_RESULT_CONSTANT: - { - BcConst *c = bc_vec_item(p->consts, r->d.loc.loc); - BcBigDig base = BC_PROG_IBASE(p); - - if (c->base != base) { - - if (c->num.num == NULL) { - BC_SIG_LOCK; - bc_num_init(&c->num, BC_NUM_RDX(strlen(c->val))); - BC_SIG_UNLOCK; - } - - // bc_num_parse() should only do operations that cannot fail. - bc_num_parse(&c->num, c->val, base, !c->val[1]); - - c->base = base; - } - - BC_SIG_LOCK; - - n = &r->d.n; - - r->t = BC_RESULT_TEMP; - - bc_num_createCopy(n, &c->num); - - BC_SIG_UNLOCK; - - break; - } - case BC_RESULT_STR: case BC_RESULT_TEMP: case BC_RESULT_IBASE: @@ -263,6 +233,12 @@ static BcNum* bc_program_num(BcProgram *p, BcResult *r) { break; } + case BC_RESULT_ZERO: + { + n = &p->zero; + break; + } + case BC_RESULT_ONE: { n = &p->one; @@ -308,7 +284,7 @@ static void bc_program_binPrep(BcProgram *p, BcResult **l, BcNum **ln, assert(p != NULL && l != NULL && ln != NULL && r != NULL && rn != NULL); #ifndef BC_PROG_NO_STACK_CHECK - if (!BC_IS_BC) { + if (BC_IS_DC) { if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 2))) bc_vm_err(BC_ERROR_EXEC_STACK); } @@ -346,7 +322,7 @@ static void bc_program_assignPrep(BcProgram *p, BcResult **l, BcNum **ln, { BcResultType lt, min; - min = BC_RESULT_CONSTANT - ((unsigned int) (BC_IS_BC << 1)); + min = BC_RESULT_TEMP - ((unsigned int) (BC_IS_BC)); bc_program_binPrep(p, l, ln, r, rn, 0); @@ -356,7 +332,7 @@ static void bc_program_assignPrep(BcProgram *p, BcResult **l, BcNum **ln, bc_vm_err(BC_ERROR_EXEC_TYPE); #if DC_ENABLED - if(!BC_IS_BC) { + if(BC_IS_DC) { bool good = (((*r)->t == BC_RESULT_STR || BC_PROG_STR(*rn)) && lt <= BC_RESULT_ARRAY_ELEM); @@ -373,7 +349,7 @@ 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 - if (!BC_IS_BC) { + if (BC_IS_DC) { if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1))) bc_vm_err(BC_ERROR_EXEC_STACK); } @@ -400,6 +376,33 @@ static BcResult* bc_program_prepResult(BcProgram *p) { return bc_vec_top(&p->results); } +static void bc_program_const(BcProgram *p, const char *code, size_t *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); + + if (c->base != base) { + + if (c->num.num == NULL) { + BC_SIG_LOCK; + bc_num_init(&c->num, BC_NUM_RDX(strlen(c->val))); + BC_SIG_UNLOCK; + } + + // bc_num_parse() should only do operations that cannot fail. + bc_num_parse(&c->num, c->val, base, !c->val[1]); + + c->base = base; + } + + BC_SIG_LOCK; + + bc_num_createCopy(&r->d.n, &c->num); + + BC_SIG_UNLOCK; +} + static void bc_program_op(BcProgram *p, uchar inst) { BcResult *opd1, *opd2, *res; @@ -459,7 +462,9 @@ static void bc_program_read(BcProgram *p) { if (BC_ERR(parse.l.t != BC_LEX_NLINE && parse.l.t != BC_LEX_EOF)) bc_vm_err(BC_ERROR_EXEC_READ_EXPR); +#if BC_ENABLED if (BC_G) bc_program_prepGlobals(p); +#endif // BC_ENABLED ip.func = BC_PROG_READ; ip.idx = 0; @@ -470,8 +475,9 @@ static void bc_program_read(BcProgram *p) { bc_vec_pushByte(&f->code, vm.read_ret); bc_vec_push(&p->stack, &ip); + #if DC_ENABLED - if (!BC_IS_BC) { + if (BC_IS_DC) { size_t temp = 0; bc_vec_push(&p->tail_calls, &temp); } @@ -485,12 +491,12 @@ exec_err: BC_LONGJMP_CONT; } -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND static void bc_program_rand(BcProgram *p) { BcRand rand = bc_rand_int(&p->rng); bc_program_pushBigdig(p, (BcBigDig) rand, BC_RESULT_TEMP); } -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND static void bc_program_printChars(const char *str) { @@ -510,7 +516,7 @@ static void bc_program_printString(const char *restrict str) { size_t i, len = strlen(str); #if DC_ENABLED - if (!len && !BC_IS_BC) { + if (!len && BC_IS_DC) { bc_vm_putchar('\0'); return; } @@ -552,7 +558,7 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { assert(p != NULL); #ifndef BC_PROG_NO_STACK_CHECK - if (!BC_IS_BC) { + if (BC_IS_DC) { if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1))) bc_vm_err(BC_ERROR_EXEC_STACK); } @@ -560,9 +566,6 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { assert(BC_PROG_STACK(&p->results, idx + 1)); - assert(BC_IS_BC || - p->strs == &((BcFunc*) bc_vec_item(&p->fns, BC_PROG_MAIN))->strs); - r = bc_vec_item_rev(&p->results, idx); #if BC_ENABLED @@ -586,6 +589,7 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { size_t i = (r->t == BC_RESULT_STR) ? r->d.loc.loc : n->scale; + bc_file_flush(&vm.fout); str = *((char**) bc_vec_item(p->strs, i)); if (inst == BC_INST_PRINT_STR) bc_program_printChars(str); @@ -736,7 +740,7 @@ static void bc_program_copyToVar(BcProgram *p, size_t idx, bool var = (t == BC_TYPE_VAR); #if DC_ENABLED - if (!BC_IS_BC) { + if (BC_IS_DC) { if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERROR_EXEC_STACK); @@ -763,7 +767,7 @@ static void bc_program_copyToVar(BcProgram *p, size_t idx, vec = bc_program_vec(p, idx, t); #if DC_ENABLED - if (ptr->t == BC_RESULT_STR) { + if (BC_IS_DC && (ptr->t == BC_RESULT_STR || BC_PROG_STR(n))) { if (BC_ERR(!var)) bc_vm_err(BC_ERROR_EXEC_TYPE); bc_program_assignStr(p, ptr, vec, true); return; @@ -839,7 +843,7 @@ static void bc_program_assign(BcProgram *p, uchar inst) { if (right->t == BC_RESULT_STR || BC_PROG_STR(r)) { - size_t idx = right->d.loc.loc; + size_t idx = right->t == BC_RESULT_STR ? right->d.loc.loc : r->scale; if (left->t == BC_RESULT_ARRAY_ELEM) { BC_SIG_LOCK; @@ -891,7 +895,7 @@ static void bc_program_assign(BcProgram *p, uchar inst) { } else { min = BC_NUM_MIN_BASE; - if (BC_ENABLE_EXTRA_MATH && ob && (!BC_IS_BC || !BC_IS_POSIX)) + if (BC_ENABLE_EXTRA_MATH && ob && (BC_IS_DC || !BC_IS_POSIX)) min = 0; max = vm.maxes[ob + BC_PROG_GLOBALS_IBASE]; v = p->globals_v + BC_PROG_GLOBALS_IBASE + ob; @@ -904,9 +908,9 @@ static void bc_program_assign(BcProgram *p, uchar inst) { *ptr = val; *ptr_t = val; } -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND else if (left->t == BC_RESULT_SEED) bc_num_rng(l, &p->rng); -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND BC_SIG_LOCK; @@ -931,7 +935,7 @@ static void bc_program_pushVar(BcProgram *p, const char *restrict code, r.d.loc.loc = idx; #if DC_ENABLED - if (!BC_IS_BC && (pop || copy)) { + if (BC_IS_DC && (pop || copy)) { BcVec *v = bc_program_vec(p, idx, BC_TYPE_VAR); BcNum *num = bc_vec_top(v); @@ -989,8 +993,13 @@ static void bc_program_pushArray(BcProgram *p, const char *restrict code, r.t = BC_RESULT_ARRAY_ELEM; r.d.loc.idx = (size_t) temp; + + BC_SIG_LOCK; + bc_vec_pop(&p->results); bc_vec_push(&p->results, &r); + + BC_SIG_UNLOCK; } #if BC_ENABLED @@ -1160,14 +1169,14 @@ static void bc_program_builtin(BcProgram *p, uchar inst) { BcNum *num; bool len = (inst == BC_INST_LENGTH); -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND assert(inst >= BC_INST_LENGTH && inst <= BC_INST_IRAND); -#else // BC_ENABLE_EXTRA_MATH +#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND assert(inst >= BC_INST_LENGTH && inst <= BC_INST_ABS); -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND #ifndef BC_PROG_NO_STACK_CHECK - if (!BC_IS_BC) { + if (BC_IS_DC) { if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERROR_EXEC_STACK); } @@ -1196,7 +1205,7 @@ static void bc_program_builtin(BcProgram *p, uchar inst) { res->d.n.neg = false; } -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND else if (inst == BC_INST_IRAND) { BC_SIG_LOCK; @@ -1207,7 +1216,7 @@ static void bc_program_builtin(BcProgram *p, uchar inst) { bc_num_irand(num, &res->d.n, &p->rng); } -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND else { BcBigDig val = 0; @@ -1582,7 +1591,7 @@ static void bc_program_pushGlobal(BcProgram *p, uchar inst) { bc_program_pushBigdig(p, p->globals[inst - BC_INST_IBASE], t); } -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND static void bc_program_pushSeed(BcProgram *p) { BcResult *res; @@ -1598,7 +1607,7 @@ static void bc_program_pushSeed(BcProgram *p) { bc_num_createFromRNG(&res->d.n, &p->rng); } -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND static void bc_program_addFunc(BcProgram *p, BcFunc *f, BcId *id_ptr) { @@ -1610,11 +1619,10 @@ static void bc_program_addFunc(BcProgram *p, BcFunc *f, BcId *id_ptr) { bc_vec_push(&p->fns, f); // This is to make sure pointers are updated if the array was moved. - if (BC_IS_BC && p->stack.len) { - ip = bc_vec_item_rev(&p->stack, 0); + if (p->stack.len) { + ip = bc_vec_top(&p->stack); bc_program_setVecs(p, (BcFunc*) bc_vec_item(&p->fns, ip->func)); } - else bc_program_setVecs(p, (BcFunc*) bc_vec_item(&p->fns, BC_PROG_MAIN)); } size_t bc_program_insertFunc(BcProgram *p, const char *name) { @@ -1643,9 +1651,7 @@ size_t bc_program_insertFunc(BcProgram *p, const char *name) { bc_program_addFunc(p, &f, id_ptr); #if DC_ENABLED - if (!BC_IS_BC && strcmp(name, bc_func_main) && - strcmp(name, bc_func_read)) - { + if (BC_IS_DC && idx >= BC_PROG_REQ_FUNCS) { bc_vec_push(p->strs, &id_ptr->name); assert(p->strs->len == p->fns.len - BC_PROG_REQ_FUNCS); } @@ -1679,12 +1685,15 @@ void bc_program_free(BcProgram *p) { if (BC_IS_BC) bc_num_free(&p->last); #endif // BC_ENABLED -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND bc_rand_free(&p->rng); -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND #if DC_ENABLED - if (!BC_IS_BC) bc_vec_free(&p->tail_calls); + if (BC_IS_DC) { + bc_vec_free(&p->tail_calls); + bc_vec_free(&p->strs_v); + } #endif // DC_ENABLED } #endif // NDEBUG @@ -1710,7 +1719,10 @@ void bc_program_init(BcProgram *p) { } #if DC_ENABLED - if (!BC_IS_BC) { + if (BC_IS_DC) { + + bc_vec_init(&p->strs_v, sizeof(char*), bc_string_free); + p->strs = &p->strs_v; bc_vec_init(&p->tail_calls, sizeof(size_t), NULL); i = 0; @@ -1722,10 +1734,12 @@ void bc_program_init(BcProgram *p) { } #endif // DC_ENABLED -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND srand((unsigned int) time(NULL)); bc_rand_init(&p->rng); -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND + + bc_num_setup(&p->zero, p->zero_num, BC_PROG_ONE_CAP); bc_num_setup(&p->one, p->one_num, BC_PROG_ONE_CAP); bc_num_one(&p->one); @@ -1748,6 +1762,10 @@ void bc_program_init(BcProgram *p) { bc_vec_init(&p->results, sizeof(BcResult), bc_result_free); bc_vec_init(&p->stack, sizeof(BcInstPtr), NULL); bc_vec_push(&p->stack, &ip); + + bc_program_setVecs(p, (BcFunc*) bc_vec_item(&p->fns, BC_PROG_MAIN)); + + assert(p->consts != NULL && p->strs != NULL); } void bc_program_reset(BcProgram *p) { @@ -1760,11 +1778,13 @@ void bc_program_reset(BcProgram *p) { bc_vec_npop(&p->stack, p->stack.len - 1); bc_vec_npop(&p->results, p->results.len); +#if BC_ENABLED if (BC_G) bc_program_popGlobals(p, true); +#endif // BC_ENABLED f = bc_vec_item(&p->fns, BC_PROG_MAIN); ip = bc_vec_top(&p->stack); - if (BC_IS_BC) bc_program_setVecs(p, f); + bc_program_setVecs(p, f); ip->idx = f->code.len; if (vm.sig) { @@ -1779,7 +1799,7 @@ void bc_program_exec(BcProgram *p) { size_t idx; BcResult r, *ptr; BcInstPtr *ip = bc_vec_top(&p->stack); - BcFunc *func = bc_vec_item(&p->fns, ip->func); + BcFunc *func = (BcFunc*) bc_vec_item(&p->fns, ip->func); char *code = func->code.v; bool cond = false; #if BC_ENABLED @@ -1793,8 +1813,7 @@ void bc_program_exec(BcProgram *p) { jmp_bufs_len = vm.jmp_bufs.len; #endif // NDEBUG - if (BC_IS_BC) bc_program_setVecs(p, func); - else bc_program_setVecs(p, (BcFunc*) bc_vec_item(&p->fns, BC_PROG_MAIN)); + bc_program_setVecs(p, func); while (ip->idx < func->code.len) { @@ -1867,7 +1886,7 @@ void bc_program_exec(BcProgram *p) { func = bc_vec_item(&p->fns, ip->func); code = func->code.v; - if (BC_IS_BC) bc_program_setVecs(p, func); + bc_program_setVecs(p, func); break; } @@ -1894,25 +1913,25 @@ void bc_program_exec(BcProgram *p) { func = bc_vec_item(&p->fns, ip->func); code = func->code.v; - if (BC_IS_BC) bc_program_setVecs(p, func); + bc_program_setVecs(p, func); break; } -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_INST_RAND: { bc_program_rand(p); break; } -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_INST_MAXIBASE: case BC_INST_MAXOBASE: case BC_INST_MAXSCALE: -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_INST_MAXRAND: -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND { BcBigDig dig = vm.maxes[inst - BC_INST_MAXIBASE]; bc_program_pushBigdig(p, dig, BC_RESULT_TEMP); @@ -1942,21 +1961,21 @@ void bc_program_exec(BcProgram *p) { break; } -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_INST_SEED: { bc_program_pushSeed(p); break; } -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_INST_LENGTH: case BC_INST_SCALE_FUNC: case BC_INST_SQRT: case BC_INST_ABS: -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND case BC_INST_IRAND: -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND { bc_program_builtin(p, inst); break; @@ -1964,18 +1983,17 @@ void bc_program_exec(BcProgram *p) { case BC_INST_NUM: { - r.t = BC_RESULT_CONSTANT; - r.d.loc.loc = bc_program_index(code, &ip->idx); - bc_vec_push(&p->results, &r); + bc_program_const(p, code, &ip->idx); break; } + case BC_INST_ZERO: case BC_INST_ONE: #if BC_ENABLED case BC_INST_LAST: #endif // BC_ENABLED { - r.t = BC_RESULT_ONE + (inst - BC_INST_ONE); + r.t = BC_RESULT_ZERO + (inst - BC_INST_ZERO); bc_vec_push(&p->results, &r); break; } @@ -2077,6 +2095,7 @@ void bc_program_exec(BcProgram *p) { ip = bc_vec_top(&p->stack); func = bc_vec_item(&p->fns, ip->func); code = func->code.v; + bc_program_setVecs(p, func); break; } @@ -2100,6 +2119,7 @@ void bc_program_exec(BcProgram *p) { ip = bc_vec_top(&p->stack); func = bc_vec_item(&p->fns, ip->func); code = func->code.v; + bc_program_setVecs(p, func); break; } @@ -2164,6 +2184,7 @@ void bc_program_exec(BcProgram *p) { ip = bc_vec_top(&p->stack); func = bc_vec_item(&p->fns, ip->func); code = func->code.v; + bc_program_setVecs(p, func); break; } @@ -2195,6 +2216,7 @@ void bc_program_exec(BcProgram *p) { ip = bc_vec_top(&p->stack); func = bc_vec_item(&p->fns, ip->func); code = func->code.v; + bc_program_setVecs(p, func); break; } #endif // DC_ENABLED diff --git a/src/rand/rand.c b/src/rand/rand.c index aa589bbd533d8..b16061d711a1d 100644 --- a/src/rand/rand.c +++ b/src/rand/rand.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2019 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2019 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -66,8 +66,6 @@ * */ -#if BC_ENABLE_EXTRA_MATH - #include <assert.h> #include <stdlib.h> #include <string.h> @@ -80,6 +78,8 @@ #include <rand.h> #include <vm.h> +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND + #if !BC_RAND_BUILTIN static BcRandState bc_rand_addition(uint_fast64_t a, uint_fast64_t b) { @@ -412,4 +412,4 @@ void bc_rand_free(BcRNG *r) { } #endif // NDEBUG -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND diff --git a/src/read.c b/src/read.c index c63952523181f..6886a7e13602b 100644 --- a/src/read.c +++ b/src/read.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -61,29 +61,29 @@ static bool bc_read_binary(const char *buf, size_t size) { return false; } -static bool bc_read_buf(BcVec *vec) { +bool bc_read_buf(BcVec *vec, char *buf, size_t *buf_len) { char *nl; - if (!vm.buf_len) return false; + if (!*buf_len) return false; - nl = strchr(vm.buf, '\n'); + nl = strchr(buf, '\n'); if (nl != NULL) { - size_t nllen = (size_t) ((nl + 1) - vm.buf); + size_t nllen = (size_t) ((nl + 1) - buf); - nllen = vm.buf_len >= nllen ? nllen : vm.buf_len; + nllen = *buf_len >= nllen ? nllen : *buf_len; - bc_vec_npush(vec, nllen, vm.buf); - vm.buf_len -= nllen; - memmove(vm.buf, nl + 1, vm.buf_len); + bc_vec_npush(vec, nllen, buf); + *buf_len -= nllen; + memmove(buf, nl + 1, *buf_len + 1); return true; } - bc_vec_npush(vec, vm.buf_len, vm.buf); - vm.buf_len = 0; + bc_vec_npush(vec, *buf_len, buf); + *buf_len = 0; return false; } @@ -105,7 +105,7 @@ BcStatus bc_read_chars(BcVec *vec, const char *prompt) { } #endif // BC_ENABLE_PROMPT - if (bc_read_buf(vec)) { + if (bc_read_buf(vec, vm.buf, &vm.buf_len)) { bc_vec_pushByte(vec, '\0'); return BC_STATUS_SUCCESS; } @@ -154,8 +154,9 @@ BcStatus bc_read_chars(BcVec *vec, const char *prompt) { } vm.buf_len += (size_t) r; + vm.buf[vm.buf_len] = '\0'; - done = bc_read_buf(vec); + done = bc_read_buf(vec, vm.buf, &vm.buf_len); } bc_vec_pushByte(vec, '\0'); diff --git a/src/vector.c b/src/vector.c index 28c7440693ebf..f45bcb198a25f 100644 --- a/src/vector.c +++ b/src/vector.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -86,20 +86,19 @@ void bc_vec_expand(BcVec *restrict v, size_t req) { void bc_vec_npop(BcVec *restrict v, size_t n) { + sig_atomic_t lock; + assert(v != NULL && n <= v->len); + BC_SIG_TRYLOCK(lock); + if (v->dtor == NULL) v->len -= n; else { - - sig_atomic_t lock; size_t len = v->len - n; - - BC_SIG_TRYLOCK(lock); - while (v->len > len) v->dtor(v->v + (v->size * --v->len)); - - BC_SIG_TRYUNLOCK(lock); } + + BC_SIG_TRYUNLOCK(lock); } void bc_vec_npopAt(BcVec *restrict v, size_t n, size_t idx) { @@ -112,26 +111,35 @@ void bc_vec_npopAt(BcVec *restrict v, size_t n, size_t idx) { ptr = bc_vec_item(v, idx); data = bc_vec_item(v, idx + n); + BC_SIG_LOCK; + if (v->dtor != NULL) { size_t i; - BC_SIG_LOCK; - for (i = 0; i < n; ++i) v->dtor(bc_vec_item(v, idx + i)); - - BC_SIG_UNLOCK; } v->len -= n; memmove(ptr, data, (v->len - idx) * v->size); + + BC_SIG_UNLOCK; } void bc_vec_npush(BcVec *restrict v, size_t n, const void *data) { + + sig_atomic_t lock; + assert(v != NULL && data != NULL); + + BC_SIG_TRYLOCK(lock); + if (v->len + n > v->cap) bc_vec_grow(v, n); + memcpy(v->v + (v->size * v->len), data, v->size * n); v->len += n; + + BC_SIG_TRYUNLOCK(lock); } inline void bc_vec_push(BcVec *restrict v, const void *data) { @@ -140,32 +148,35 @@ inline void bc_vec_push(BcVec *restrict v, const void *data) { void bc_vec_pushByte(BcVec *restrict v, uchar data) { assert(v != NULL && v->size == sizeof(uchar)); - if (v->len == v->cap) bc_vec_grow(v, 1); - v->v[v->len] = (char) data; - v->len += 1; + bc_vec_npush(v, 1, &data); } void bc_vec_pushIndex(BcVec *restrict v, size_t idx) { - uchar amt, nums[sizeof(size_t)]; + uchar amt, nums[sizeof(size_t) + 1]; assert(v != NULL); assert(v->size == sizeof(uchar)); for (amt = 0; idx; ++amt) { - nums[amt] = (uchar) idx; + nums[amt + 1] = (uchar) idx; idx &= ((size_t) ~(UCHAR_MAX)); idx >>= sizeof(uchar) * CHAR_BIT; } - bc_vec_push(v, &amt); - bc_vec_npush(v, amt, nums); + nums[0] = amt; + + bc_vec_npush(v, amt + 1, nums); } static void bc_vec_pushAt(BcVec *restrict v, const void *data, size_t idx) { + sig_atomic_t lock; + assert(v != NULL && data != NULL && idx <= v->len); + BC_SIG_TRYLOCK(lock); + if (idx == v->len) bc_vec_push(v, data); else { @@ -178,40 +189,62 @@ static void bc_vec_pushAt(BcVec *restrict v, const void *data, size_t idx) { memmove(ptr + v->size, ptr, v->size * (v->len++ - idx)); memmove(ptr, data, v->size); } + + BC_SIG_TRYUNLOCK(lock); } void bc_vec_string(BcVec *restrict v, size_t len, const char *restrict str) { + sig_atomic_t lock; + assert(v != NULL && v->size == sizeof(char)); assert(v->dtor == NULL); assert(!v->len || !v->v[v->len - 1]); assert(v->v != str); + BC_SIG_TRYLOCK(lock); + bc_vec_npop(v, v->len); bc_vec_expand(v, bc_vm_growSize(len, 1)); memcpy(v->v, str, len); v->len = len; bc_vec_pushByte(v, '\0'); + + BC_SIG_TRYUNLOCK(lock); } void bc_vec_concat(BcVec *restrict v, const char *restrict str) { + sig_atomic_t lock; + assert(v != NULL && v->size == sizeof(char)); assert(v->dtor == NULL); assert(!v->len || !v->v[v->len - 1]); assert(v->v != str); + BC_SIG_TRYLOCK(lock); + if (v->len) v->len -= 1; bc_vec_npush(v, strlen(str) + 1, str); + + BC_SIG_TRYUNLOCK(lock); } void bc_vec_empty(BcVec *restrict v) { + + sig_atomic_t lock; + assert(v != NULL && v->size == sizeof(char)); assert(v->dtor == NULL); + + BC_SIG_TRYLOCK(lock); + bc_vec_npop(v, v->len); bc_vec_pushByte(v, '\0'); + + BC_SIG_TRYUNLOCK(lock); } #if BC_ENABLE_HISTORY @@ -242,6 +275,7 @@ inline void* bc_vec_item_rev(const BcVec *restrict v, size_t idx) { } inline void bc_vec_clear(BcVec *restrict v) { + BC_SIG_ASSERT_LOCKED; v->v = NULL; v->len = 0; v->dtor = NULL; diff --git a/src/vm.c b/src/vm.c index d569cc70a0086..b3dee16b2e28c 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1,9 +1,9 @@ /* * ***************************************************************************** * - * Copyright (c) 2018-2020 Gavin D. Howard and contributors. + * SPDX-License-Identifier: BSD-2-Clause * - * All rights reserved. + * Copyright (c) 2018-2020 Gavin D. Howard and contributors. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -69,7 +69,7 @@ BC_NORETURN void bc_vm_jmp(const char* f) { BC_NORETURN void bc_vm_jmp(void) { #endif - assert(vm.status != BC_STATUS_SUCCESS || vm.sig); + assert(BC_SIG_EXC); BC_SIG_MAYLOCK; @@ -191,11 +191,13 @@ void bc_vm_error(BcError e, size_t line, ...) { bc_file_putchar(&vm.ferr, ' '); bc_file_puts(&vm.ferr, f->name); +#if BC_ENABLED if (BC_IS_BC && ip->func != BC_PROG_MAIN && ip->func != BC_PROG_READ) { bc_file_puts(&vm.ferr, "()"); } +#endif // BC_ENABLED } } @@ -327,14 +329,14 @@ void bc_vm_shutdown(void) { bc_file_free(&vm.ferr); } -size_t bc_vm_arraySize(size_t n, size_t size) { +inline size_t bc_vm_arraySize(size_t n, size_t size) { size_t res = n * size; if (BC_ERR(res >= SIZE_MAX || (n != 0 && res / n != size))) bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR); return res; } -size_t bc_vm_growSize(size_t a, size_t b) { +inline size_t bc_vm_growSize(size_t a, size_t b) { size_t res = a + b; if (BC_ERR(res >= SIZE_MAX || res < a || res < b)) bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR); @@ -402,11 +404,10 @@ void bc_vm_putchar(int c) { static void bc_vm_clean(void) { - BcProgram *prog = &vm.prog; - BcVec *fns = &prog->fns; + BcVec *fns = &vm.prog.fns; BcFunc *f = bc_vec_item(fns, BC_PROG_MAIN); - BcInstPtr *ip = bc_vec_item(&prog->stack, 0); - bool good = (vm.status && vm.status != BC_STATUS_QUIT); + BcInstPtr *ip = bc_vec_item(&vm.prog.stack, 0); + bool good = ((vm.status && vm.status != BC_STATUS_QUIT) || vm.sig); if (good) bc_program_reset(&vm.prog); @@ -415,53 +416,38 @@ static void bc_vm_clean(void) { #endif // BC_ENABLED #if DC_ENABLED - if (!BC_IS_BC) { + if (BC_IS_DC) { size_t i; - for (i = 0; i < vm.prog.vars.len; ++i) { - BcVec *arr = bc_vec_item(&vm.prog.vars, i); - BcNum *n = bc_vec_top(arr); - if (arr->len != 1 || BC_PROG_STR(n)) break; - } - - if (i == vm.prog.vars.len) { - - for (i = 0; i < vm.prog.arrs.len; ++i) { - - BcVec *arr = bc_vec_item(&vm.prog.arrs, i); - size_t j; - - assert(arr->len == 1); - - arr = bc_vec_top(arr); - - for (j = 0; j < arr->len; ++j) { - BcNum *n = bc_vec_item(arr, j); - if (BC_PROG_STR(n)) break; - } - - if (j != arr->len) break; - } + good = true; - good = (i == vm.prog.arrs.len); + for (i = 0; good && i < vm.prog.results.len; ++i) { + BcResult *r = (BcResult*) bc_vec_item(&vm.prog.results, i); + good = BC_VM_SAFE_RESULT(r); } } #endif // DC_ENABLED // If this condition is true, we can get rid of strings, // constants, and code. This is an idea from busybox. - if (good && prog->stack.len == 1 && !prog->results.len && - ip->idx == f->code.len) - { + if (good && vm.prog.stack.len == 1 && ip->idx == f->code.len) { + #if BC_ENABLED if (BC_IS_BC) { bc_vec_npop(&f->labels, f->labels.len); bc_vec_npop(&f->strs, f->strs.len); + bc_vec_npop(&f->consts, f->consts.len); } #endif // BC_ENABLED - bc_vec_npop(&f->consts, f->consts.len); + +#if DC_ENABLED + // Note to self: you cannot delete strings and functions. Deal with it. + if (BC_IS_DC) bc_vec_npop(vm.prog.consts, vm.prog.consts->len); +#endif // DC_ENABLED + bc_vec_npop(&f->code, f->code.len); + ip->idx = 0; } } @@ -494,6 +480,9 @@ static void bc_vm_process(const char *text, bool is_stdin) { #endif // BC_ENABLED bc_program_exec(&vm.prog); + + assert(BC_IS_DC || vm.prog.results.len == 0); + if (BC_I) bc_file_flush(&vm.fout); } while (vm.prs.l.t != BC_LEX_EOF); @@ -604,6 +593,7 @@ restart: bc_vec_empty(&buffer); if (vm.eof) break; + else bc_vm_clean(); } if (!BC_STATUS_IS_ERROR(s)) { @@ -707,6 +697,7 @@ static void bc_vm_exec(const char* env_exp_exit) { size_t i; bool has_file = false; + BcVec buf; #if BC_ENABLED if (BC_IS_BC && (vm.flags & BC_FLAG_L)) { @@ -720,8 +711,40 @@ static void bc_vm_exec(const char* env_exp_exit) { #endif // BC_ENABLED if (vm.exprs.len) { + + size_t len = vm.exprs.len - 1; + bool more; + + BC_SIG_LOCK; + bc_vec_init(&buf, sizeof(uchar), NULL); + +#ifndef NDEBUG + BC_SETJMP_LOCKED(err); +#endif // NDEBUG + + BC_SIG_UNLOCK; + bc_lex_file(&vm.prs.l, bc_program_exprs_name); - bc_vm_process(vm.exprs.v, false); + + do { + + more = bc_read_buf(&buf, vm.exprs.v, &len); + bc_vec_pushByte(&buf, '\0'); + bc_vm_process(buf.v, false); + + bc_vec_npop(&buf, buf.len); + + } while (more); + + BC_SIG_LOCK; + bc_vec_free(&buf); + +#ifndef NDEBUG + BC_UNSETJMP; +#endif // NDEBUG + + BC_SIG_UNLOCK; + if (getenv(env_exp_exit) != NULL) return; } @@ -733,6 +756,18 @@ static void bc_vm_exec(const char* env_exp_exit) { } if (BC_IS_BC || !has_file) bc_vm_stdin(); + +// These are all protected by ifndef NDEBUG because if these are needed, bc is +// goingi to exit anyway, and I see no reason to include this code in a release +// build when the OS is going to free all of the resources anyway. +#ifndef NDEBUG + return; + +err: + BC_SIG_MAYLOCK; + bc_vec_free(&buf); + BC_LONGJMP_CONT; +#endif // NDEBUG } void bc_vm_boot(int argc, char *argv[], const char *env_len, @@ -798,18 +833,22 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len, bc_vm_envArgs(env_args); bc_args(argc, argv); +#if BC_ENABLED if (BC_IS_POSIX) vm.flags &= ~(BC_FLAG_G); +#endif // BC_ENABLED vm.maxes[BC_PROG_GLOBALS_IBASE] = BC_NUM_MAX_POSIX_IBASE; vm.maxes[BC_PROG_GLOBALS_OBASE] = BC_MAX_OBASE; vm.maxes[BC_PROG_GLOBALS_SCALE] = BC_MAX_SCALE; -#if BC_ENABLE_EXTRA_MATH +#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND vm.maxes[BC_PROG_MAX_RAND] = ((BcRand) 0) - 1; -#endif // BC_ENABLE_EXTRA_MATH +#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND +#if BC_ENABLED if (BC_IS_BC && !BC_IS_POSIX) vm.maxes[BC_PROG_GLOBALS_IBASE] = BC_NUM_MAX_IBASE; +#endif // BC_ENABLED if (BC_IS_BC && BC_I && !(vm.flags & BC_FLAG_Q)) bc_vm_info(NULL); |