The <estack.h> header file


  
This header file contains the following functions:
all_tail                                any_tail
are_expressions_identical               can_be_approxed
check_estack_size                       compare_complex_magnitudes
compare_expressions                     compare_Floats
delete_between                          deleted_between
delete_expression                       deleted_expression
did_push_cnvrt_Float_to_integer         display_statements
estack_number_to_Float                  estack_to_short
estack_to_ushort                        factor_base_index
factor_exponent_index                   gcd_exact_whole_Floats
get_key_ptr                             GetValue
HS_popEStack                            HToESI
im_index                                index_below_display_expression_aux
index_main_var                          index_numeric_term
index_of_lead_base_of_lead_term         is_advanced_tag
is_antisymmetric                        is_complex_number
is_complex0                             is_Float_exact_whole_number
is_free_of_tag                          is_independent_of
is_independent_of_de_seq_vars           is_independent_of_elements
is_independent_of_tail                  is_matrix
is_monomial                             is_monomial_in_kernel
is_narrowly_independent_of              is_square_matrix
is_symmetric                            is_tail_indepenent_of
is_valid_smap_aggregate                 last_element_index
lead_base_index                         lead_exponent_index
lead_factor_index                       lead_term_index
likely_approx_to_complex_number         likely_approx_to_number
main_gen_var_index                      map_tail
map_tail_Int                            map_unary_over_comparison
min_quantum                             move_between_to_top
moved_between_to_top                    next_expression_index
NG_approxESI                            NG_execute
NG_graphESI                             NG_rationalESI
NG_tokenize                             NG_RPNToText
norm1_complex_Float                     numeric_factor_index
Parms2D                                 Parse1DExpr
Parse2DExpr                             Parse2DMultiExpr
Print2DExpr                             push_ANSI_string
push_between                            push_cnvrt_integer_if_whole_nmb
push_END_TAG                            push_expr_quantum
push_expr2_quantum                      push_Float
push_Float_to_nonneg_int                push_Float_to_rat
push_internal_simplify                  push_list_plus
push_LIST_TAG                           push_list_times
push_longint                            push_matrix_product
push_next_arb_int                       push_next_arb_real
push_next_internal_var                  push_offset_array
push_overflow_to_infinity               push_parse_text
push_pow                                push_quantum
push_quantum_pair                       push_reversed_tail
push_round_Float                        push_string
re_index                                reductum_index
remaining_element_count                 remaining_factors_index
reset_estack_size                       reset_control_flags
should_and_did_push_approx_arg2         signum_Float
the following global variables:
top_estack
and the following constants and predefined types:
bcd                 Bool                ESI                  ExtTags
HANDLE              H_NULL              InstructionTags      NULL
Tags                ti_float            SCR_RECT             SysvarTags
WINDOW
NOTE: See also related header file args.h.


Functions


void reset_control_flags (void);

Resets the control flags for operations with the expressions stack.

reset_control_flags resets various control flags which control operations which uses the expressions stack. It is good idea to call this function before starting any calculation using the expressions stack.

void push_quantum (unsigned char Tag);

Pushes a byte (tag) to the expressions stack.

push_quantum is a basic function for manipulating with the expressions stack, and many other functions are based on it. It pushes a byte Tag to the expressions stack. For example, you can push a complex value to the expressions stack using the following construction:
push_Float (real_part);
push_Float (imaginary_part);
push_quantum (COMPLEX_TAG);
See push_Float, and info about top_estack and Tags for more info about this example.

NOTE: This routine (including all other "push_..." routines) may cause heap compression, and may throw an error if there is not enough space on the expressions stack.

void push_quantum_pair (unsigned char Tag1, unsigned char Tag2);

Pushes two bytes (tags) to the expressions stack.

push_quantum_pair pushes bytes Tag1 and Tag2 to the expressions stack.

void push_longint (long value);

Pushes an integer to the expressions stack.

push_longint pushes an integer value value to the expressions stack.

NOTE: push_longint is not a TIOS entry; it is implemented "by hand" using push_quantum and push_quantum_pair.

void push_ANSI_string (const char *str);

Pushes a (ANSI) string to the expressions stack.

push_ANSI_string pushes the string str to the expressions stack. str is a standard ANSI string (zero terminated string).

NOTE: push_ANSI_string is a macro which calls push_string, strlen and strcpy.

void push_string (const char *str);

Pushes a (TIOS) string or stringficated expression to the expressions stack.

push_string is a very powerful TIOS entry which may be used for two purposes. In one way, it can work similarly like push_ANSI_string, but it expects that the string is "zero-bounded" from both sides, and that str is the pointer to the terminating zero of the string. For more info about such strings see vat.h header file, and $ macro constructor. But, push_string is much more powerful. str may point to a tag of an arbitrary expression. This expression will be converted to a printable form (see display_statements), and the result of the conversion will be pushed on the stack as a string. For example, after execution of
push_longint (100);
push_quantum_pair (VAR_X_TAG, ADD_TAG);
push_string (top_estack);
the string "x+100" will be pushed at the top of the expressions stack. See info about top_estack and Tags for more info about this example.

NOTE: If the string is known in advance (i.e. if it is a constant, for example "abc"), it is better to use push_string ($(abc)) than push_ANSI_string ("abc"): it will generate a shorter and more efficient code.

void push_Float (float value);

Pushes a floating point value to the expressions stack.

push_Float rounds value to the 14 significant digits (using round14), then pushes it to the expressions stack. If value is not representable as a finite float, the most appropriate transfinite tag is pushed.

void push_Float_to_nonneg_int (float value);

Rounds a floating point value to an integer, then push it to the expressions stack.

push_Float_to_nonneg_int rounds value to the nearest integer, then pushes it to the expressions stack, as a tagged integer value. The sign of value is ignored. This routine may throw an error if the truncated integer part of value is not representable as a big integer.

void push_Float_to_rat (ESI ptr);

Pushes a rational approximation of a floating point entry.

push_Float_to_rat finds a rational approximation of the floating point entry pointed to by ptr (of course, ptr points to the tag), and pushes it on the top of the expressions stack. At the moment, I am not sure how you can set a tolerance for the approximation (I know that it can be done). This routine work well even with transfinite float (e.g. POSITIVE_INF will be pushed as INFINITY_TAG).

void push_round_Float (ESI ptr);

Push an approximation of a floating point entry.

push_round_Float first finds a rational approximation of the floating point entry pointed to by ptr using push_Float_to_rat, then converts this fraction back to the floating point number and pushes it on the top of the expressions stack. The summary effect is rounding float to the precision about 1e-5.

void push_cnvrt_integer_if_whole_nmb (ESI ptr);

Pushes a floating point entry eventually converted to an integer.

push_cnvrt_integer_if_whole_nmb checks the entry on the expressions stack pointed to by ptr. If it is not a floating point value (represented by FLOAT_TAG), or if it is a floating point value which is not a whole number, yet another copy of the entry is pushed on the expressions stack. If the entry is a floating point value which is a whole number, this number is pushed on the expressions stack, but this time as an integer (i.e. with POSINT_TAG or NEGINT_TAG).

short did_push_cnvrt_Float_to_integer (ESI ptr);

Pushes a floationg point entry converted to an integer, but only if it is an exact whole number.

did_push_cnvrt_Float_to_integer is a subroutine used in push_cnvrt_integer_if_whole_nmb. It assumes that ptr points to a floating point entry. If it is a whole number (including big numbers too), did_push_cnvrt_Float_to_integer pushes the number converted to a tagged integer to the expressions stack, and returns TRUE, else does nothing and returns FALSE.

void push_END_TAG (void);

Pushes end-of-list marker to the expressions stack.

push_END_TAG pushes END_TAG to the expressions stack. This is the same as push_quantum (END_TAG). See also push_quantum.

push_END_TAG may be useful when you want to push a list on the expressions stack: first push END_TAG, then all elements of the list in reverse order, and finally push LIST_TAG (using push_LIST_TAG).

void push_LIST_TAG (void);

Pushes list tag to the expressions stack.

push_LIST_TAG pushes LIST_TAG to the expressions stack. This is the same as push_quantum (LIST_TAG). See also push_quantum.

push_LIST_TAG may be useful when you want to push a list on the expressions stack: first push END_TAG (using push_END_TAG), then all elements of the list in reverse order, and finally push LIST_TAG.

void push_list_plus (ESI ptr1, ESI ptr2);

Pushes sum of two lists to the expressions stack.

Assuming that ptr1 and ptr2 point to tags of two lists (or matrices, which are "lists of lists"), push_list_plus pushes element-by-element sum of these two lists to the expressions stack. If lists are not equal in size, an error will be thrown. If ptr1 or ptr2 don't point to list tags, the behaviour is unpredictable.

void push_list_times (ESI ptr1, ESI ptr2);

Pushes product of two lists to the expressions stack.

Assuming that ptr1 and ptr2 point to tags of two lists (or matrices, which are "lists of lists"), push_list_times pushes element-by-element product of these two lists to the expressions stack. If lists are not equal in size, an error will be thrown. If ptr1 or ptr2 don't point to list tags, the behaviour is unpredictable.

void push_matrix_product (ESI ptr1, ESI ptr2);

Pushes product of two matrices to the expressions stack.

Assuming that ptr1 and ptr2 point to tags of two matrices (which are, in fact, lists of equally sized lists), push_maxrix_product pushes the matrix product of these two matrices to the expressions stack. As matrix product is not comutative, the matrix pointed to by ptr1 is assumed to be the first factor. If matrices are not compatible for multiplying, an error will be thrown. If ptr1 or ptr2 don't point to matrices, the behaviour is unpredictable.

void push_transpose_aux (ESI ptr, short ConjFlag);

Pushes transposed matrix to the expressions stack.

Assuming that ptr points to the tag of a matrix (which is, in fact, a list of equally sized lists), push_transpose_aux pushes the transpose of the matrix to the expressions stack. If ConjFlag is TRUE, a complex conjugate transpose will be produced, and if ConjFlag is FALSE, an ordinary transpose will be produced. For complex conjugate transposition, the matrix should be in canonic internal form (see push_internal_simplify). If ptr doesn't point to a matrix, the behaviour is unpredictable.

void push_pow (ESI base_ptr, ESI exp_ptr);

Pushes the result of the floating point power function.

Assuming that base_ptr and exp_ptr point to tags of two floating point numbers (called x and y for example), push_pow calculates x ^ y and pushes the result to the expressions stack. If this assumption is not true, a garbage will be pushed instead.

void push_between (void *ptr1, void *ptr2);

Pushes a sequence of bytes to the expressions stack.

push_between pushes a sequence of bytes starting at ptr1+1 and ending at ptr2 to the expressions stack.

NOTE: Break key (ON) is checked during execution of this routine, and an error is thrown if it is pressed!

void push_expr_quantum (ESI ptr, unsigned char Tag);

Pushs an expression followed by a tag to the expressions stack.

push_expr_quantum pushes an entry (expression) on the expressions stack pointed to by ptr (it need to point on the entry tag) to the top of the stack, then pushes a byte Tag. The entry need not to be a simple entity; it may be a complex symbolic expression too. This is achieved by calling next_expression_index and push_between. This function is useful when you need to perform an unary operation on the expression.

void push_expr2_quantum (ESI ptr1, ESI ptr2, unsigned char Tag);

Pushes two expressions followed by a tag to the expressions stack.

push_expr2_quantum pushes two entries (expressions) on the expressions stack pointed to by ptr1 and ptr2 to the top of the stack, then pushes a byte Tag. This function is useful when you need to perform a binary operation on two expressions. See also push_expr_quantum.

void push_reversed_tail (ESI ptr);

Pushes elements of the list up to tail onto the stack in reversed order.

push_reversed_tail first pushes END_TAG to the expressions stack, then pushes all expressions starting from the expression pointed to by ptr one by one (by calling next_expression_index) until END_TAG is reached. So after calling this function, the expressions up to tail will be pushed onto the stack in reversed order. See other "tail" operations like map_tail.

short push_parse_text (const char *str);

Parses an expression given in a string and pushes tokenized expression to the expressions stack.

push_parse_text is an extremely powerful function: it parses the expression given in the string str, and pushes the expressions (in RPN form) to the expressions stack. This function also can parse TI-Basic statements (after parsing, the tokenized form of these statements is pushed on the expressions stack too). push_parse_text returns FALSE if the expression is a multi expression (i.e. if it contains ":" [separator], "->" [store] or TI-Basic statements), else returns TRUE. This routine may cause the expansion of the expresions stack or the heap compression. TIGCCLIB internally uses this function (together with estack_number_to_Float) in the implemenation of atof function. For more examples of usage of this function, see NG_approxESI, NG_rationalESI, NG_execute etc. The "inverse" function of push_parse_text is display_statements.

