diff options
Diffstat (limited to 'contrib/bc/include/lang.h')
-rw-r--r-- | contrib/bc/include/lang.h | 147 |
1 files changed, 88 insertions, 59 deletions
diff --git a/contrib/bc/include/lang.h b/contrib/bc/include/lang.h index 5a678ed34a25..97aeeaa98da8 100644 --- a/contrib/bc/include/lang.h +++ b/contrib/bc/include/lang.h @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (c) 2018-2021 Gavin D. Howard and contributors. + * Copyright (c) 2018-2023 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: @@ -38,15 +38,19 @@ #include <stdbool.h> +// These have to come first to silence a warning on BC_C11 below. #include <status.h> #include <vector.h> #include <num.h> -/// The instructions for bytecode. -typedef enum BcInst { +#if BC_C11 +#include <assert.h> +#endif // BC_C11 +/// The instructions for bytecode. +typedef enum BcInst +{ #if BC_ENABLED - /// Postfix increment and decrement. Prefix are translated into /// BC_INST_ONE with either BC_INST_ASSIGN_PLUS or BC_INST_ASSIGN_MINUS. BC_INST_INC = 0, @@ -58,6 +62,7 @@ typedef enum BcInst { /// Boolean not. BC_INST_BOOL_NOT, + #if BC_ENABLE_EXTRA_MATH /// Truncation operator. BC_INST_TRUNC, @@ -72,7 +77,6 @@ typedef enum BcInst { BC_INST_MINUS, #if BC_ENABLE_EXTRA_MATH - /// Places operator. BC_INST_PLACES, @@ -174,6 +178,8 @@ typedef enum BcInst { BC_INST_SCALE_FUNC, BC_INST_SQRT, BC_INST_ABS, + BC_INST_IS_NUMBER, + BC_INST_IS_STRING, #if BC_ENABLE_EXTRA_MATH /// Another builtin function. @@ -200,6 +206,19 @@ typedef enum BcInst { BC_INST_MAXRAND, #endif // BC_ENABLE_EXTRA_MATH + /// bc line_length() builtin function. + BC_INST_LINE_LENGTH, + +#if BC_ENABLED + + /// bc global_stacks() builtin function. + BC_INST_GLOBAL_STACKS, + +#endif // BC_ENABLED + + /// bc leading_zero() builtin function. + BC_INST_LEADING_ZERO, + /// This is slightly misnamed versus BC_INST_PRINT_POP. Well, it is in bc. /// dc uses this instruction to print, but not pop. That's valid in dc. /// However, in bc, it is *never* valid to print without popping. In bc, @@ -258,6 +277,9 @@ typedef enum BcInst { #if DC_ENABLED + /// dc extended registers command. + BC_INST_EXTENDED_REGISTERS, + /// dc's return; it pops an executing string off of the stack. BC_INST_POP_EXEC, @@ -311,11 +333,16 @@ typedef enum BcInst { } BcInst; -/// Used by maps to identify where items are in the array. -typedef struct BcId { +#if BC_C11 +_Static_assert(BC_INST_INVALID <= UCHAR_MAX, + "Too many instructions to fit into an unsigned char"); +#endif // BC_C11 +/// Used by maps to identify where items are in the array. +typedef struct BcId +{ /// The name of the item. - char *name; + char* name; /// The index into the array where the item is. size_t idx; @@ -323,21 +350,27 @@ typedef struct BcId { } BcId; /// The location of a var, array, or array element. -typedef struct BcLoc { - +typedef struct BcLoc +{ /// The index of the var or array. size_t loc; + /// The index of the array or variable in the array stack. This is to + /// prevent a bug with getting the wrong array element or variable after a + /// function call. See the tests/bc/scripts/array.bc test for the array + /// case; the variable case is in various variable tests. + size_t stack_idx; + /// The index of the array element. Only used for array elements. size_t idx; } BcLoc; /// An entry for a constant. -typedef struct BcConst { - +typedef struct BcConst +{ /// The original string as parsed from the source code. - char *val; + char* val; /// The last base that the constant was parsed in. BcBigDig base; @@ -350,8 +383,8 @@ typedef struct BcConst { /// A function. This is also used in dc, not just bc. The reason is that strings /// are executed in dc, and they are converted to functions in order to be /// executed. -typedef struct BcFunc { - +typedef struct BcFunc +{ /// The bytecode instructions. BcVec code; @@ -370,14 +403,8 @@ typedef struct BcFunc { #endif // BC_ENABLED - /// The strings encountered in the function. - BcVec strs; - - /// The constants encountered in the function. - BcVec consts; - /// The function's name. - const char *name; + const char* name; #if BC_ENABLED /// True if the function is a void function. @@ -387,8 +414,8 @@ typedef struct BcFunc { } BcFunc; /// Types of results that can be pushed onto the results stack. -typedef enum BcResultType { - +typedef enum BcResultType +{ /// Result is a variable. BC_RESULT_VAR, @@ -442,8 +469,8 @@ typedef enum BcResultType { } BcResultType; /// A union to store data for various result types. -typedef union BcResultData { - +typedef union BcResultData +{ /// A number. Strings are stored here too; they are numbers with /// cap == 0 && num == NULL. The string's index into the strings vector is /// stored in the scale field. But this is only used for strings stored in @@ -460,8 +487,8 @@ typedef union BcResultData { } BcResultData; /// A tagged union for results. -typedef struct BcResult { - +typedef struct BcResult +{ /// The tag. The type of the result. BcResultType t; @@ -472,8 +499,8 @@ typedef struct BcResult { /// An instruction pointer. This is how bc knows where in the bytecode vector, /// and which function, the current execution is. -typedef struct BcInstPtr { - +typedef struct BcInstPtr +{ /// The index of the currently executing function in the fns vector. size_t func; @@ -488,8 +515,8 @@ typedef struct BcInstPtr { } BcInstPtr; /// Types of identifiers. -typedef enum BcType { - +typedef enum BcType +{ /// Variable. BC_TYPE_VAR, @@ -507,8 +534,8 @@ typedef enum BcType { #if BC_ENABLED /// An auto variable in bc. -typedef struct BcAuto { - +typedef struct BcAuto +{ /// The index of the variable in the vars or arrs vectors. size_t idx; @@ -527,7 +554,8 @@ struct BcProgram; * @param name The name of the function. The string is assumed to be owned by * some other entity. */ -void bc_func_init(BcFunc *f, const char* name); +void +bc_func_init(BcFunc* f, const char* name); /** * Inserts an auto into the function. @@ -538,25 +566,28 @@ void bc_func_init(BcFunc *f, const char* name); * @param line The line in the source code where the insert happened. This is * solely for error reporting. */ -void bc_func_insert(BcFunc *f, struct BcProgram* p, char* name, - BcType type, size_t line); +void +bc_func_insert(BcFunc* f, struct BcProgram* p, char* name, BcType type, + size_t line); /** * Resets a function in preparation for it to be reused. This can happen in bc * because it is a dynamic language and functions can be redefined. * @param f The functio to reset. */ -void bc_func_reset(BcFunc *f); +void +bc_func_reset(BcFunc* f); -#ifndef NDEBUG +#if BC_DEBUG /** * Frees a function. This is a destructor. This is only used in debug builds * because all functions are freed at exit. We free them in debug builds to * check for memory leaks. * @param func The function to free as a void pointer. */ -void bc_func_free(void *func); -#endif // NDEBUG +void +bc_func_free(void* func); +#endif // BC_DEBUG /** * Initializes an array, which is the array type in bc and dc source code. Since @@ -569,7 +600,8 @@ void bc_func_free(void *func); * @param nums True if the array should be for numbers, false if it should be * for vectors. */ -void bc_array_init(BcVec *a, bool nums); +void +bc_array_init(BcVec* a, bool nums); /** * Copies an array to another array. This is used to do pass arrays to functions @@ -578,19 +610,22 @@ void bc_array_init(BcVec *a, bool nums); * @param d The destination array. * @param s The source array. */ -void bc_array_copy(BcVec *d, const BcVec *s); +void +bc_array_copy(BcVec* d, const BcVec* s); /** * Frees a string stored in a function. This is a destructor. * @param string The string to free as a void pointer. */ -void bc_string_free(void *string); +void +bc_string_free(void* string); /** * Frees a constant stored in a function. This is a destructor. * @param constant The constant to free as a void pointer. */ -void bc_const_free(void *constant); +void +bc_const_free(void* constant); /** * Clears a result. It sets the type to BC_RESULT_TEMP and clears the union by @@ -598,7 +633,8 @@ void bc_const_free(void *constant); * uninitialized data. * @param r The result to clear. */ -void bc_result_clear(BcResult *r); +void +bc_result_clear(BcResult* r); /** * Copies a result into another. This is done for things like duplicating the @@ -607,13 +643,15 @@ void bc_result_clear(BcResult *r); * @param d The destination result. * @param src The source result. */ -void bc_result_copy(BcResult *d, BcResult *src); +void +bc_result_copy(BcResult* d, BcResult* src); /** * Frees a result. This is a destructor. * @param result The result to free as a void pointer. */ -void bc_result_free(void *result); +void +bc_result_free(void* result); /** * Expands an array to @a len. This can happen because in bc, you do not have to @@ -624,17 +662,8 @@ void bc_result_free(void *result); * @param a The array to expand. * @param len The length to expand to. */ -void bc_array_expand(BcVec *a, size_t len); - -/** - * Compare two BcId's and return the result. Since they are just comparing the - * names in the BcId, I return the result from strcmp() exactly. This is used by - * maps in their binary search. - * @param e1 The first id. - * @param e2 The second id. - * @return The result of strcmp() on the BcId's names. - */ -int bc_id_cmp(const BcId *e1, const BcId *e2); +void +bc_array_expand(BcVec* a, size_t len); #if BC_ENABLED |