If you want to perform highly advanced symbolic operations with expressions, you should know that expressions created by push_parse_text are not always organized on a way which allows the most efficient symbolic processing (so-called internal canonic form). For example, TIOS always converts 'x*3' into '3*x' and converts 'x-y' into 'x+y*(-1)', although it will be printed as 'x-y'. However, expressions created by push_parse_text are always as-is, i.e. '3*x' will be just '3*x', not 'x*3'. Some routines (like numeric_factor_index for example) may be fooled if the expression is not "sorted" correctly. Also, some routines (like lead_term_index, lead_factor_index etc.) may also be fooled with expressions like 'x-y' and 'x/y', because operators '-' and '/' are usually never seen in expressions during symbolic processing (the processing is more unique if addition and substraction are treated as the same operation; the same is true for '*' and '/'). So, if you planed to perform some advanced symbolic processing which is based on accessing various part of the expression, always call push_internal_simplify after calling push_parse_text. This function pushes on the expressions stack the same expression but converted in internal canonic form.

NOTE: push_parse_text will throw an error if the string contains expression with wrong syntax, so you need to use TRY etc. to catch eventual errors. And, the string must be built using TI-Basic conventions (for example, you must use 0xAD ("small" minus) instead of '-' for unary minus, etc. See NG_tokenize for a more powerful function which don't throw any errors, and which can determine the exact location and type of the error.

void push_internal_simplify (ESI ptr);

Converts an expression into internal canonic form and pushes the result to the expressions stack.

This extremely important low-level subroutine converts an expression pointed to by ptr to the internal canonic form (see top_estack for more info about the internal canonic form), and pushes the converted expression at the top of the expressions stack. This routine accepts all valid (algebraic, calculus, relational, logical or Boolean) tokenized expressions. During the conversion, various simplifications may be performed too. This routine may cause heap compression, stack expansion, and may throw an error if something goes wrong.

NOTE: It is really unbelievable that such important routine was not present in TIOS jump table before AMS 2.xx. Using very dirty hacks, it is implemented here to work on any AMS version.

void push_next_arb_int (void);

Pushes a next "arbitrary integer" symbol to the expressions stack.

push_next_arb_int pushes a next "arbitrary integer" symbol (i.e. symbol @nxxx) to the top of the expressions stack. More precise, it increments an internal counter for arbitrary integers, pushs the counter on the stack, then pushs ARB_INT_TAG. The counter wraps to zero after 255 is reached.

void push_next_arb_real (void);

Pushes a next "arbitrary real" symbol to the expressions stack.

push_next_arb_int pushes a next "arbitrary real" symbol (i.e. symbol @xxx) to the top of the expressions stack. More precise, it increments an internal counter for arbitrary reals, pushs the counter on the stack, then pushs ARB_REAL_TAG. The counter wraps to zero after 255 is reached.

void push_next_internal_var (unsigned char Tag);

Pushes a next internal variable to the expressions stack.

push_next_internal_var is an auxilary function used in calculus operation. It pushes the sequence 0, Tag+1, count, 0 to the expressions stack, where count is the internal counter of internal variables. Then, the counter is increased by one. TIOS usually passed 0 or 1 for Tag, so it manages a two independent sets of internal variables. You can see that internal variable names consist of two bytes (see VAR_NAME_TAG): one byte is "set number", and another byte is "number of a variable in the set".

void push_overflow_to_infinity (unsigned char inf_tag);

Displays a warning, and pushs a tag to the expressions stack.

push_overflow_to_infinity displays the warning message "Warning: Overflow replaced by INF or -INF", then pushes byte inf_tag to the expressions stack (it is usually INFINITY_TAG or NEGINFINITY_TAG).

unsigned short push_offset_array (ESI elements_ptr, unsigned short **dest);

Pushes an array of offsets to the list items.

This function is not complicated, but it is a bit hard to explain. It first increments the pointer to the top of the expressions stack to the nearest even address, then pushes a word array which contains the offsets to all entries on the expressions stack below elements_ptr until END_TAG is reached. The offset is expressed relative to the elements_ptr. push_offset_array returns the size of pushed array in words (i.e. the number of elements), and stores in the pointer variable pointed to by dest the top address of pushed array. For example, if you execute the following sequence

unsigned int *offsets;
ESI esi;
unsigned int count;
...
esi = top_estack;
count = push_offset_array (esi, &offsets);

then esi-offsets[0], esi-offsets[-1], esi-offsets[-2], ..., esi-offsets[1-count] will point to entries on the expressions stack. esi-offsets[0] will point to the further entry from the top of the expressions stack, esi-offsets[-1] will point to the next one, and finally, esi-offsets[1-count] will point to the entry on the top of the expressions stack (more precise, offsets[1-count] is always zero). This function is useful when you need a fast way to access to all entries on the expressions stack many times.

unsigned short min_quantum (unsigned char Tag1, unsigned char Tag2);

Finds smaller of two tags.

min_quantum returns Tag1 if it is smaller than Tag2, else returns Tag2.

void delete_between (ESI ptr1, ESI ptr2);

Deletes a sequence of bytes from the expressions stack.

delete_between deletes a sequence of bytes between ptr1 and ptr2 (more precise, starting at ptr1+1 and ending at ptr2) from the expressions stack. It does this by moving the memory from ptr2+1 to top_estack downwards (using memmove) and adjusting top_estack. This routine assumes that ptr1 and ptr2 really point to parts of the expressions stack and that ptr2 is above ptr1, else the result is unpredictable.

unsigned short deleted_between (ESI ptr1, ESI ptr2);

Deletes a sequence of bytes from the expressions stack.

deletes_between acts like delete_between, but it also returns a number of deleted bytes. Note that delete_between calls memmove for moving a memory after ptr2, but deleted_between uses an embeded loop sequence for the same task. I don't know why these two routines use different methods: as I can see, the final effect is the same. Maybe I am wrong?

void delete_expression (ESI ptr);

Deletes an expression from the expressions stack.

delete_expression deletes an entry on the expressions stack pointed to by ptr (it need to point on the entry tag) from the stack. The entry need not to be a simple entity; it may be a complex symbolic expression too. This is achieved by calling next_expression_index and delete_between.

unsigned short deleted_expression (ESI ptr);

Deletes an expression from the expressions stack.

deleted_expression acts like delete_expression, but it also returns a number of deleted bytes. It calls deleted_between instead of delete_between.

void move_between_to_top (ESI ptr1, ESI ptr2);

Moves a sequence of bytes to the top of the expressions stack.

move_between_to_top moves a sequence of bytes between ptr1 and ptr2 (more precise, starting at ptr1+1 and ending at ptr2) to the top of the expressions stack. It acts like a combination of push_between and delete_between (in fact, it is). This routine assumes that ptr1 and ptr2 really point to parts of the expressions stack and that ptr2 is above ptr1, else the result is unpredictable.

unsigned short moved_between_to_top (ESI ptr1, ESI ptr2);

Moves a sequence of bytes to the top of the expressions stack.

moved_between_to_top acts like move_between_to_top, but it also returns a number of moved bytes. It calls deleted_between instead of delete_between.

ESI next_expression_index (ESI ptr);

Finds the next entry on the expressions stack.

Assuming that ptr points to an expression entry on the expressions stack, next_expression_index returns the pointer which points to an expression which is located just below the expression pointed to by ptr. So, by successive calls to next_expression_index starting from top_estack, you can locate all expressions on the stack. This command will throw an error if ptr points to the END_TAG, so be careful.

NOTE: next_expression_index calls index_after_match_endtag for TI-Basic functions and program tags, so that inline functions are counted as entire expressions rather than of their components.

long signum_Float (ESI ptr);

Finds the signum of a floating point entry.

signum_Float finds the signum of the floating point entry pointed to by ptr (i.e. returns 1 if the entry is positive, -1 if it is negative, 0 if it is zero). If the entry is not a floating point number, the result is a garbage.

float norm1_complex_Float (ESI ptr);

Finds the 1-norm of a complex number entry.

norm1_complex_Float finds the 1-norm (i.e. the sum of absolute values of real and imaginary part) of the complex number entry pointed to by ptr and returns the result. If the entry is not a complex or real floating point number, the result is a garbage (in the case of real number, norm1_complex_Float reduces to a simple absolute value).

float gcd_exact_whole_Floats (ESI ptr1, ESI ptr2);

Finds the greatest common divisor of two floating point entries.

gcd_exact_whole_Floats finds the greatest common divisor of two floating point entries pointed to by ptr1 and ptr2 and returns the result (the result is a garbage if ptr1 or ptr2 don't point to floating point entries).

NOTE: Although the name of the function suggests that both entries need to be whole numbers, this is not true. This function, in fact, returns "generalized" GCD of two numbers x and y which is defined as the greatest number z which has a property that both x/z and y/z are whole numbers.

short estack_to_short (ESI ptr, short *value_ptr);

Converts entry on the expressions stack to signed short integer.

estack_to_short converts an entry on the expressions stack pointed to by ptr (it need to point on the entry tag) to the signed short integer and stores the result in the location pointed to by value_ptr. Note that the entry need not to be represented by POSINT_TAG or NEGINT_TAG: it also may be represented by FLOAT_TAG for example, but the value itself need to be a whole number. This function does not remove the entry from the stack.

estack_to_short returns 1 if the conversion was sucessful, 0 in the case of overflow (in this case the stored result will be -32768 or 32767 depending of the direction of the overflow), and -1 if the entry can not be represented as a whole number (in this case the result is undefined).

short estack_to_ushort (ESI ptr, unsigned short *value_ptr);

Converts entry on the expressions stack to unsigned short integer.

estack_to_ushort converts an entry on the expressions stack pointed to by ptr (it need to point on the entry tag) to the unsigned short integer and stores the result in the location pointed to by value_ptr. Note that the entry need not to be represented by POSINT_TAG or NEGINT_TAG: it also may be represented by FLOAT_TAG for example, but the value itself need to be a whole number. This function does not remove the entry from the stack.

estack_to_short returns 1 if the conversion was sucessful, 0 in the case of overflow (in this case the stored result will be 0 or 65535 depending of the direction of the overflow), and -1 if the entry can not be represented as a whole number (in this case the result is undefined).

float estack_number_to_Float (ESI ptr);

Converts entry on the expressions stack to floating point number.

estack_number_to_Float converts an entry on the expressions stack pointed to by ptr (it need to point on the entry tag) to a floating point value and returns the result. Note that the entry need not to be represented by FLOAT_TAG: it also may be represented by an integer, or by a fraction. This function does not remove the entry from the stack.

NOTE: estack_number_to_Float will throw an error if the entry on the stack is not a floating point number, a fraction or an integer, so you will need to use ER_catch to catch an eventual errors.

long GetValue (ESI ptr, long low, long high);

Converts entry on the expressions stack to short integer and checks whether it is in a given range.

GetValue converts an entry on the expressions stack pointed to by ptr (it need to point on the entry tag) to a short integer value using estack_to_short or estack_to_ushort, depending of the sign of low. Then, a "Domain Error" is thrown if the value is smaller than low or greater than high, else the value will be returned as the result of the function. It also throw "Data type" error if the entry can not be represented as an integer.

unsigned short remaining_element_count (ESI start_ptr);

Returns number of elements remaining.

remaining_element_count counts how many expressions are stored on the expressions stack below the expression pointed to by ptr (including this one). END_TAG is treated as the terminator, so eventual expressions below END_TAG are not counted. So, if ptr points to an element of the list, remaining_element_count returns the number of elements in the list starting from this element up to the end of the list.

remaining_element_count works using repeated calling next_expression_index and increasing a counter until END_TAG is reached.

void map_tail (void (*f) (ESI element_ptr), ESI start_ptr);

Applies a function to all elements in the list.

map_tail first pushes END_TAG on the expressions stack, then calls callback function f for every expression on the expression stack (in reversed order), starting from the expression pointed to by start_ptr until END_TAG is reached. Each time f is called, a pointer to the actual expression is passed to it. This function is very useful if you want to apply some operation on all elements of the list (then start_ptr need to point to the first element of the list). If the callback function does not push anything on the stack, the END_TAG pushed by map_tail should probably be deleted.

NOTE: map_tail calls next_expression_index to step from one expression to another.

short map_tail_Int (short (*f) (ESI element_ptr, short n), ESI start_ptr, short n);

Applies an extended function to all elements in the list.

map_tail_Int is very similar to map_tail, except callback function f has one additional parameter n. Each time f is called, the parameter n passed to map_tail_Int is passed to f. Also, callback function is not void but returns a Boolean value (TRUE or FALSE). The result of map_tail_Int is logical OR of all values returned by f.

short all_tail (short (*f) (ESI element_ptr), ESI start_ptr);

Checks whether all elements in the list have some property.

all_tail is similar to map_tail, but callback function f is not void. It needs to return a Boolean value (TRUE or FALSE). If f returns FALSE, any further processing of the list tail will be stopped, even if END_TAG is not reached yet. The result of all_tail is the last value returned from f. In other words, it returns TRUE if and only if the callback function f returns TRUE for each expression in the tail of expressions indexed by element_ptr.

all_tail is very useful to check whether all elements of a list possess some property. Suppose that you defined the following function which checks whether an entry on the expressions stack is a positive integer:
short is_positive_integer (ESI ptr)
{
  return *ptr == POSINT_TAG;
}
and suppose that start_ptr points to the first element of the list (one byte below LIST_TAG). Then, you can use the following call to check whether all elements of the lists are positive integers:
are_all_positive_integers = all_tail (is_positive_integer, start_ptr);

short any_tail (short (*f) (ESI element_ptr), ESI start_ptr);

Checks whether any element in the list has some property.

any_tail is similar like all_tail, except further processing of the list will be stopped if f returns TRUE instead of FALSE. In other words, it returns TRUE if and only if the callback function f returns TRUE for at least one expression in the tail of expressions indexed by element_ptr. any_tail is very useful to check whether any element of a list possesses some property. Assuming the same assumptions as in the example given with all_tail, the following call will check whether any element of the list is a positive integer:
is_any_positive_integer = any_tail (is_positive_integer, start_ptr);

void map_unary_over_comparison (void (*f) (ESI term_ptr), ESI cmptag_ptr);

Calls callback function for both comparison terms and pushes the comparison tag.

map_unary_over_comparison assumes that cmptag_ptr points to a comparison tag. It calls callback function f twice, passing to it pointers to both comparison terms, i.e. two expressions below the comparison tag (callback function should push something to the expressions stack). Callback function is applied first to the deeper argument on the stack, then to the shallower argument. Finally, map_unary_over_comparison will push the tag pointed to by cmptag_ptr (one byte) to the expressions stack. This function is useful to perform some transformations on both sides of a comparison (e.g. to transform 'n<5' into 'n!<120'). Beware that squaring of both sides of an inequality can cause losing of solutions, and squaring both sides of an equation may introduce spurious solutions!

short is_Float_exact_whole_number (ESI ptr);

Checks whether a floating point entry is an exact whole number.

is_Float_exact_whole_number which returns TRUE if the floating point entry pointed to by ptr is an exact whole number whose magnitude is less than the smallest whole number that is not represented exactly (1e15), else returns FALSE.

short is_free_of_tag (ESI ptr, unsigned char Tag);

Checks whether an expression is free of a particular tag.

is_free_of_tag is a recursive function which returns TRUE if the expression structure pointed to by ptr is free of tag Tag, else returns FALSE.

short is_advanced_tag (unsigned char Tag);

Checks whether a tag is an advanced tag.

is_advanced_tag returns TRUE if a byte Tag is an advanced tag, else returns FALSE. Advanced tags are all tags which do not represent a variable, a number (integer, fraction or float) or an expression which consists only of simple operations "+", "-", "*", "/" and "^" (including element-by-element versions "+.", "-.", "*.", "/." and "^.".).

short is_complex_number (ESI ptr);

Checks whether an expression is a number.

is_complex_number returns TRUE if the expression (in RPN form, of course) pointed to by ptr is a "number" (integer, rational, floating point, or complex, but not irrational), else returns FALSE. Note that 'sqrt(2)' is not a "number" in this convention. A complex number is a "number" if both real and imaginary parts are "numbers" in a sense of the convention given above. See also likely_approx_to_number.

NOTE: The information about this routine in releases of TIGCCLIB before 2.3 was wrong.

short is_complex0 (ESI ptr);

Checks whether an expression is reducable to zero.

is_complex0 returns TRUE if the expression pointed to by ptr is a zero (signed, unsigned, or even complex), else returns FALSE.

NOTE: The information about this routine in releases of TIGCCLIB before 2.3 was wrong.

short is_matrix (ESI ptr);

Checks whether an expression is a matrix.

is_matrix returns TRUE if the expression pointed to by ptr is a matrix (i.e. a list which consists of equally sized lists), else returns FALSE.

short is_square_matrix (ESI ptr);

Checks whether an expression is a square matrix.

is_square_matrix returns TRUE if the expression pointed to by ptr is a square matrix, else returns FALSE.

short is_valid_smap_aggregate (ESI ptr);

Checks whether an expression is a valid aggregate type.

is_valid_smap_aggregate returns TRUE if the expression pointed to by ptr is a valid aggregate type (i.e. list or valid matrix), else returns FALSE. This is not a simple check whether a tag pointed to by ptr is LIST_TAG. For example, list which consists of lists which are not equally sized (like {{1,2,3},{4,5}}) are not valid. Also, matrices whose elements are list or matrices are also not valid aggregate types.

short is_monomial (ESI ptr);

Checks whether an expression is a monomial.

is_monomial returns TRUE if the expression pointed to by ptr is a monomial expression, else returns FALSE. For example, the expression 'x*y^3' is a monomial, and x+y*z' or 'ln(x)' are not.

short is_monomial_in_kernel (ESI ptr);

Checks whether an expression is a monomial in kernel.

is_monomial_in_kernel returns TRUE if the expression pointed to by ptr is a monomial in kernel, i.e. if it is a monomial function of kernels, where "kernel" means any irrational subexpression, else returns FALSE. For example, 'sin(x)*ln(y)' is not monomial (in respect to 'x' and 'y'), but it is monomial in kernel (in respect to 'sin(x)' and 'ln(y)').

short is_independent_of (ESI expr_ptr, ESI var_ptr);

Checks whether an expression is independent of a variable (or expression).

is_independent_of returns TRUE if the expression pointed to by expr_ptr is independent of the variable pointed to by var_ptr, else returns FALSE. Although var_ptr may point to something which is not a variable, the indepencence of the "expression" is not well defined, so avoid such situations until more information about what such "indepedence" means (TI says that this means "syntactical indepedence", but this is not wee defined too).

NOTE: This routine (and all other "independence" routines too) is not reliable if expressions are not in internal canonic form (see push_internal_simplify).

short is_narrowly_independent_of (ESI expr_ptr, ESI var_ptr);

Checks whether an expression is narrowly independent of a variable (???).

is_narrowly_independent_of returns TRUE if the expression pointed to by expr_ptr is narrowly independent of the variable pointed to by var_ptr, else returns FALSE. I am not sure what "narrowly independent" really means, and what is the difference between this function and is_independent_of.

short is_independent_of_tail (ESI expr_ptr, ESI start_ptr);

Checks whether an expression is independent of a sequence of variables (or expressions).

is_independent_of_tail returns TRUE if the expression pointed to by expr_ptr is independent of all entries on the expressions stack stored below start_ptr up to END_TAG tag, else returns FALSE. See also is_independent_of, is_independent_of_elements and other "tail" operations like map_tail, etc.

short is_independent_of_elements (ESI expr_ptr, ESI varlist_ptr);

Checks whether an expression is independent of the elements of a list.

is_independent_of_tail is very similar to is_independent_of_tail. Assuming that varlist_ptr points to the list of variables or expressions (more precise, to the LIST_TAG of such list), is_independent_of_elements returns TRUE if the expression pointed to by expr_ptr is independent of all variables from the list pointed to by varlist_ptr, else returns FALSE. More precise,
is_independent_of_elements (expr_ptr, varlist_ptr)
is the same as
is_independent_of_tail (expr_ptr, varlist_ptr - 1)

short is_tail_independent_of (ESI start_ptr, ESI var_ptr);

Checks whether a sequence of expressions is independent of a variable (or expression).

is_tail_independent_of returns TRUE if all expressions on the expressions stack which are stored below start_ptr up to END_TAG are independent of the variable pointed to by var_ptr, else returns FALSE. See also other indepedence-checking functions like is_independent_of and other "tail" operations like map_tail, etc.

short is_independent_of_de_seq_vars (ESI ptr);

Checks whether an expression is independent of diferential equation and sequence variables.

is_independent_of_de_seq_vars returns TRUE if the expression pointed to by expr_ptr is independent of system variables which are used for differential equation and sequence graphing (i.e. variables u1-u99 and y1'-y99'), else returns FALSE.

short is_symmetric (ESI expr_ptr, ESI var_ptr);

Checks for a symmetry.

is_symmetric returns TRUE if the expression pointed to by expr_ptr is such that it remains the same when the variable pointed to by var_ptr changes it sign, else returns FALSE.

short is_antisymmetric (ESI expr_ptr, ESI var_ptr);

Checks for a antisymmetry.

is_antisymmetric returns TRUE if the expression pointed to by expr_ptr is such that it changes the sign but keeps the same magnitude when the variable pointed to by var_ptr changes it sign, else returns FALSE.

short can_be_approxed (ESI ptr, short Complex);

Checks whether an expression can be approximated to a number.

can_be_approxed returns TRUE if the expression pointed to by ptr can be approximated to a number (including transfinite ones) or a list of numbers (such expression are for example 'ln(2+sin(1))/5', '1/0' or 'x^2+1-x*x'), else returns FALSE. Complex is a Boolean parameter: if it is TRUE, complex results will be allowed, but if it is FALSE, complex results will be treated as "can not be approxed".

NOTE: can_be_approxed performs much detailed investigation than functions likely_approx_to_number and likely_approx_to_complex_number.

short likely_approx_to_number (ESI ptr);

Checks is it likely that an expression can be approxed to a real number.

If likely_approx_to_number returned TRUE, it is sure that the expression pointed to by ptr can be approxed to a real number, but returning FALSE does not mean that the approximation is not possible: it only means that the approximation to a number is not obvious. For example, it is obvious that expression 'ln(2+sin(1))/5' can be approxed to a number, but this is not so obvious for expression 'x^2+1-x*x', because it contains a symbolic variable name. See can_be_approxed for more detailed investigation of possibility of approximation.

short likely_approx_to_complex_number (ESI ptr);

Checks is is likely that an expression can be approxed to a complex number.

likely_approx_to_complex_number is very similar like likely_approx_to_number, except it checks possibility of approximation to numbers which need not to be real numbers.

short are_expressions_identical (ESI ptr1, ESI ptr2);

Checks whether two expressions are identical.

are_expressions_identical returns TRUE if expressions pointed to by ptr1 and ptr2 are syntactically identical, else returns FALSE. At the moment, I am not exactly sure what is the criteria for equivalence. I only know that a+b and b+a are not identical for example. And, floats are never identical to rational numbers. So far, I only know that this function surely returns TRUE when two expressions are absolutely identical. But, if this is the only case of equivalence, this routine should be very simple. But it is not. It is very complicated and recursive, so I am really not sure which pairs of expressions may be treated as "identical". Any additional info is welcomed.

long compare_Floats (ESI ptr1, ESI ptr2);

Compares two floating point entries on the expressions stack.

compare_Floats compares two floating point entries on the expressions stack pointed to by ptr1 and ptr2, and returns a value which is So, this function is similar like fcmp, except the arguments are different (fcmp uses floating point arguments, and compare_Floats uses pointers to floating point entries on the expressions stack).

short compare_complex_magnitudes (ESI ptr1, ESI ptr2);

Compares magnitudes of two complex number entries on the expressions stack.

compare_complex_magnitudes compares two complex number entries (which may be real too) on the expressions stack pointed to by ptr1 and ptr2, and returns a value which is

short compare_expressions (ESI ptr1, ESI ptr2);

Compares two expressions.

compare_expressions returns 0 if two expressions pointed to by ptr1 and ptr2 are equal in the sense that they have the same structure, variables, function names, and numbers that compare equal. A float and a rational number compare equal if converting the rational number to a float produces an identical number. If the expressions are not, it returns a non-zero value which may be positive or negative (more precise, 1 or -1). Positive result means that the expression pointed to by ptr1 is "more main" that the expression pointed to by ptr2, and negative result means "less main". Principally, variables are more main than symbolic constants such as pi, which are more main than numbers. In expressions such as 'expand(...,var)' or 'Integral(...,var)', a variable var is "most main". Otherwise, the 26 Roman one-letter variables order r>>s>>...>>z>>a>>b>>...>>q ('>>' means "more main"), which order more main than all other variables, which order alphabetically. Functions and operators are typically ordered by recursively comparing their first arguments, with ties broken by comparing their second arguments, etc. then finally comparing the operators or functions, if necessary. For example: NOTE: Both expressions should be in internal canonic form (see push_internal_simplify), else this function may not work as expected.

short should_and_did_push_approx_arg2 (ESI arg1_ptr, ESI arg2_ptr);

Checks should and did push approxed second argument.

This function is combination of "push" and "check" operations. If the entry on the expressions stack pointed to by arg1_ptr is not a floating point number (i.e. if arg1_ptr does not point to FLOAT_TAG), this function does nothing and returns FALSE. Else, it checks is it likely that the entry on the expressions stack pointed to by arg2_ptr can be approxed to a real number (using likely_approx_to_number). If it is, should_and_did_push_approx_arg2 pushes approximated value to the expressions stack and returns TRUE, else does nothing more and returns FALSE.

ESI lead_term_index (ESI ptr);

Gets the index of the lead term of an expression.

If ptr points to the ADD_TAG, which is a case when it points to an expression of form term1 + term2 + ... (i.e. if the expression is a sum of simpler terms), lead_term_index returns the pointer to term1 (i.e. to the lead term). If ptr does not point to the ADD_TAG (i.e. if the expression is not a sum of simpler terms), lead_term_index returns ptr (i.e. the pointer to the expression itself).

NOTE: Expressions in internal canonic form have the most main term shallowest, with less main terms deeper (see compare_expressions about more info about "main" ordering). Also, the lead term of an internally-simplified sum is never a sum. For example, the lead term of '(2+x)+y' converted to canonic form is 'x'. By default, similar powers of the main variable are collected in internal canonic forms. For example, the lead term of 'x^2*y+x^2+5' converted to canonic form is 'x^2*(y+1)'. See push_internal_simplify for more info about how to convert an expression into the internal canonic form.

ESI reductum_index (ESI ptr);

Gets the index of remaining terms of an expression.

If ptr points to the ADD_TAG, which is a case when it points to an expression of form term1 + term2 + ... (i.e. if the expression is a sum of simpler terms), reductum_index returns the pointer to the subexpression term2 + ... (which is a reductum subexpression of the given expression). If ptr does not point to the ADD_TAG (i.e. if the expression is not a sum of simpler terms), reductum_index returns a pointer to a simple zero expression, i.e. expression which consists only of number 0 (floating point or integer, depending of whether the approximation mode is active or not).

NOTE: Expressions in internal canonic form have the most main term shallowest (see lead_term_index. So, the reductum of '2+x+y' converted to canonic form is 'y+2'. By default, similar powers of the main variable are collected in internal canonic forms. For example, the reductum of 'x^2*y+x^2+5' converted to canonic form is '5'. See push_internal_simplify for more info about how to convert an expression into the internal canonic form.

ESI lead_factor_index (ESI ptr);

Gets the index of the lead factor of an expression.

If ptr points to the MUL_TAG, which is a case when it points to an expression of form factor1 * factor2 * ... (i.e. if the expression is a product of simpler factors), lead_factor_index returns the pointer to factor1 (i.e. to the lead factor). If ptr does not point to the MUL_TAG (i.e. if the expression is not a product of simpler factors), lead_factor_index returns ptr (i.e. the pointer to the expression itself).

NOTE: Expressions in internal canonic form have the most main factor shallowest, with less main factors deeper (see compare_expressions for more info about "main" ordering). Also, the lead factor of an internally-simplified product is never a product. For example, lead factor of '(3*x^2)*y' converted into canonic form is 'x^2'. Internally-simplified numeric denominator factors are combined with numeric numerator factors into a fractional numeric factor. Non-numeric denominator factors are internally simplified to be merged with numerator factors as negative powers. For example, the lead factor of '2/x' converted into canonic form is 'x^-1'. A factor having a sum as its base orders shallower than a factor having the sum’s main variable as its base. For example, the lead factor of '(x+1)^-2*x^3' converted into canonic form is '(x+1)^-2'. See push_internal_simplify for more info about how to convert an expression into the internal canonic form.

ESI remaining_factors_index (ESI ptr);

Gets the index of remaining factors of an expression.

If ptr points to the MUL_TAG, which is a case when it points to an expression of form factor1 * factor2 * ... (i.e. if the expression is a sum of simpler terms), remaining_factors_index returns the pointer to the subexpression term2 * ... (i.e. to the remaining factors of the expression). If ptr does not point to the MUL_TAG (i.e. if the expression is not a product of simpler factors), remaining_factors_index returns a pointer to a simple expression which consists only of number 1.

NOTE: Expressions in internal canonic form have the most main factor shallowest, with less main factors below that (see compare_expressions for more info about "main" ordering). Also, the lead factor of an internally-simplified product is never a product. For example, remaining factors of '(3*x^2)*y' converted into canonic form are '3*y'. By default, similar powers of the main variable are collected, so remaining factor of 'x^2*y+x^2' after conversion into canonic form is 'y+1'. Internally-simplified numeric denominator factors are combined with numeric numerator factors into a fractional numeric factor. Non-numeric denominator factors are internally simplified to be merged with numerator factors as negative powers. See push_internal_simplify for more info about how to convert an expression into the internal canonic form.

ESI re_index (ESI ptr);

Gets the index of the real part of an expression.

If ptr points to the COMPLEX_TAG (i.e. if the expression is complex), re_index returns the pointer to the real part of the expression. If ptr does not point to the COMPLEX_TAG (i.e. if the expression is real), re_index returns ptr (i.e. the pointer to the expression itself).

NOTE: The expression should be in internal canonic form (see push_internal_simplify), else this function is not reliable.

ESI im_index (ESI ptr);

Gets the index of the imaginary part of an expression.

If ptr points to the COMPLEX_TAG (i.e. if the expression is complex), im_index returns the pointer to the imaginary part of the expression. If ptr does not point to the COMPLEX_TAG (i.e. if the expression is real), im_index returns a pointer to a simple zero expression, i.e. expression which consists only of number 0 (floating point or integer, depending of whether the approximation mode is active or not).

NOTE: The expression should be in internal canonic form (see push_internal_simplify), else this function is not reliable.

ESI factor_base_index (ESI ptr);

Gets the index of the base of an expression.

If ptr points to the POW_TAG, which is a case when it points to an expression of form base ^ exponent factor_base_index returns the pointer to base. If ptr does not point to the POW_TAG, factor_base_index returns ptr (i.e. the pointer to the expression itself).

ESI factor_exponent_index (ESI ptr);

Gets the index of the exponent of an expression.

If ptr points to the POW_TAG, which is a case when it points to an expression of form base ^ exponent factor_exponent_index returns the pointer to exponent. If ptr does not point to the POW_TAG, factor_exponent_index returns a pointer to a simple expression which consists only of number 1 (floating point or integer, depending of whether the approximation mode is active or not).

ESI lead_base_index (ESI ptr);

Gets the index of the base of the lead factor of an expression.

lead_base_index first calls lead_factor_index, then apply factor_base_index on the result. So, it returns the pointer to the base of the lead factor (i.e. the lead base) of the expression pointed to by ptr.

ESI lead_exponent_index (ESI ptr);

Gets the index of the exponent of the lead factor of an expression.

lead_exponent_index first calls lead_factor_index, then apply factor_exponent_index on the result. So, it returns the pointer to the exponent of the lead factor (i.e. the lead exponent) of the expression pointed to by ptr.

ESI index_of_lead_base_of_lead_term (ESI ptr);

Gets the index of the base of the lead term of an expression.

index_of_lead_base_of_lead_term first calls lead_term_index, then apply lead_base_index on the result. So, it returns the pointer to the base of the lead factor of the first term of the expression pointed to by ptr.

ESI numeric_factor_index (ESI ptr);

Searches factors in the expression for a numeric factor.

If ptr points to the MUL_TAG, which is a case when it points to an expression of form factor1 * factor2 * ... (i.e. if the expression is a product of simpler factors), numeric_factor_index returns the pointer to the eventual numeric factor in the expression. If the expression is a number, numeric_factor_index returns ptr (i.e. the pointer to the expression itself). If ptr does not point to the MUL_TAG (i.e. if the expression is not a product of simpler factors), or if there is no any numeric factors in the expression, lead_factor_index returns a pointer to a simple expression which consists only of number 1 (floating point or integer, depending of whether the approximation mode is active or not).

NOTE: This function is not implemented to be very universal. TIOS always "reorganizes" expressions on such way that numeric factors are at the beginning of the expression (i.e. x*3 will be reorganized into 3*x), and this function assumes that the expression is organized on such way. This is so-called "internal canonic" form, and such expressions always have at most one factor with a numeric tag, in which case it is the deepest factor. So, '3*x^2*y' contains a numeric factor (3), but '2*x+3' does not. Also, numeric factors in numerators and denominators are always simplified into a single numeric factor in internal canonic forms (so, the numeric factor of '6*x/(4*y)' after conversion to canonic form is 3/2. Fortunately, all expressions in argument are always in internal canonic form. However, this is not true after push_parse_text function, nor after an evaluation using NG_rationalESI or NG_approxESI. In other words, results of these commands are not always "correctly" organized. To force converting an expression to the internal canonic form, always call push_internal_simplify after usage any of functions mentioned above.

ESI index_numeric_term (ESI ptr);

Searches terms in the expression for a numeric term.

If ptr points to the ADD_TAG, which is a case when it points to an expression of form term1 + term2 + ... (i.e. if the expression is a sum of simpler terms), index_numeric_term returns the pointer to the eventual numeric term in the expression. If the expression is a number, index_numeric_term returns ptr (i.e. the pointer to the expression itself). If ptr does not point to the ADD_TAG (i.e. if the expression is not a sum of simpler terms), or if there is no any numeric terms in the expression, index_numeric_factor returns a pointer to a simple expression which consists only of number 0 (floating point or integer, depending of whether the approximation mode is active or not).

NOTE: This function is not implemented to be very universal. TIOS always "reorganizes" expressions on such way that numeric terms are at the beginning of the expression (for example, x+3 will be reorganized into 3+x, although it will be displayed just reversed, i.e. as x+3), and this function assumes that the expression is organized on such way. In other words, it must be in internal canonic form (such expressions always have at most one term with a numeric tag, in which case it is the deepest term). Fortunately, all expressions in argument are always in internal canonic form. However, this is not true after push_parse_text function, nor after an evaluation using NG_rationalESI or NG_approxESI. In other words, results of these commands are not always "correctly" organized. To force converting an expression to the internal canonic form, always call push_internal_simplify after usage any of functions mentioned above.

ESI index_main_var (ESI ptr);

Searches an expression for a first encountered variable.

index_main_var returns the index of the first encountered variable in the expression pointed to by ptr. More precise, it repeatedly decreases value of ptr by one until the tag of a variable, a number or a symbolic constant (like pi) is reached. As expressions are usually organized in "internal canonic" form (see notes given with description of numeric_factor_index) in which all constants are always "below" variables on the stack, a variable will always be reached before any constant, except if there is no any variables in the expression (in this case, a pointer to a constant is returned). Obviously, this function is not reliable if the expression is not in the internal canonic form (see push_internal_simplify).

ESI main_gen_var_index (ESI ptr);

Searches an expression for a generalized variable.

main_gen_var_index is a variant of index_main_var, but it searches for a "generalized variable", which may also be a subexpression. For example, if the expression is 'sin(x)+y', index_main_var will return a pointer to 'x', but main_gen_var_index will return a pointer to 'sin(x)'. Generalized variable can be an ordinary variable, the base of a noningeger power, or a kernel (like 'sin(x)'), meaning any other irrational subexpression.

More precise, main_gen_var_index skips all ADD_TAG, MUL_TAG and POW_TAG tags, then stops at the first tag which is not equal to some of them. In addition to this, if the tag is POW_TAG, function next_expression_index will be called, to get access to the base of the power (note that "powers" can not be "reorganized" on such way that constants are always in front of variables, because '2^x' and 'x^2' are not the same expression). This implies that "main generalized variable" of a sum, a product or an integer power is equal to the main generalized variable of a lead term, a lead factor or a base respectively. Otherwise, main generalized variable is the expression itself. For example, main "generalized variables" of expressions 'sin(x)^2*y+ln(z)', '3^(1/5)+2' and '(x+y)^(1/2)+x' are 'sin(x)', '3' and 'x+y' respectively.

ESI last_element_index (ESI ptr);

Searches for a last expression in the list.

last_element_index calls next_expression_index in a loop starting from ptr until END_TAG is reached, then returns the pointer to the last encountered expression before END_TAG. So, assuming that ptr points to a member of the list (including argument lists to), last_element_index will return the pointer to the last element of the list.

ESI index_below_display_expression_aux (ESI ptr);

Main routine for detokenizing.

index_below_display_expression_aux is main (recursive) routine for detokenizing. As it is just an auxilary routine used in display_statements and Parse1DExpr, it shouldn't need to be used directly.

ESI HToESI (HANDLE Handle);

Converts a handle to expressions stack index

HToESI is a simple but very useful routine. It allows usage of TIOS variables as input data in routines for manipulating with expressions stack. Assuming that Handle is a handle of a TIOS variable which contains an expression, HToESI will return a pointer to the tag of the expression contained in the variable. Such pointer may be used in any routine which needs an argument of type ESI like NG_approxESI, etc. (except in functions which manipulate with the actual memory space on the expressions stack, like delete_between). In fact, HToESI simply dereferences Handle and adds the size to the address. It also may be used to determine a type of a TIOS variable, because after execution the result points to the data type tag of the variable data.

NOTE: If the handle is not locked, HToESI must be done again after a heap compression since the block of memory associated with the handle may have moved.

HANDLE HS_popEStack (void);

Pops an entry from the expressions stack to the memory.

HS_popEStack allocates a zone in the memory, pops the last entry from the expressions stack into allocated zone, and returns the handle which points to it (throws an error if there is not enough memory). See NG_execute for an example of usage. Returned handle is allocated with HeapAllocHigh, and it is therefore intended to be temporary.

void check_estack_size (unsigned short Size);

Checks if there is enough room on the expressions stack.

check_estack_size checks if there is enough room to push Size bytes to the expressions stack. If there is not enough space, it tries to enlarge the stack (using HeapRealloc) to make an additional space. It throws an error if the requirement cannot be satisfied. Note that all "push_..." functions calls this routine, so all of them may throw an error if there is not enough memory.

void reset_estack_size (unsigned short NewSize);

Reallocates the expressions stack.

reset_estack_size changes the size of the expressions stack to NewSize. It throws an error if the requirement cannot be satisfied. If NewSize is smaller than the current amount of used space, then the expressions stack is set to the current amount of used space instead of NewSize. Default size of the expressions stack is 16384 bytes.

void NG_approxESI (ESI ptr);

Evaluates an expression in "APPROX" mode.

NG_approxESI executes the entry on the expressions stack pointed to by ptr (it need to point on the entry tag) in "APPROX" mode, then pushes the result (i.e. a new expression) on the top of the expressions stack. The pushed result is NOT in internal canonic form (if necessary, push_internal_simplify to force conversion to the internal canonic form). The following example ilustrates this very powerful command:
push_parse_text ("sin(1.3)+log(2)/7");
NG_approxESI (top_estack);
printf_xy (0, 50, "%f", estack_number_to_Float (top_estack));
See push_parse_text and estack_number_to_Float to understand how this example works.

NOTE: The expressions must be an expression, i.e. it must not contain TI-Basic statements. For executing TI-Basic statements, use NG_execute. Also, this command may cause expansion of the expressions stack or heap compression, and may throw various errors is something is wrong.

void NG_rationalESI (ESI ptr);

Evaluates an expression in "EXACT" mode.

NG_rationalESI executes the entry on the expressions stack pointed to by ptr (it need to point on the entry tag) in "EXACT" mode, then pushes the result (i.e. a new expression) on the top of the expressions stack. See the example of usage given with display_statements. The same notes given with NG_approxESI are true with this command too.

NOTE: The expressions must be an expression, i.e. it must not contain TI-Basic statements. For executing TI-Basic statements, use NG_execute. Also, this command may cause expansion of the expressions stack or heap compression, and may throw various errors is something is wrong.

void NG_execute (HANDLE Handle, unsigned short approx_flag);

Executes TI-Basic statements.

NG_execute executes a sequence of TI-Basic statements in tokenized form, which are located in a memory block pointed to by handle Handle. To create such block, functions push_parse_text and HS_popEStack may be very useful, like in the following example:
push_parse_text ("ClrGraph : Graph sin(x)");
handle = HS_popEStack ();
NG_execute (handle, 0);
HeapFree (handle);
When approx_flag is non-zero, the sequence will be executed in "approx" mode (like running with [DIAMOND]+[ENTER]). Else, the current mode settings will be used. This routine is called after NG_RPNToText from the home screen.

NG_execute can also evaluate expressions. In this case, the result of evaluation is pushed on the top of the expressions stack.

NOTE: This routine always clears the error context, resets control flags, may cause estack expansion or heap compression. It may throw various errors if something is wrong.

short NG_tokenize (HANDLE hTEXT, unsigned short *ErrCode, unsigned short *ErrOffset);

Tokenizes text associated with a handle and pushes them to the expressions stack.

NG_tokenize is more powerful variant of push_parse_text. It tokenizes the text associated with the handle hTEXT, and pushes the converted text to the expressions stack. Returns TRUE if the operation was successful, else returns FALSE. If there was an error, then the variable pointed to by ErrCode contains the error code, and the variable pointed to by ErrOffset contains the offset in the text where the error occured. If there was not any errors, then the variable pointed to by ErrCode contains multi state (this is the result returned from push_parse_text) and ErrOffset is undefined. This routine may expand the expressions stack, may cause the heap compression, or even may throw an error if something goes really wrong (not enough memory, for example).

void NG_graphESI (ESI ptr, HANDLE Handle);

Evaluates an expressions for graphing purposes.

NG_graphESI is the function used in TIOS during drawing function graphs. It evaluates the entry on the expressions stack pointed to by ptr in "APPROX" mode then pushes the result on the top of the expressions stack, similarly like NG_approxESI does, but NG_graphESI requires that all variables in the expression must be defined, i.e. the expression must evaluate to a number (else "Undefined variable" error will be thrown). Handle is the handle of the function in which the expression is defined. I don't know exactly when and why this function needs this handle (probably to check which variables are parameters of the function, which variables are local etc.). When I tried to pass H_NULL to this function, nothing bad happened. However, in the absence of more info, avoid this function.

HANDLE NG_RPNToText (HANDLE hRPN, unsigned short NewLines, unsigned short FullPrec);

Detokenizes a tokenized structure associated with a handle.

NG_RPNToText detokenizes a tokenized structure (an expression, TI-Basic statement or a group of statements) associated with handle hRPN and returns a handle to the memory block where detokenized string is stored (you don't need to allocate anything by yourself, this function will do it instead). The first word of the data associated with hRPN should be the length of the data which is used to find the first tag of the tokenized data. It throws an error if the detokenization fails. This function is mainly identical as display_statements except NG_RPNToText requires a handle instead of the pointer to the structure which need to be detokenized. See display_statements for more info.

char *get_key_ptr (unsigned char Tag1, unsigned char Tag2);

Converts a tag code to a tag name.

get_key_ptr returns a static pointer to the string which represents the name of the tag Tag1. Tag2 is used only if Tag1 is an extended tag (i.e. EXT_TAG, EXT_INSTR_TAG or EXT_SYSTEM_TAG) which can't be fully represented using only one byte.

HANDLE display_statements (ESI ptr, unsigned short Newlines, unsigned short FullPrec);

Converts tokenized expressions or TI-Basic statements to the printable form.

display_statements converts the expression (or a group of tokenized TI-Basic statements) pointed to by ptr from RPN form to the standard printable ("algebraic") form, and returns a handle to the memory block where converted string is stored (you don't need to allocate anything by yourself, this function will do it instead; note that this routine may cause heap compression). It will return H_NULL if memory full. Newline is a Boolean flag: when it is nonzero, all newline characters will be replaced with ':', otherwise they will remain intact. FullPrec is also a Boolean flag: when it is non-zero, all floating point values will be converted using the maximal precision (14 digits), else current precision settings (from TI-Basic MODE dialog) will be used. Here is an ilustrative example for usage of this command:
push_parse_text ("expand((x+1)(x+2)(x+3))");
NG_rationalESI (top_estack);
handle = display_statements (top_estack, 1, 1);
printf_xy (0, 40, "%s", HeapDeref (handle));
HeapFree (handle);
See push_parse_text, NG_rationalESI, HeapDeref and HeapFree to understand how this example works.

display_statements will always convert expressions into the "cannonic printing (external) form". For example, both x*3 and 3*x will be displayed as 3*x, x*y^(-1) will be displayed as x/y etc.

NOTE: Although display_statements is very similar as Parse1DExpr and the both of them may be usually used for the same purposes, display_statements is used in TIOS for printing TI-Basic statements (from programs) and for the detokenization (in NG_RPNToText, and Parse1DExpr is used for printing expressions.

HANDLE Parse1DExpr (ESI ptr, unsigned short FullPrec, unsigned short width);

Parses a tokenized expression to be printed.

Parse1DExpr does a similar job as display_statements (i.e. converts a RPN expression to the TEXT and returns the handle to the text), but the parameters are somewhat different. Here, width is the maximum width of text result (0 indicates no width restriction). So, when necessary, symbolic expressions are truncated to width-1 characters and terminated with an ellipsis character ('...'). When ptr points to a tagged floating point number, the number is rounded to fit in width characters. When the number cannot be rounded to fit in width characters, an ellipsis character ('...') is returned. See display_statements for more info.

ESI Parse2DExpr (ESI ptr, unsigned short FullPrec);

Parses a tokenized expression to be pretty printed using Print2DExpr.

Parse2DExpr parses the expression pointed to by ptr, so it can be displayed with Print2DExpr. This function splits up expression into blocks with information about their relative position and size. This splitting is performed for efficiency reasons, so the expression may be displayed again without having to calculate the positions again. Parse2DExpr returns the pointer to a created structure (it need to be passed to the Print2DExpr). This pointer is in fact the new value of top_estack, because created structure (known as "boxed RPN") is also pushed on the expressions stack. FullPrec is a Boolean flag: when it is non-zero, all floating point values will be converted using the maximal precision (14 digits), else current precision settings (from TI-Basic MODE dialog) will be used. If there is no enough memory, a special symbol is pushed onto the expression stack to signify this. This routine may cause a heap compression. See Print2DExpr for an example of usage.

Parse2DExpr will always convert expressions into the "cannonic printing (external) form". For example, both x*3 and 3*x will be displayed as 3*x, x*y^(-1) will be displayed as x/y etc.

NOTE: Break key (ON) is checked during execution of this function, and pressing it will throw an error!

void Print2DExpr (ESI ptr, WINDOW *w, short x, short y);

Performs "pretty printing" (or "2D printing") of an expression.

Print2DExpr prints the expression in "pretty" or "2D" style. Before printing, the expression needs first to be "parsed" using Parse2DExpr, and argument ptr should be a result returned from Parse2DExpr (an error may be thrown if ptr points to something else). w is a pointer to the WINDOW structure which describes the window in which the expression will be displayed (see wingraph.h header file for more info about windows). If you didn't create your own windows in the program, you can pass DeskTop as the parameter (as in the example given below). x and y are coordinates (window-relative) where the expression will be printed. x determines the left edge of the expression, and the expression goes (in y direction) both above and below the value of y. See Params2D for exact information about dimensions of displayed expression. If the displayed expression can not fit into the given window, it will be simply clipped at edges of the window.

Here is an example which first calculates the integral of 1/((x-3)(x^2+4)), then "pretty prints" the result on the screen:
push_END_TAG ();
push_quantum (VAR_X_TAG);
push_parse_text ("1/((x-3)(x^2+4))");
push_quantum (INTEGRATE_TAG);
NG_rationalESI (top_estack);                // evaluates the expression
WinClr (DeskTop);
Print2DExpr (Parse2DExpr (top_estack, FALSE), DeskTop, 0, 50);
It is also possible to use
Parse2DExpr (top_estack, FALSE);
Print2DExpr (top_estack, DeskTop, 0, 50);
instead of
Print2DExpr (Parse2DExpr (top_estack, FALSE), DeskTop, 0, 50);
You can use Parms2D to get information about the height and the width of the printed expression without displaying it on the screen. This may be used to determining coordinates where the expression need to be displayed.

ESI Parse2DMultiExpr (HANDLE Handle, unsigned short FullPrec);

Parses a multi-statement expression associated with a handle to be pretty printed using Print2DExpr.

Parse2DMultiExpr parses a multi-statement expression associated with Handle so that it can be displayed with Print2DExpr. Parameter FullPrec has the same meaning as in Parse2DExpr. The expression associated with Handle may contain multiple expressions separated with NEXTEXPR_TAG (in opposite to Parse2DExpr). I must admit that I don't understand this function very well, so avoid it except if you know about it more than I know...

void Parms2D (ESI ptr, short *Width, short *Bottom, short *Top);

Gets information about dimensions of block which will be "pretty printed".

Parms2D gets information about the screen space which will be occupied by displayed expression. It should be called after calling to Parse2DExpr (or Parse2DMultiExpr), and ptr should be a result returned from it. Params2D stores the information in three variables pointed to by Width, Bottom and Top. Width is the width of the displayed block, and Top and Bottom are distances of top and bottom edge of the block measured from the wanted y position. More precise, if the expression is printed at (x, y) using Print2DExpr, the left corner of the occupied space will be at (x, y-*Top), and the right corner of the occupied space will be at (x+*Width, y+*Bottom). So, the 2D expression has an imaginary center line above which is the "Top", and below (counting this line too) is the "Bottom".


Global variables


ESI top_estack;

The global variable top_estack points to the top (i.e. the last byte) of the expressions stack. Strictly speaking, in "nostub" mode it is not a real variable but smart macro, although it works like it is a variable. Expressions stack is the place in the memory where TI keeps expressions during the evaluation. All statements are tokenised before being executed (interpreted). Instructions are reduced to (byte sized) quanta and parsed into Reverse Polish Notation (RPN). This is a common technique in interpreted languagues. Expressions, functions, etc. are all stored in RPN form, to allow for efficient operation of the expressions stack. See below for more details about organization of the expressions stack.

The actual processing of all expressions is done via the expressions stack. The position in the stack is given by top_estack. Pushing a value appends it to the expressions stack and increments top_estack. When a expression is interpreted, expressions are reduced, and executed as far as possible. Whatever remains on the stack is the result, this may then be stored or processed later.

When a file is interpreted the end of the variable is found and it is processed as a separate expression stack. It is then processed recursively, producing a simplified version on the real expressions stack. Expressions are therefore interpreted from the top (high memory) recursively.

As an artefact of expressions processing mechhanism, the arguments of the called program are kept also on the expressions stack. It grows upwards, and the last argument is stored first. After the assembly program is called, the image of the expressions stack is as follows: Each string entry on the expressions stack is stored as follows (from lower to higher addresses): Each integer entry is stored as follows: Each fraction entry is stored as follows: Each floating point entry is stored as follows: If the entry is complex number, real part is stored first (which can be integer, float, fraction, etc.), then imaginary part. COMPLEX_TAG (0x9D) is stored after them, so if the current argument type is complex, decrease the argument pointer by one, then first read imaginary part, then real part separately.

If the entry is composite (i.e. if it is a list or a matrix), the first byte is end_of_list marker (byte END_TAG or 0xE5), then follow each element of the list in reverse order (starting from the last element), and the last byte is LIST_TAG (0xD9). Now, you surely have an idea how you can pick up elements from the list. Note that a matrix is a "list of lists".

Signed zeros (POSITIVE_ZERO and NEGATIVE_ZERO) are represented as fractions +0/1 and -0/1.

Variable names are stored exactly like strings without terminating STR_TAG (i.e. it is a sequence of letters bounded with two zero bytes), so "variable" tag is just a zero byte. There is an exception: one-letter variables have unique one-byte tags (see Tags for more info. Also, note that variable names are always stored with lowercase letters. Variables whose names ends with an underscore are assumed to be complex, and variables whose names starts with an understore are assumed to represent physical units.

Expressions are stored in RPN (Reverse Polish Notation) form (also known as postfix form). So, function calls like func(arg1,arg2,...argn) are stored as sequence

argn ... arg2 arg1 func_tag

and terms like arg1 operator arg2 are stored as arg1 arg2 operator_tag or arg2 arg1 operator_tag, depending of the concrete operator. The situation is analogous for unary operators. Note that a "pointer to an expression" is a pointer to the last byte of the expression! When a function (or operator) has variable number of arguments, END_TAG is used to indicate "no more arguments". See Tags for complete list of various tags. This will be ilustrated with some examples:

Algebraic form: integrate (e^(x^2), x, 1, 2)
RPN form: 2 1 2 x ^ e ^ integrate
Sequence of bytes:    [02 01 1F] [01 01 1F] [08] [02 01 1F] [08] [93] [25] [93] [C4]

Algebraic form: sum (sqrt (1 + x), x, 0, a)
RPN form: a 0 x x 1 sqrt sum
Sequence of bytes:    [0B] [00 1F] [08] [08] [01 01 1F] [8B] [51]

Algebraic form: a + b + a - b + (a + b) * (a - b) -> a
RPN form: a b + a + b - a b + a b - * + a ->
Sequence of bytes:    [0B] [0C] [8B] [0B] [8B] [0C] [8D] [0B] [0C] [8B] [0B] [0C] [8D] [8F] [8B] [0B] [80]

Algebraic form: {{1, 2}, {3, 4}}
RPN form: END_TAG END_TAG 4 3 LIST_TAG END_TAG 2 1 LIST_TAG LIST_TAG
Sequence of bytes:    [E5] [E5] [04 01 1F] [03 01 1F] [D9] [E5] [02 01 1F] [01 01 1F] [D9] [D9]

Algebraic form: my_func (a, b, c)
RPN form: END_TAG c b a my_func USERFUNC_TAG
Sequence of bytes:    [E5] [0D] [0C] [0B] [00 6D 79 5F 66 75 6E 63 00] [DA]

To perform some algebraic transformations on more unique way, expressions should be transformed into an equivalent form called "internal canonic form". In such form, for example, all constants are always in front of variables, e.g. 'x*3' and 'x+3' becomes '3*x' and '3+x' (although the second example will be printed as 'x+3'). Also, expressions like 'x/y' or 'x-y' in internal canonic form do not contain substractions and divisions. As the parameter list (when the program is called from TI-Basic) is always in internal canonic form, such expressions will never be observed as-is in parameter lists etc. because they will be converted before passing them to the program. A lot of functions for algebraic manipulations automatically convert the expression in the internal canonic form, but when this is not true, you can always force the conversion using explicite call to push_internal_simplify function. Note that the reverse conversion (i.e. back from the canonic form into a regular form) is performed anytime when you try to print out the expression. Here is the list of the most common transformations which appears during the transformation into the internal canonic form:

ExpressionStandard canonnic form
-x(-1)*x
x-yx+y*(-1)
x/yx*y^(-1)
e^xexp(x)
x^yexp(ln(x)*y)
[ except when "y" is an integer or a fraction ]
eexp(1)
sqrt(x)x^(1/2)
log(x)ln(x)*(ln(10)^(-1))
sin(x)trig(x,0)
[ assuming "radian" mode; for "trig" function, see SINCOS_TAG ]
cos(x)trig(x,1)
tan(x)trig(x,0)*trig(x,1)^(-1)
sinh(x)exp(x)*(1/2)+exp(x)^(-1)*(-1/2)
cosh(x)exp(x)*(1/2)+exp(x)^(-1)*(1/2)
tanh(x)(exp(x)^2+1)^(-1)*(exp(x)^2+(-1))
x xor y(not x and y) or (x and not y)

Mode dependent calculations are performed by converting expressions to a specific format, i.e. for trigonometric functions all values are converted to radians before passing them to radian trigonometric functions.

A variable may consist of multiple expressions, these are separated by several special quanta: NEXTEXPR_TAG and NEWLINE_TAG. The last expression is marked with ENDSTACK_TAG.

If everything mentioned above is not so clear for you, compile and run the following program:
#include <tigcclib.h>
int _ti89;
void _main(void)
{
  printf_xy (0, 50, "Top=%lx", top_estack);
  ngetchx ();
}
Run this program in VTI and pass to it parameters as you want. top_estack will be shown on the screen. During waiting for a keypress, enter the debugger and look the addresses below shown address, to see how parameters are stored.


Constants and predefined types


type ESI

ESI is "expressions stack index" which is, in fact, the pointer to the tag byte on the TIOS expressions stack. It is defined as
typedef char *ESI;
See top_estack and Tags for more info about the expressions stack.

enum Tags

Tags is enumerated type for describing types of entries on the expressions stack. This enum is very big, as there is a lot of various entries (see top_estack for more info about how entries on the expressions stack are organized). Here is a complete list of tags (all values are in hex), with their meaning (used notation is RPN):

00VAR_NAME_TAGvariable name (with more than one letter)
01_VAR_Q_TAGvariable q (but not used - 1B is used normally)
02VAR_R_TAGvariable r
03VAR_S_TAGvariable s
04VAR_T_TAGvariable t
05VAR_U_TAGvariable u
06VAR_V_TAGvariable v
07VAR_W_TAGvariable w
08VAR_X_TAGvariable x
09VAR_Y_TAGvariable y
0AVAR_Z_TAGvariable z
0BVAR_A_TAGvariable a
0CVAR_B_TAGvariable b
0DVAR_C_TAGvariable c
0EVAR_D_TAGvariable d
0FVAR_E_TAGvariable e
10VAR_F_TAGvariable f
11VAR_G_TAGvariable g
12VAR_H_TAGvariable h
13VAR_I_TAGvariable i
14VAR_J_TAGvariable j
15VAR_K_TAGvariable k
16VAR_L_TAGvariable l
17VAR_M_TAGvariable m
18VAR_N_TAGvariable n
19VAR_O_TAGvariable o
1AVAR_P_TAGvariable p
1BVAR_Q_TAGvariable q
1CEXT_SYSTEM_TAGsystem token (a byte before the tag identifies a system variable, see SysvarTags)
1DARB_REAL_TAGarbitrary real number @xxx (byte before the tag determines xxx)
1EARB_INT_TAGarbitrary integer number @nxxx (byte before the tag determines xxx)
1FPOSINT_TAGpositive integer tag
20NEGINT_TAGnegative integer tag
21POSFRAC_TAGpositive fraction tag
22NEGFRAC_TAGnegative fraction tag
23FLOAT_TAGfloating point tag
23BCD_TAGfloating point tag (alias tag name)
24PI_TAGconstant pi
25EXP_TAGconstant e
26IM_TAGconstant i
27NEGINFINITY_TAG-infinity
28INFINITY_TAGinfinity
29PN_INFINITY_TAG+/- infinity
2AUNDEF_TAGundef
2BFALSE_TAGfalse
2CTRUE_TAGtrue
2DSTR_TAGstring tag
2ENOTHING_TAGallows missing terms in expressions
2FACOSH_TAGexpr acosh
30ASINH_TAGexpr asinh
31ATANH_TAGexpr atanh
35COSH_TAGexpr cosh
36SINH_TAGexpr sinh
37TANH_TAGexpr tanh
3BACOS_TAGexpr acos
3CASIN_TAGexpr asin
3DATAN_TAGexpr atan
41RACOS_TAGexpr arcos (used only internally)
42RASIN_TAGexpr arsin (used only internally)
43RATAN_TAGexpr artan (used only internally)
44COS_TAGexpr cos
45SIN_TAGexpr sin
46TAN_TAGexpr tan
4AITAN_TAGexpr tan (used only internally)
4BABS_TAGexpr abs
4CANGLE_TAGexpr angle
4DCEILING_TAGexpr ceiling
4EFLOOR_TAGexpr floor
4FINT_TAGexpr int
50SIGN_TAGexpr sign
51SQRT_TAGexpr _sqrt_
52EXPF_TAGexpr _e_^
53LN_TAGexpr ln
54LOG_TAGexpr log
55FPART_TAGexpr fPart
56IPART_TAGexpr iPart
57CONJ_TAGexpr conj
58IMAG_TAGexpr imag
59REAL_TAGexpr real
5AAPPROX_TAGexpr approx
5BTEXPAND_TAGexpr tExpand
5CTCOLLECT_TAGexpr tCollect
5DGETDENOM_TAGexpr getDenom
5EGETNUM_TAGexpr getNum
60CUMSUM_TAGlist cumSum
61DET_TAGmat det
62COLNORM_TAGmat colNorm
63ROWNORM_TAGmat rowNorm
64NORM_TAGmat norm
65MEAN_TAGlist mean
66MEDIAN_TAGlist median
67PRODUCT_TAGlist product
68STDDEV_TAGlist stdDev
69SUM_TAGlist sum
6AVARIANCE_TAGlist variance
6BUNITV_TAGvec unitV
6CDIM_TAGmat dim
6DMAT2LIST_TAGmat mat->list
6ENEWLIST_TAGno_of_elements newList
6FRREF_TAGmat rref
70REF_TAGmat ref
71IDENTITY_TAGinteger identity
72DIAG_TAGmat diag
73COLDIM_TAGmat colDim
74ROWDIM_TAGmat rowDim
75TRANSPOSE_TAGmat _transpose_
76FACTORIAL_TAGexpr !
77PERCENT_TAGexpr %
78RADIAN_TAGexpr _radians_
79NOT_TAGexpr not
7AMINUS_TAGexpr _negative_
7BVEC_POLAR_TAGmat _polar_vector_ (mat is assumed to be [[R,THETA]])
7CVEC_CYLIND_TAGmat _cylind_vector_ (mat is assumed to be [[R,THETA,Z]])
7DVEC_SPHERE_TAGmat _sphere_vector_ (mat is assumed to be [[R,THETA,PHI]])
7ESTART_TAG( (used only internally, don't use it)
7FISTORE_TAGexpr var -> (internal version: don't use)
80STORE_TAGexpr var ->
81WITH_TAGcondition expr |
82XOR_TAGexpr2 expr1 xor
83OR_TAGexpr2 expr1 or
84AND_TAGexpr2 expr1 and
85LT_TAGexpr2 expr1 <
86LE_TAGexpr2 expr1 <=
87EQ_TAGexpr2 expr1 =
88GE_TAGexpr2 expr1 >=
89GT_TAGexpr2 expr1 >
8ANE_TAGexpr2 expr1 <>
8BADD_TAGexpr1 expr2 +
8CADDELT_TAGexpr1 expr2 .+
8DSUB_TAGexpr1 expr2 -
8ESUBELT_TAGexpr1 expr2 .-
8FMUL_TAGexpr1 expr2 *
90MULELT_TAGexpr1 expr2 .*
91DIV_TAGexpr1 expr2 /
92DIVELT_TAGexpr1 expr2 ./
93POW_TAGexpr2 expr1 ^
94POWELT_TAGexpr2 expr1 .^
95SINCOS_TAGint expr trig       where trig(expr,int)=cos(expr+(int-1)*pi/2)
96SOLVE_TAGvar equation solve
97CSOLVE_TAGvar equation cSolve
98NSOLVE_TAGvar equation nSolve
99ZEROS_TAGvar equation zeros
9ACZEROS_TAGvar equation cZeros
9BFMIN_TAGvar equation fMin
9CFMAX_TAGvar equation fMax
9DCOMPLEX_TAGcomplex number
9EPOLYEVAL_TAGexpr list polyEval
9FRANDPOLY_TAGorder var randPoly
A0CROSSP_TAGvec2 vec1 crossP
A1DOTP_TAGvec2 vec1 dotP
A2GCD_TAGexpr2 expr1 gcd
A3LCM_TAGexpr2 expr1 lcm
A4MOD_TAGexpr2 expr1 mod
A5INTDIV_TAGexpr2 expr1 intDiv
A6REMAIN_TAGexpr2 expr1 remain
A7NCR_TAGexpr2 expr1 nCr
A8NPR_TAGexpr2 expr1 nPr
A9P2RX_TAGtheta_expr r_expr P->Rx
AAP2RY_TAGtheta_expr r_expr P->Ry
ABP2PTHETA_TAGy_expr x_expr R->P_THETA_
ACP2PR_TAGy_expr x_expr R->Pr
ADAUGMENT_TAGmat2 mat1 augment
AENEWMAT_TAGnum_columns num_rows newMat
AFRANDMAT_TAGnum_columns num_rows randMat
B0SIMULT_TAGvec mat simult
B1PART_TAG[#] expr part
B2EXP2LIST_TAGvar list exp->list
B3RANDNORM_TAGsd mean randNorm
B4MROW_TAGindex mat expr mRow
B5ROWADD_TAGindex2 index1 mat rowAdd
B6ROWSWAP_TAGindex2 index1 mat rowSwap
B7ARCLEN_TAGend start var expr arcLen
B8NINT_TAGup low var expr nInt
B9PI_PRODUCT_TAGhigh low var expr _PRODUCT_
BASIGMA_SUM_TAGhigh low var expr _SIGMA_
BBMROWADD_TAGindex2 index1 mat expr mRowAdd
BCANS_TAG[int] ans
BDENTRY_TAG[int] entry
BEEXACT_TAG[tol] expr exact
BFLOGB_TAGexpr2 expr1 logb       where logb(expr1,expr2)=ln(expr1)/ln(expr2)
C0COMDENOM_TAG[var] expr comDenom
C1EXPAND_TAG[var] expr expand
C2FACTOR_TAG[var] expr factor
C3CFACTOR_TAG[var] expr cFactor
C4INTEGRATE_TAG[up low] var expr _integrate_
C5DIFFERENTIATE_TAG   [order] var expr _differentiate_
C6AVGRC_TAG[h] var expr avgRC
C7NDERIV_TAG[h] var expr nDeriv
C8TAYLOR_TAG[point] order var expr taylor
C9LIMIT_TAG[direction] point var expr limit
CAPROPFRAC_TAG[[tol] var] expr propFrac
CBWHEN_TAG[[undef_val] false_val] true_val condition when
CCROUND_TAG[digits] expr round
CDDMS_TAG[[ss] mm] dd _DMSNUMBER_
CELEFT_TAG[num] string left
CFRIGHT_TAG[num] string right
D0MID_TAG[count] start string mid
D1SHIFT_TAG[int] list shift
D2SEQ_TAG[step] high low var expr seq
D3LIST2MAT_TAG[elements_per_row] list list->mat
D4SUBMAT_TAG[[[[col2] row2] col1] row1] mat subMat
D5SUBSCRIPT_TAG[col] row var _subcript_       (i.e. var[row] or var[row,col])
D6RAND_TAG[int] rand
D7MIN_TAGexpr2 list|expr1 min
D8MAX_TAGexpr2 list|expr1 max
D9LIST_TAGlist tag, or matrix represented as "list of list"
DAUSERFUNC_TAGuser defined function/program ([[...] arg1] fnc_name USERFUNC_TAG)
DBMATRIX_TAGmatrix tag (only in data editor)
DCFUNC_TAGprogram/function tag (not used in expressions)
DDDATA_TAGdata tag (not used in expressions)
DEGDB_TAGGDB tag (not used in expressions)
DFPIC_TAGpicture tag (not used in expressions)
E0TEXT_TAGtext tag (not used in expressions)
E1FIG_TAGfigure tag (not used in expressions)
E2MAC_TAGmacro tag (not used in expressions)
E3EXT_TAGextra TI-Basic function token (see ExtTags)
E4EXT_INSTR_TAGTI-Basic command token (not used in expressions, see InstructionTags)
E5END_TAGend of the expression or the list (END_TAG)
E6COMMENT_TAGcomment (not used in expressions) - organized like a string
E7NEXTEXPR_TAG":" between tokens on same line in the program (not used in expressions)
E8NEWLINE_TAGmarks end of line in TI-Basic (not used in expressions)
E9ENDSTACK_TAGend of TI-Basic program (not used in expressions), or end of the expressions stack
EAPN1_TAGexpr +/-
EBPN2_TAGexpr1 expr2 +/-
ECERROR_MSG_TAGname error_message
EDEIGVC_TAGmat eigVc
EEEIGVL_TAGmat eigVl
EFDASH_TAGexpr ' (prime, i.e. expr')
F0LOCALVAR_TAGvar _local_ (parameter/local variable reference)
F1DESOLVE_TAG[] depend_var indep_var equation deSolve
F2FDASH_TAGfunc_params func_name ' (prime, i.e. func_name'(func_params)
F3ASM_TAGASM program tag (not used in expressions)
F4ISPRIME_TAGint isPrime
F8OTH_TAGOther file tag, for future expansions (not used in expressions)
F9ROTATE_TAG[count] list|int|string rotate

enum ExtTags

If the tag of an entry on the expressions stack is EXT_TAG (0xE3), then the byte below it is the extra TI-Basic function tag. ExtTags is enumerated type for describing such extended entries (see top_estack for more info about how entries on the expressions stack are organized). This enum is quite big, and here is a complete list of extended function tags defined in it (all values are in hex), with their meaning (used notation is RPN):

01INDIR_TAGstring_expr # (indirection)
02GETKEY_TAGgetKey
03GETFOLD_TAGgetFold
04SWITCH_TAG[int] switch
05UNITCONV_TAGunit1 unit2 |> (unit conversion, unit1 |> unit2)
06ORD_TAGstring ord
07EXPR_TAGstring expr
08CHAR_TAGint char
09STRING_TAGexpr string
0AGETTYPE_TAGvar getType
0BGETMODE_TAGstring getMode
0CSETFOLD_TAGvar setFold
0DPTTEST_TAGy x ptTest
0EPXLTEST_TAGcolumn row pxlTest
0FSETGRAPH_TAGstring string setGraph
10SETTABLE_TAGstring string setTable
11SETMODE_TAGstring string setMode
12FORMAT_TAG[string] expr format
13INSTRING_TAG[start] substring search-string inString
14APPEND_TAGstring2 string1 & (append)
15DD_TAGdmsnumber |>DD
16EXPR2DMS_TAGexpr |>DMS
17VEC2RECT_TAGvec |>Rect
18VEC2POLAR_TAGvec |>Polar
19VEC2CYLIND_TAGvec |>Cylind
1AVEC2SPHERE_TAGvec |>Sphere
1BPARENTH_START_TAG(   (used only internally for the parser, not in expressions)
1CPARENTH_END_TAG)   (used only internally for the parser, not in expressions)
1DMAT_START_TAG[   (used only internally for the parser, not in expressions)
1EMAT_END_TAG]   (used only internally for the parser, not in expressions)
1FLIST_START_TAG{   (used only internally for the parser, not in expressions)
20LIST_END_TAG}   (used only internally for the parser, not in expressions)
21COMMA_TAG,   (used only internally for the parser, not in expressions)
22SEMICOLON_TAG;   (used only internally for the parser, not in expressions)
23COMPLEX_ANGLE_TAG   /_   (used only internally for the parser, not in expressions)
24SINGLE_QUOTE_TAG'   (used only internally for the parser, not in expressions)
25QUOTE_TAG"   (used only internally for the parser, not in expressions)
26POLCPLX_TAGmagnitude angle /_    (polar complex number)
27TMPCNV_TAGexpr2 expr1 tmpCnv
28DELTA_TMPCNV_TAGexpr2 expr1 _DELTA_tmpCnv
29GETUNITS_TAGgetUnits
2ASETUNITS_TAGlist setUnits
2BBIN_TAGint 0b   (i.e. 0bint)
2CHEX_TAGexpr 0h   (i.e. 0hexpr)
2DINT2BIN_TAGint |>Bin
2EINT2DEC_TAGint |>Dec
2FINT2HEX_TAGint |>Hex
30DET_TOL_TAGtol mat det
31REF_TOL_TAGtol mat ref
32RREF_TOL_TAGtol mat rref
33SIMULT_TOL_TAGtol vec mat simult
34GETCONFG_TAGgetConfg
35V_AUGMENT_TAGmat2 ; mat1 augment

enum SysvarTags

If the tag of an entry on the expressions stack is EXT_SYSTEM_TAG (0x1C), then the byte below it is the tag of a TI-Basic system variable. SysvarTags is enumerated type for describing such extended entries (see top_estack for more info about how entries on the expressions stack are organized). This enum is quite big, and here is a complete list of system variables tags defined in it (all values are in hex), with their meaning:

01X_BAR_TAGx_bar_
02Y_BAR_TAGy_bar_
03SIGMA_X_TAG_SIGMA_x
04SIGMA_X2_TAG_SIGMA_x_^2_
05SIGMA_Y_TAG_SIGMA_y
06SIGMA_Y2_TAG_SIGMA_y_^2_
07SIGMA_XY_TAG_SIGMA_xy
08SX_TAGSx
09SY_TAGSy
0ASMLSIGMA_X_TAG_sigma_x
0BSMLSIGMA_Y_TAG_sigma_y
0CNSTAT_TAGnStat
0DMINX_TAGminX
0EMINY_TAGminY
0FQ1_TAGq1
10MEDSTAT_TAGmedStat
11Q3_TAGq3
12MAXX_TAGmaxX
13MAXY_TAGmaxY
14CORR_TAGcorr
15R2_TAGR_^2_
16MEDX1_TAGmedx1
17MEDX2_TAGmedx2
18MEDX3_TAGmedx3
19MEDY1_TAGmedy1
1AMEDY2_TAGmedy2
1BMEDY3_TAGmedy3
1CXC_TAGxc
1DYC_TAGyc
1EZC_TAGzc
1FTC_TAGtc
20RC_TAGrc
21THETA_C_TAG_THETA_c
22NC_TAGnc
23XFACT_TAGxfact
24YFACT_TAGyfact
25ZFACT_TAGzfact
26XMIN_TAGxmin
27XMAX_TAGxmax
28XSCL_TAGxscl
29YMIN_TAGymin
2AYMAX_TAGymax
2BYSCL_TAGyscl
2CDELTA_X_TAG_DELTA_x
2DDELTA_Y_TAG_DELTA_y
2EXRES_TAGxres
2FXGRID_TAGxgrid
30YGRID_TAGygrid
31ZMIN_TAGzmin
32ZMAX_TAGzmax
33ZSCL_TAGzscl
34EYE_THETA_TAGeye_THETA_
35EYE_PHI_TAGeye_PHI_
36THETA_MIN_TAG_THETA_min
37THETA_MAX_TAG_THETA_max
38THETA_STEP_TAG_THETA_step
39TMIN_TAGtmin
3ATMAX_TAGtmax
3BTSTEP_TAGtstep
3CNMIN_TAGnmin
3DNMAX_TAGnmax
3EPLOTSTRT_TAGplotStrt
3FPLOTSTEP_TAGplotStep
40ZXMIN_TAGzxmin
41ZXMAX_TAGzxmax
42ZXSCL_TAGzxscl
43ZYMIN_TAGzymin
44ZYMAX_TAGzymax
45ZYSCL_TAGzyscl
46ZXRES_TAGzxres
47Z_THETA_MIN_TAGz_THETA_min
48Z_THETA_MAX_TAGz_THETA_max
49Z_THETA_STEP_TAG    z_THETA_step
4AZTMIN_TAGztmin
4BZTMAX_TAGztmax
4CZTSTEP_TAGztstep
4DZXGRID_TAGzxgrid
4EZYGRID_TAGzygrid
4FZZMIN_TAGzzmin
50ZZMAX_TAGzzmax
51ZZSCL_TAGzzscl
52ZEYE_THETA_TAGzeye_THETA_
53ZEYE_PHI_TAGzeye_PHI_
54ZNMIN_TAGznmin
55ZNMAX_TAGznmax
56ZPLTSTEP_TAGzpltstep
57ZPLTSTRT_TAGzpltstrt
58SEED1_TAGseed1
59SEED2_TAGseed2
5AOK_TAGok
5BERRORNUM_TAGerrornum
5CSYSMATH_TAGsysMath
5DSYSDATA_TAGsysData
5EREGEQ_TAGregEq (Name = null)
5FREGCOEF_TAGregCoef
60TBLINPUT_TAGtblInput
61TBLSTART_TAGtblStart
62DELTA_TBL_TAG_DELTA_tbl
63FLDPIC_TAGfldpic (this tag is suspicious)
64EYE_PSI_TAGeye_PSI_
65TPLOT_TAGtplot
66DIFTOL_TAG diftol
67ZEYE_PSI_TAGzeye_PSI_
68T0_TAGt0
69DTIME_TAGdtime
6ANCURVES_TAGncurves
6BFLDRES_TAGfldres
6CESTEP_TAGEstep
6DZT0DE_TAGzt0de
6EZTMAXDE_TAGztmaxde (Name = ztmax)
6FZTSTEPDE_TAGztstepde (Name = ztstep)
70ZTPLOTDE_TAGztplotde
71NCONTOUR_TAGncontour

enum InstructionTags

If the tag of an entry on the expressions stack is EXT_INSTR_TAG (0xE4), then the byte below it is the tag of a TI-Basic command token. Although TI-Basic tokens are not interesting for programming, they are defined in enumerated type InstructionTags, due to completeness. This enum is quite big, and here is a complete list of TI-Basic instruction token tags defined in it (all values are in hex), with their meaning (used notation is RPN):

01CLRDRAW_ITAGClrDraw
02CLRGRAPH_ITAGClrGraph
03CLRHOME_ITAGClrHome
04CLRIO_ITAGClrIO
05CLRTABLE_ITAGClrTable
06CUSTOM_ITAGCustom
07CYCLE_ITAGCycle
08DIALOG_ITAGDialog
09DISPG_ITAGDispG
0ADISPTBL_ITAGDispTbl
0BELSE_ITAGElse (in If...Endif statement)
0CENDCUSTM_ITAGEndCustm
0DENDDLOG_ITAGEndDlog
0EENDFOR_ITAGdisplacement EndFor
0FENDFUNC_ITAGEndFunc
10ENDIF_ITAGEndIf
11ENDLOOP_ITAGdisplacement EndLoop
12ENDPRGM_ITAGEndPrgm
13ENDTBAR_ITAGEndTBar
14ENDTRY_ITAGdisplacement EndTry
15ENDWHILE_ITAGdisplacement EndWhile
16EXIT_ITAGExit
17FUNC_ITAGFunc
18LOOP_ITAGLoop
19PRGM_ITAGPrgm
1ASHOWSTAT_ITAGShowStat
1BSTOP_ITAGStop
1CTHEN_ITAGThen
1DTOOLBAR_ITAGToolbar
1ETRACE_ITAGTrace
1FTRY_ITAGTry
20ZOOMBOX_ITAGZoomBox
21ZOOMDATA_ITAGZoomData
22ZOOMDEC_ITAGZoomDec
23ZOOMFIT_ITAGZoomFit
24ZOOMIN_ITAGZoomIn
25ZOOMINT_ITAGZoomInt
26ZOOMOUT_ITAGZoomOut
27ZOOMPREV_ITAGZoomPrev
28ZOOMRCL_ITAGZoomRcl
29ZOOMSQR_ITAGZoomSqr
2AZOOMSTD_ITAGZoomStd
2BZOOMSTO_ITAGZoomSto
2CZOOMTRIG_ITAGZoomTrig
2DDRAWFUNC_ITAG    expr DrawFunc
2EDRAWINV_ITAGexpr DrawInv
2FGOTO_ITAGexpr Goto (Expr = LABEL)
30LBL_ITAGexpr Lbl (Expr = LABEL)
31GET_ITAGvar Get
32SEND_ITAGlist Send
33GETCALC_ITAGvar GetCalc
34SENDCALC_ITAGvar SendCalc
35NEWFOLD_ITAGfoldername NewFold
36PRINTOBJ_ITAGvar PrintObj
37RCLGDB_ITAGvar RclGDB
38STOGDB_ITAGvar StoGDB
39ELSEIF_ITAGcondition ElseIf
3AIF_ITAGcondition If (simple variant)
3BIFTHEN_ITAGcondition If...Then (If condition Then)
3CRANDSEED_ITAGexpr RandSeed
3DWHILE_ITAGcondition While
3ELINETAN_ITAGpoint expr LineTan
3FCOPYVAR_ITAGvar2 var1 CopyVar
40RENAME_ITAGnewname oldname Rename
41STYLE_ITAGstring expr Style
42FILL_ITAGvar expr Fill
43REQUEST_ITAGvar string Request
44POPUP_ITAGvar itemlist PopUp
45PTCHG_ITAGy x PtChg
46PTOFF_ITAGy x PtOff
47PTON_ITAGy x PtOn
48PXLCHG_ITAGcolumn row PxlChg
49PXLOFF_ITAGcolumn row PxlOff
4APXLON_ITAGcolumn row PxlOn
4BMOVEVAR_ITAGnewfolder oldfolder var MoveVar
4CDROPDOWN_ITAGvar list title_string DropDown
4DOUTPUT_ITAGexpr column row Output
4EPTTEXT_ITAGy x string PtText
4FPXLTEXT_ITAGcolumn row string PxlText
50DRAWSLP_ITAGslope y x DrawSlp
51PAUSE_ITAGexpr Pause
52RETURN_ITAGexpr Return
53INPUT_ITAG[var] [string] Input
54PLOTSOFF_ITAG[9] ... [2] [1] PlotsOff
55PLOTSON_ITAG[9] ... [2] [1] PlotsOn
56TITLE_ITAG[label] string Title
57ITEM_ITAG[label] string Item
58INPUTSTR_ITAGvar [string] InputStr
59LINEHORZ_ITAG[drawmode] y LineHorz
5ALINEVERT_ITAG[drawmode] x LineVert
5BPXLHORZ_ITAG[drawmode] row PxlHorz
5CPXLVERT_ITAG[drawmode] column PxlVert
5DANDPIC_ITAG[pxlcol pxlrow] picvar AndPic
5ERCLPIC_ITAG[pxlcol pxlrow] picvar RclPic
5FRPLCPIC_ITAG[pxlcol pxlrow] picvar RplcPic
60XORPIC_ITAG[pxlcol pxlrow] picvar XorPic
61DRAWPOL_ITAG[theta_step] [theta_max] [theta_min] DrawPol
62TEXT_ITAGstring Text
63ONEVAR_ITAG[L4] [L3] [L2] [L1] OneVar
64STOPIC_ITAG[height width] [pxlcol pxlrow] var StoPic
65GRAPH_ITAG[var2] [var1] [expr2] expr1 Graph
66TABLE_ITAG[var] [expr2] expr1 Table
67NEWPIC_ITAG[maxcol] [maxrow] picvar mat NewPic
68DRAWPARM_ITAG[tstep] [tmax] [tmin] expr2 expr1 DrawParm
69CYCLEPIC_ITAG[direction] [cycle] [wait] N picname_string CyclePic
6ACUBICREG_ITAG[[L5 L4] [L3]] L2 L1 CubicReg
6BEXPREG_ITAG[[L5 L4] [L3]] L2 L1 ExpReg
6CLINREG_ITAG[[L5 L4] [L3]] L2 L1 LinReg
6DLNREG_ITAG[[L5 L4] [L3]] L2 L1 LnReg
6EMEDMED_ITAG[[L5 L4] [L3]] L2 L1 MedMed
6FPOWERREG_ITAG[[L5 L4] [L3]] L2 L1 PowerReg
70QUADREG_ITAG[[L5 L4] [L3]] L2 L1 QuadReg
71QUARTREG_ITAG[[L5 L4] [L3]] L2 L1 QuartReg
72TWOVAR_ITAG[[L5 L4] [L3]] L2 L1 TwoVar
73SHADE_ITAG[patres] [pat] [xhigh] [xlow] expr2 expr1 Shade
74FOR_ITAG[step] high low var For
75CIRCLE_ITAG[drawmode] r y x Circle
76PXLCRCL_ITAG[drawmode] r col rowPxlCrcl
77NEWPLOT_ITAG[bucket [mark] [inc] [cat] [frq] [ylist] xlist type N NewPlot
78LINE_ITAG[drawmode] yend xend ystart xstart Line
79PXLLINE_ITAG[drawmode] colend rowend colstart rowstartPxlLine
7ADISP_ITAG[[...] expr1] Disp
7BFNOFF_ITAG[9] ... [2] [1] FnOff
7CFNON_ITAG[9] ... [2] [1] FnOn
7DLOCAL_ITAG[[...] var1] Local
7EDELFOLD_ITAG[[...] var1] DelFold
7FDELVAR_ITAG[[...] var1] DelVar
80LOCK_ITAG[[...] var1] Lock
81PROMPT_ITAG[[...] var1] Prompt
82SORTA_ITAG[[...] list1] SortA
83SORTD_ITAG[[...] list1] SortD
84UNLOCK_ITAG[[...] var1] UnLock
85NEWDATA_ITAG[[...] list1] datavar NewData
86DEFINE_ITAGexpr var|userfunc Define
87ELSE_TRY_ITAGcondition Else (in Try...EndTry statement)
88CLRERR_ITAGClrErr
89PASSERR_ITAGPassErr
8ADISPHOME_ITAGDispHome
8BEXEC_ITAG[[...] expr] string Exec
8CARCHIVE_ITAG[[...] var1] Archive
8DUNARCHIV_ITAG[[...] var1] Unarchiv
8ELU_ITAG[tol] pvar uvar lvar mat LU
8FQR_ITAG[tol] rvar qvar mat QR
90BLDDATA_ITAGvar|sysdata BldData
91DRWCTOUR_ITAGexpr DrwCtour
92NEWPROB_ITAGNewProb
93SINREG_ITAG[[L4 L3] [period] [iter]] L2 L1 SinReg
94LOGISTIC_ITAG[[L4 L3] [period] [iter]] L2 L1 Logistic
95CUSTMON_ITAGCustmOn
96CUSTMOFF_ITAGCustmOff
97SENDCHAT_ITAGvar SendChat

NOTE: Displacements for jumps are 2 byte quantities in little endian format.

type ti_float

Starting for TIGCC 0.9, ti_float is an alias name for standard ANSI float type, introduced to keep backward compatibility with previous releases of the TIGCC compiler, which don't support standard ANSI floats. See bcd for more info about internal organization of floating point values.

type bcd

bcd is a structure which represents the internal structure of floating point values. It is defined as
typedef struct
  {
    unsigned short exponent;
    unsigned long long mantissa;
  } ti_float;
Note that long long is not a typing error: it is a GNU C extension for representing very long integers (8-byte integers in this implementation). See description of bcd type in the documentation for timath.h header file for more info about the internal organization of floating point values.

Return to the main index