dynamiC  0.1
Functions
DynamicOperations

Defintion of all dynamic operations, including arithmetic, logical, relational, and bit-operations. More...

Functions

trilean dyn_op_neg (dyn_c *dyn)
 Negate dynamic value in param dyn. More...
 
trilean dyn_op_add (dyn_c *dyn1, dyn_c *dyn2)
 Add dyn2 to dyn1. More...
 
trilean dyn_op_sub (dyn_c *dyn1, dyn_c *dyn2)
 Subtract dyn2 from dyn1. More...
 
trilean dyn_op_mul (dyn_c *dyn1, dyn_c *dyn2)
 Multiply dyn1 with dyn2. More...
 
trilean dyn_op_div (dyn_c *dyn1, dyn_c *dyn2)
 Divide dyn1 by dyn2. More...
 
trilean dyn_op_mod (dyn_c *dyn1, dyn_c *dyn2)
 dyn1 Modulo dyn2 More...
 
trilean dyn_op_pow (dyn_c *dyn1, dyn_c *dyn2)
 dyn1 to the power of dyn2 More...
 
trilean dyn_op_and (dyn_c *dyn1, dyn_c *dyn2)
 Logical (trinary) AND operation. More...
 
trilean dyn_op_or (dyn_c *dyn1, dyn_c *dyn2)
 Logical (trinary) OR operation. More...
 
trilean dyn_op_xor (dyn_c *dyn1, dyn_c *dyn2)
 Logical (trinary) XOR operation. More...
 
trilean dyn_op_not (dyn_c *dyn)
 Logical (trinary) Negation. More...
 
trilean dyn_op_id (dyn_c *dyn1, dyn_c *dyn2)
 Type and Value Equality. More...
 
trilean dyn_op_eq (dyn_c *dyn1, dyn_c *dyn2)
 Relational Equality. More...
 
trilean dyn_op_ne (dyn_c *dyn1, dyn_c *dyn2)
 Relational Not Equal. More...
 
trilean dyn_op_lt (dyn_c *dyn1, dyn_c *dyn2)
 Relational Less Than. More...
 
trilean dyn_op_le (dyn_c *dyn1, dyn_c *dyn2)
 Relational Less Than or Equal. More...
 
trilean dyn_op_gt (dyn_c *dyn1, dyn_c *dyn2)
 Relational Greater Than. More...
 
trilean dyn_op_ge (dyn_c *dyn1, dyn_c *dyn2)
 Relational Greater Than or Equal. More...
 
trilean dyn_op_in (dyn_c *element, dyn_c *container)
 Check if dyn2 is element of dyn1. More...
 
trilean dyn_op_b_not (dyn_c *dyn)
 Binary complement.
 
trilean dyn_op_b_and (dyn_c *dyn1, dyn_c *dyn2)
 Binary AND.
 
trilean dyn_op_b_or (dyn_c *dyn1, dyn_c *dyn2)
 Binary OR.
 
trilean dyn_op_b_xor (dyn_c *dyn1, dyn_c *dyn2)
 Binary XOR.
 
trilean dyn_op_b_shift_l (dyn_c *dyn1, dyn_c *dyn2)
 Binary shift left.
 
trilean dyn_op_b_shift_r (dyn_c *dyn1, dyn_c *dyn2)
 Binary shift right.
 

Detailed Description

Defintion of all dynamic operations, including arithmetic, logical, relational, and bit-operations.

These functions cover all basic operations, which are common for most programming languages. In principle most operations known from Python are offered with a similar behavior, but with two differences. Dynamic operations evaluate a result based on the data type with the highes priority and not on the basis of left-hand and right-hand parameters. That means, for dynple (see the defintion of every function):

// LIST type is higher than STRING type
dyn_op_add([1,2,3], "test string") == [1,2,3,"test string"]
dyn_op_add("test string", [1,2,3]) == ["test string",1,2,3]
// STRING type is higher than INTEGER type
dyn_op_mul(3, "abc") == "abcabcabc"
dyn_op_mul("abc", 3) == "abcabcabc"
// FLOAT type is higher than INTEGER type
dyn_op_div(9.0, 3) == 3.0
dyn_op_div(9, 3.0) == 3.0

The result is always stored and returned within the first parameter passed to an operator function. If this parameter is a dynamic reference of TYPE REFERENCE or REFERENCE2, then a new element is created, the original element remains. If the operation was performed without any error, then DYN_TRUE is returned by every function of that module, otherwise DYN_FALSE.

A second characteristic of the operations applied is that a trinary logical system is applied to simplify error-handling amongst other benefits. Trinary means that next to the two boolean values DYN_TRUE and DYN_FALSE, the NONE type is used to represent another unknown or undefined state. The benefit is, that comparing two distinct dynamic types such as a list and a string with less than or greater than results in that unknown/undefined state and not in an error. This trinary logical system is also perfect for applying logical operations, see therefor the corresponding logical functions.

See also
https://en.wikipedia.org/wiki/Three-valued_logic

Function Documentation

◆ dyn_op_add()

trilean dyn_op_add ( dyn_c dyn1,
dyn_c dyn2 
)

Add dyn2 to dyn1.

The add operation shows generates different results according to the input data types. The resulting type is defined by the highest type, see the following list for allowed operations:

dyn_1 dyn_2 result type
BOOL BOOL BOOL
INTEGER BOOL INTEGER
BOOL INTEGER INTEGER
INTEGER INTEGER INTEGER
FLOAT BOOL FLOAT
BOOL FLOAT FLOAT
FLOAT INTEGER FLOAT
INTEGER FLOAT FLOAT
FLOAT FLOAT FLOAT
STRING (NUMERIC) STRING (concatenaited) "abc123"
(NUMERIC) STRING STRING (concatenaited) "123abc"
STRING STRING STRING (concatenaited) "abcabc"
LIST ... LIST [, ...]
... LIST LIST [... ,]
SET ... SET {, ...} (unique elements only)
... SET SET {, ...} (unique elements only)
DICT DICT DICT {with all elements}
Parameters
[in,out]dyn1in- and output parameter
[in]dyn2input parameter
Return values
DYN_TRUEif operation could be applied onto the input data type
DYN_FALSEotherwise

Definition at line 124 of file dynamic_op.c.

125 {
126  CHECK_REFERENCE(dyn1, dyn2)
127 
128  dyn_c tmp;
129  DYN_INIT(&tmp);
130 
131  if (DYN_TYPE(dyn1) && DYN_TYPE(dyn2)) {
132  switch (max_type(dyn1, dyn2)) {
133  case BOOL:
134 
135  case INTEGER: dyn_set_int(dyn1, dyn_get_int(dyn1) + dyn_get_int(dyn2));
136  goto LABEL_OK;
137  case FLOAT: dyn_set_float(dyn1, dyn_get_float(dyn1) + dyn_get_float(dyn2));
138  goto LABEL_OK;
139  case STRING: {
140  if (DYN_TYPE(dyn1) == STRING) {
141  dyn1->data.str = (dyn_str) realloc(dyn1->data.str, dyn_strlen(dyn1->data.str) +
142  dyn_string_len(dyn2) + 1 );
143  dyn_string_add(dyn2, dyn1->data.str);
144  }
145  else {
146  tmp.type = STRING;
147  tmp.data.str = (dyn_str) malloc(dyn_string_len(dyn1) + dyn_string_len(dyn2) + 1);
148  tmp.data.str[0]='\0';
149  dyn_string_add(dyn1, tmp.data.str);
150  dyn_string_add(dyn2, tmp.data.str);
151  dyn_move(&tmp, dyn1);
152  }
153  goto LABEL_OK;
154  }
155  case LIST: {
156  if (DYN_TYPE(dyn1) == LIST) {
157  dyn_list_push(dyn1, dyn2);
158  } else {
159  dyn_move(dyn1, &tmp);
160  dyn_copy(dyn2, dyn1);
161  dyn_list_insert(dyn1, &tmp, 0);
162  }
163  goto LABEL_OK;
164 
165  }
166  case SET: {
167  if (DYN_TYPE(dyn1) == DYN_TYPE(dyn2)) {
168  dyn_ushort i;
169  for (i=0; i<DYN_LIST_LEN(dyn2); ++i)
170  dyn_set_insert(dyn1, DYN_LIST_GET_REF(dyn2, i));
171  } else if (DYN_TYPE(dyn1) == SET) {
172  dyn_set_insert(dyn1, dyn2);
173  } else {
174  dyn_move(dyn1, &tmp);
175  dyn_copy(dyn2, dyn1);
176  dyn_set_insert(dyn1, &tmp);
177  }
178  goto LABEL_OK;
179  }
180  case DICT: {
181  if (DYN_TYPE(dyn1) == DYN_TYPE(dyn2)) {
182  dyn_ushort i;
183  for (i=0; i<DYN_DICT_LEN(dyn2); ++i)
184  dyn_dict_insert(dyn1,
185  DYN_DICT_GET_I_KEY(dyn2, i),
186  DYN_DICT_GET_I_REF(dyn2, i));
187  goto LABEL_OK;
188  }
189  }
190  }
191  }
192 
193  dyn_free(dyn1);
194  return DYN_FALSE;
195 LABEL_OK:
196  return DYN_TRUE;
197 }
float 32 bit
Definition: dynamic_types.h:65
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
dyn_float dyn_get_float(const dyn_c *dyn)
Return float value of a dynamic element.
dictionary of type dyn_dict
Definition: dynamic_types.h:69
dyn_ushort dyn_strlen(dyn_const_str str)
Returns the length of an string.
dyn_c * dyn_dict_insert(dyn_c *dict, dyn_const_str key, dyn_c *value)
Insert a new key-value pair into the dictionary.
Definition: dynamic_dict.c:65
trilean dyn_list_insert(dyn_c *list, dyn_c *element, const dyn_ushort i)
Insert a new element at the ith position into a list.
Definition: dynamic_list.c:199
#define DYN_LIST_LEN(dyn)
Return list length.
Definition: dynamic.h:123
dyn_int dyn_get_int(const dyn_c *dyn)
Return integer value of a dynamic element.
trilean dyn_set_insert(dyn_c *set, dyn_c *element)
Insert new element into set, if and only if it is not included yet.
Definition: dynamic_set.c:48
dyn_int i
basic integer
Definition: dynamic_types.h:59
trilean dyn_copy(const dyn_c *dyn, dyn_c *copy)
Deep copy dynamic element.
set of type dyn_list
Definition: dynamic_types.h:68
#define DYN_INIT(dyn)
Mandatory initialization for dynamic elements (NONE)
Definition: dynamic.h:38
#define DYN_LIST_GET_REF(dyn, i)
Return the reference to the ith element within a dynamic list.
Definition: dynamic.h:125
Boolean 0==False, 1==True.
Definition: dynamic_types.h:62
#define DYN_DICT_GET_I_REF(dyn, i)
Return a reference to the ith element stored within a dictionary.
Definition: dynamic.h:191
#define DYN_DICT_GET_I_KEY(dyn, i)
Return a reference to the ith key stored within a dictionary.
Definition: dynamic.h:194
list of type dyn_list
Definition: dynamic_types.h:67
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
#define DYN_DICT_LEN(dyn)
Return number of elements within a dictionary.
Definition: dynamic.h:188
signed integer 32 bit
Definition: dynamic_types.h:64
char*
Definition: dynamic_types.h:66
uint16_t dyn_ushort
16bit unsigned integer
Definition: dynamic_types.h:43
void dyn_string_add(const dyn_c *dyn, dyn_str string)
Add string representation of dynamic element to string.
void dyn_move(dyn_c *from, dyn_c *to)
Move dynamic element to new reference, from is of type NONE afterwards.
void dyn_set_float(dyn_c *dyn, const dyn_float v)
Set dynamic element to FLOAT.
Definition: dynamic.c:99
dyn_ushort dyn_string_len(const dyn_c *dyn)
Calculate length of string representation of dynamic element.
dyn_c * dyn_list_push(dyn_c *list, const dyn_c *element)
Push new element to the end of a list.
Definition: dynamic_list.c:124
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30
char * dyn_str
Standard dynamic C string.
Definition: dynamic_types.h:36
char type
type definition
void dyn_set_int(dyn_c *dyn, const dyn_int v)
Set dynamic element to INTEGER.
Definition: dynamic.c:88
dyn_str str
pointer to character-array
Basic container for dynamic data types.
Definition: dynamic_types.h:98

◆ dyn_op_and()

trilean dyn_op_and ( dyn_c dyn1,
dyn_c dyn2 
)

Logical (trinary) AND operation.

As depicted in the truth table below, this function performes the standard boolean AND operation, the extention with the None boolean type does not affect this operation. The truth value of every dynamic element is generated with the help of function dyn_get_bool_3.

AND True False None
True True False None
False False False False
None None False None

The result of this operation is stored within the first parameter dyn1, if this value is a reference, then a new value is created, otherwise the original value gets overwritten.

See also
dyn_get_bool_3
dyn_get_bool
Parameters
[out]dyn1in- and output dynamic element
[in]dyn2second operand
Returns
DYN_TRUE, operation can be applied on every combination of dynamic data types

Definition at line 542 of file dynamic_op.c.

543 {
544  dyn_char o1 = dyn_get_bool_3(dyn1);
545  dyn_char o2 = dyn_get_bool_3(dyn2);
546 
547  if (o1 != DYN_NONE && o2 != DYN_NONE)
548  dyn_set_bool(dyn1, o1 && o2);
549  else if (o1 == DYN_FALSE || o2 == DYN_FALSE)
550  dyn_set_bool(dyn1, DYN_FALSE);
551  else
552  dyn_free(dyn1);
553 
554  return DYN_TRUE;
555 }
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
represents a third unknown state, which is not true or false
Definition: dynamic_types.h:25
char dyn_char
Basic 8bit signed integer.
Definition: dynamic_types.h:30
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77
trilean dyn_get_bool_3(const dyn_c *dyn)
Returns the trinary truth value (DYN_TRUE|DYN_FALSE|DYN_NONE) of an element.
Definition: dynamic_op.c:509
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30

◆ dyn_op_div()

trilean dyn_op_div ( dyn_c dyn1,
dyn_c dyn2 
)

Divide dyn1 by dyn2.

Dividing is only performed onto NUMERIC values, for all other values DYN_FALSE gets returned.

Parameters
[in,out]dyn1in- and output parameter
[in]dyn2input parameter
Return values
DYN_TRUEif operation could be applied onto the input data types
DYN_FALSEotherwise

Definition at line 356 of file dynamic_op.c.

357 {
358  CHECK_REFERENCE(dyn1, dyn2)
359 
360  if ( DYN_TYPE(dyn1) && DYN_TYPE(dyn2) ) {
361  switch (max_type(dyn1, dyn2)) {
362  case BOOL:
363  case INTEGER: dyn_set_int(dyn1, dyn_get_int(dyn1) / dyn_get_int(dyn2));
364  goto LABEL_OK;
365  case FLOAT: dyn_set_float(dyn1, dyn_get_float(dyn1) / dyn_get_float(dyn2));
366  goto LABEL_OK;
367  }
368  }
369 
370  dyn_free(dyn1);
371  return DYN_FALSE;
372 
373 LABEL_OK:
374  return DYN_TRUE;
375 }
float 32 bit
Definition: dynamic_types.h:65
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
dyn_float dyn_get_float(const dyn_c *dyn)
Return float value of a dynamic element.
dyn_int dyn_get_int(const dyn_c *dyn)
Return integer value of a dynamic element.
Boolean 0==False, 1==True.
Definition: dynamic_types.h:62
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
signed integer 32 bit
Definition: dynamic_types.h:64
void dyn_set_float(dyn_c *dyn, const dyn_float v)
Set dynamic element to FLOAT.
Definition: dynamic.c:99
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30
void dyn_set_int(dyn_c *dyn, const dyn_int v)
Set dynamic element to INTEGER.
Definition: dynamic.c:88

◆ dyn_op_eq()

trilean dyn_op_eq ( dyn_c dyn1,
dyn_c dyn2 
)

Relational Equality.

Parameters
[in,out]dyn1in and output parameter
[in]dyn2exponent value
Returns
DYN_TRUE, can be performed onto any combination of types

Definition at line 850 of file dynamic_op.c.

Referenced by dyn_op_id().

851 {
852  dyn_set_bool(dyn1, dyn_op_cmp(dyn1, dyn2)
853  ? DYN_FALSE
854  : DYN_TRUE);
855  return DYN_TRUE;
856 }
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77
dyn_char dyn_op_cmp(dyn_c *dyn1, dyn_c *dyn2)
Common compare function for dynamic elements.
Definition: dynamic_op.c:683

◆ dyn_op_ge()

trilean dyn_op_ge ( dyn_c dyn1,
dyn_c dyn2 
)

Relational Greater Than or Equal.

Parameters
[in,out]dyn1in and output parameter
[in]dyn2exponent value
Returns
DYN_TRUE, can be performed onto any combination of types

Definition at line 898 of file dynamic_op.c.

899 {
900  dyn_op_lt(dyn1, dyn2);
901  dyn_op_not(dyn1); // NONE remains NONE
902 
903  return DYN_TRUE;
904 }
represents boolean true
Definition: dynamic_types.h:24
trilean dyn_op_not(dyn_c *dyn)
Logical (trinary) Negation.
Definition: dynamic_op.c:658
trilean dyn_op_lt(dyn_c *dyn1, dyn_c *dyn2)
Relational Less Than.
Definition: dynamic_op.c:878

◆ dyn_op_gt()

trilean dyn_op_gt ( dyn_c dyn1,
dyn_c dyn2 
)

Relational Greater Than.

Parameters
[in,out]dyn1in and output parameter
[in]dyn2exponent value
Returns
DYN_TRUE, can be performed onto any combination of types

Definition at line 912 of file dynamic_op.c.

Referenced by dyn_op_le().

913 {
914  dyn_char rslt = dyn_op_cmp (dyn1, dyn2);
915 
916  // types not comparable
917  if (rslt == 4)
918  dyn_free(dyn1);
919  else
920  dyn_set_bool(dyn1, (rslt == 2)
921  ? DYN_TRUE
922  : DYN_FALSE );
923  return DYN_TRUE;
924 }
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
char dyn_char
Basic 8bit signed integer.
Definition: dynamic_types.h:30
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30
dyn_char dyn_op_cmp(dyn_c *dyn1, dyn_c *dyn2)
Common compare function for dynamic elements.
Definition: dynamic_op.c:683

◆ dyn_op_id()

trilean dyn_op_id ( dyn_c dyn1,
dyn_c dyn2 
)

Type and Value Equality.

Parameters
[in,out]dyn1in and output parameter
[in]dyn2exponent value
Returns
DYN_TRUE, can be performed onto any combination of types

Definition at line 834 of file dynamic_op.c.

835 {
836  if( DYN_TYPE(DYN_IS_REFERENCE(dyn1) ? dyn1->data.ref : dyn1) ==
837  DYN_TYPE(DYN_IS_REFERENCE(dyn2) ? dyn2->data.ref : dyn2) )
838  dyn_op_eq(dyn1, dyn2);
839  else
840  dyn_set_bool(dyn1, DYN_FALSE);
841  return DYN_TRUE;
842 }
dyn_c * ref
reference pointer to dynamic elements
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
#define DYN_IS_REFERENCE(dyn)
Check if dynamic element is of type REFERENCE.
Definition: dynamic.h:46
trilean dyn_op_eq(dyn_c *dyn1, dyn_c *dyn2)
Relational Equality.
Definition: dynamic_op.c:850
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77

◆ dyn_op_in()

trilean dyn_op_in ( dyn_c element,
dyn_c container 
)

Check if dyn2 is element of dyn1.

Can only be applied if the container is of type LIST, SET, or DICT.

Parameters
[in,out]inand output parameter
[in]dyn2exponent value
Return values
DYN_TRUEif the operation could be applied
DYN_FALSEotherwise

Definition at line 949 of file dynamic_op.c.

Referenced by dyn_set_insert().

950 {
951  dyn_c *tmp = DYN_IS_REFERENCE(element) ? element->data.ref : element;
952 
953  if(DYN_IS_REFERENCE(container))
954  container = container->data.ref;
955 
956  switch (DYN_TYPE(container)) {
957  case SET:
958  case LIST:
959  case DICT:
960  dyn_set_bool(element, search(container, tmp));
961  return DYN_TRUE;
962  }
963 
964  dyn_free(element);
965  return DYN_FALSE;
966 }
dyn_c * ref
reference pointer to dynamic elements
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
dictionary of type dyn_dict
Definition: dynamic_types.h:69
#define DYN_IS_REFERENCE(dyn)
Check if dynamic element is of type REFERENCE.
Definition: dynamic.h:46
set of type dyn_list
Definition: dynamic_types.h:68
list of type dyn_list
Definition: dynamic_types.h:67
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30
Basic container for dynamic data types.
Definition: dynamic_types.h:98

◆ dyn_op_le()

trilean dyn_op_le ( dyn_c dyn1,
dyn_c dyn2 
)

Relational Less Than or Equal.

Parameters
[in,out]dyn1in- and output parameter
[in]dyn2exponent value
Returns
DYN_TRUE, can be performed onto any combination of types

Definition at line 932 of file dynamic_op.c.

933 {
934  dyn_op_gt(dyn1, dyn2);
935  dyn_op_not(dyn1); // NONE remains NONE
936 
937  return DYN_TRUE;
938 }
represents boolean true
Definition: dynamic_types.h:24
trilean dyn_op_not(dyn_c *dyn)
Logical (trinary) Negation.
Definition: dynamic_op.c:658
trilean dyn_op_gt(dyn_c *dyn1, dyn_c *dyn2)
Relational Greater Than.
Definition: dynamic_op.c:912

◆ dyn_op_lt()

trilean dyn_op_lt ( dyn_c dyn1,
dyn_c dyn2 
)

Relational Less Than.

Parameters
[in,out]dyn1in and output parameter
[in]dyn2exponent value
Returns
DYN_TRUE, can be performed onto any combination of types

Definition at line 878 of file dynamic_op.c.

Referenced by dyn_op_ge().

879 {
880  dyn_char rslt = dyn_op_cmp (dyn1, dyn2);
881 
882  // types not comparable
883  if (rslt == 4)
884  dyn_free(dyn1);
885  else
886  dyn_set_bool(dyn1, (rslt == 1)
887  ? DYN_TRUE
888  : DYN_FALSE);
889  return DYN_TRUE;
890 }
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
char dyn_char
Basic 8bit signed integer.
Definition: dynamic_types.h:30
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30
dyn_char dyn_op_cmp(dyn_c *dyn1, dyn_c *dyn2)
Common compare function for dynamic elements.
Definition: dynamic_op.c:683

◆ dyn_op_mod()

trilean dyn_op_mod ( dyn_c dyn1,
dyn_c dyn2 
)

dyn1 Modulo dyn2

Modulo can only be performed onto NUMERIC values, if these are of type FLOAT then they are casted to INTEGER, such that the result is always of type INTEGER.

Parameters
[in,out]dyn1in- and output(INTEGER) parameter
[in]dyn2input parameter
Return values
DYN_TRUEif operation could be applied onto the input data types
DYN_FALSEotherwise

Definition at line 388 of file dynamic_op.c.

389 {
390  CHECK_REFERENCE(dyn1, dyn2)
391 
392  dyn_char t1 = DYN_TYPE(dyn1);
393  dyn_char t2 = DYN_TYPE(dyn2);
394 
395  if ( (t1 && t2) && t1 <= FLOAT && t2 <= FLOAT ) {
396  dyn_set_int(dyn1, dyn_get_int(dyn1) % dyn_get_int(dyn2));
397  return DYN_TRUE;
398  }
399 
400  dyn_free(dyn1);
401  return DYN_FALSE;
402 }
float 32 bit
Definition: dynamic_types.h:65
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
dyn_int dyn_get_int(const dyn_c *dyn)
Return integer value of a dynamic element.
char dyn_char
Basic 8bit signed integer.
Definition: dynamic_types.h:30
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30
void dyn_set_int(dyn_c *dyn, const dyn_int v)
Set dynamic element to INTEGER.
Definition: dynamic.c:88

◆ dyn_op_mul()

trilean dyn_op_mul ( dyn_c dyn1,
dyn_c dyn2 
)

Multiply dyn1 with dyn2.

Multiplication generates different results according to the input data types. For NUMERIC and NUMERIC data types the common arithmetic multiplication gets applied and for the combination of: (LIST|STRING) * NUMERIC or NUMERIC * (LIST|STRING) results in a repeated string or repeated list, multiplication with ZERO generates an empty LIST or STRING, negative values are not allowed.

Parameters
[in,out]dyn1in- and output parameter
[in]dyn2input parameter
Return values
DYN_TRUEif operation could be applied onto the input data types or values
DYN_FALSEotherwise

Definition at line 271 of file dynamic_op.c.

272 {
273  CHECK_REFERENCE(dyn1, dyn2)
274 
275  if (DYN_TYPE(dyn1) && DYN_TYPE(dyn2)) {
276  switch (max_type(dyn1, dyn2)) {
277  case BOOL:
278  case INTEGER: dyn_set_int(dyn1, dyn_get_int(dyn1) * dyn_get_int(dyn2));
279  goto LABEL_OK;
280  case FLOAT: dyn_set_float(dyn1, dyn_get_float(dyn1) * dyn_get_float(dyn2));
281  goto LABEL_OK;
282  case STRING: {
283  dyn_ushort i;
284  if (DYN_TYPE(dyn1) == INTEGER && DYN_TYPE(dyn2) == STRING) {
285  i = dyn_get_int(dyn1);
286  dyn_copy(dyn2, dyn1);
287  } else if (DYN_TYPE(dyn1) == STRING && DYN_TYPE(dyn2) == INTEGER)
288  i = dyn_get_int(dyn2);
289  else
290  break;
291  switch (i) {
292  case 0: dyn_set_string(dyn1, "");
293  case 1: break;
294  default: {
295  dyn_ushort len = dyn_strlen(dyn1->data.str);
296  dyn1->data.str = (dyn_str) realloc(dyn1->data.str, len * i + 1);
297 
298  dyn_str c = &dyn1->data.str[len];
299  dyn_ushort j;
300  while(--i) {
301  for(j=0; j<len; ++j) {
302  *c++ = dyn1->data.str[j];
303  }
304  }
305  *c = '\0';
306  }
307  }
308  goto LABEL_OK;
309  }
310  case LIST: {
311  dyn_ushort i;
312  if (DYN_TYPE(dyn1) == INTEGER && DYN_TYPE(dyn2) == LIST) {
313  i = dyn_get_int(dyn1);
314  dyn_copy(dyn2, dyn1);
315  } else if (DYN_TYPE(dyn1) == LIST && DYN_TYPE(dyn2) == INTEGER)
316  i = dyn_get_int(dyn2);
317  else
318  break;
319 
320  dyn_ushort len = DYN_LIST_LEN(dyn1);
321  if (!i) {
322  dyn_set_list_len(dyn1, 1);
323  goto LABEL_OK;
324  }
325  if (i > 0) {
326  if (dyn_list_resize(dyn1, DYN_LIST_LEN(dyn1)*i ) ) {
327  dyn_ushort m, n;
328  for (m=1; m<i; ++m) {
329  for (n=0; n<len; n++)
330  dyn_list_push(dyn1, DYN_LIST_GET_REF(dyn1 ,n));
331  }
332  goto LABEL_OK;
333  }
334  }
335  }
336  }
337  }
338 
339  dyn_free(dyn1);
340  return DYN_FALSE;
341 
342 LABEL_OK:
343  return DYN_TRUE;
344 }
float 32 bit
Definition: dynamic_types.h:65
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
dyn_float dyn_get_float(const dyn_c *dyn)
Return float value of a dynamic element.
dyn_ushort dyn_strlen(dyn_const_str str)
Returns the length of an string.
#define DYN_LIST_LEN(dyn)
Return list length.
Definition: dynamic.h:123
dyn_int dyn_get_int(const dyn_c *dyn)
Return integer value of a dynamic element.
trilean dyn_set_string(dyn_c *dyn, dyn_const_str v)
Set dynamic element to STRING.
Definition: dynamic.c:128
dyn_int i
basic integer
Definition: dynamic_types.h:59
trilean dyn_copy(const dyn_c *dyn, dyn_c *copy)
Deep copy dynamic element.
#define DYN_LIST_GET_REF(dyn, i)
Return the reference to the ith element within a dynamic list.
Definition: dynamic.h:125
Boolean 0==False, 1==True.
Definition: dynamic_types.h:62
list of type dyn_list
Definition: dynamic_types.h:67
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
signed integer 32 bit
Definition: dynamic_types.h:64
char*
Definition: dynamic_types.h:66
uint16_t dyn_ushort
16bit unsigned integer
Definition: dynamic_types.h:43
void dyn_set_float(dyn_c *dyn, const dyn_float v)
Set dynamic element to FLOAT.
Definition: dynamic.c:99
dyn_c * dyn_list_push(dyn_c *list, const dyn_c *element)
Push new element to the end of a list.
Definition: dynamic_list.c:124
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30
trilean dyn_list_resize(dyn_c *list, const dyn_ushort size)
Change the maximal space of a list.
Definition: dynamic_list.c:91
char * dyn_str
Standard dynamic C string.
Definition: dynamic_types.h:36
void dyn_set_int(dyn_c *dyn, const dyn_int v)
Set dynamic element to INTEGER.
Definition: dynamic.c:88
trilean dyn_set_list_len(dyn_c *dyn, dyn_ushort len)
Set dynamic element to list with maximal length.
Definition: dynamic_list.c:37
dyn_str str
pointer to character-array

◆ dyn_op_ne()

trilean dyn_op_ne ( dyn_c dyn1,
dyn_c dyn2 
)

Relational Not Equal.

Parameters
[in,out]dyn1in and output parameter
[in]dyn2exponent value
Returns
DYN_TRUE, can be performed onto any combination of types

Definition at line 864 of file dynamic_op.c.

865 {
866  dyn_set_bool(dyn1, dyn_op_cmp(dyn1, dyn2)
867  ? DYN_TRUE
868  : DYN_FALSE);
869  return DYN_TRUE;
870 }
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77
dyn_char dyn_op_cmp(dyn_c *dyn1, dyn_c *dyn2)
Common compare function for dynamic elements.
Definition: dynamic_op.c:683

◆ dyn_op_neg()

trilean dyn_op_neg ( dyn_c dyn)

Negate dynamic value in param dyn.

The negation operation is only be applied onto numeric or boolean/trilean data types. For all other types the result of dyn is set to type NONE.

Parameters
dynin- and output dynamic element
Return values
DYN_TRUEif operation could be applied onto the input data type
DYN_FALSEotherwise

Definition at line 72 of file dynamic_op.c.

73 {
74  CHECK_COPY_REFERENCE(dyn)
75 
76  switch (DYN_TYPE(dyn)) {
77  case NONE: goto LABEL_OK;
78  case BOOL: dyn->data.b = !dyn->data.b;
79  goto LABEL_OK;
80  case INTEGER: dyn->data.i = -dyn->data.i;
81  goto LABEL_OK;
82  case FLOAT: dyn->data.f = -dyn->data.f;
83  goto LABEL_OK;
84  }
85 
86  dyn_free(dyn);
87  return DYN_FALSE;
88 
89 LABEL_OK:
90  return DYN_TRUE;
91 }
float 32 bit
Definition: dynamic_types.h:65
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
dyn_char b
boolean value
dyn_float f
float value
Boolean 0==False, 1==True.
Definition: dynamic_types.h:62
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
signed integer 32 bit
Definition: dynamic_types.h:64
None type without any value.
Definition: dynamic_types.h:61
dyn_int i
basic integer
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30

◆ dyn_op_not()

trilean dyn_op_not ( dyn_c dyn)

Logical (trinary) Negation.

As depicted in the truth table below, this function performes the standard boolean NOT operation, the extention with the None boolean type does not affect this operation. The truth value of every dynamic element is generated with the help of function dyn_get_bool_3.

NOT True False None
NOT False True None

The result of this operation is stored within the first parameter dyn1, if this value is a reference, then a new value is created, otherwise the original value gets overwritten.

See also
dyn_get_bool_3
dyn_get_bool
Parameters
[out]dynin- and output dynamic element
Returns
DYN_TRUE, operation can be applied on every combination of dynamic data types

Definition at line 658 of file dynamic_op.c.

Referenced by dyn_op_ge(), and dyn_op_le().

659 {
660  CHECK_COPY_REFERENCE(dyn)
661 
662  if (DYN_NOT_NONE(dyn))
663  dyn_set_bool(dyn, !dyn_get_bool_3(dyn));
664 
665  return DYN_TRUE;
666 }
represents boolean true
Definition: dynamic_types.h:24
#define DYN_NOT_NONE(dyn)
Check if dynamic element is not of type NONE.
Definition: dynamic.h:44
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77
trilean dyn_get_bool_3(const dyn_c *dyn)
Returns the trinary truth value (DYN_TRUE|DYN_FALSE|DYN_NONE) of an element.
Definition: dynamic_op.c:509

◆ dyn_op_or()

trilean dyn_op_or ( dyn_c dyn1,
dyn_c dyn2 
)

Logical (trinary) OR operation.

As depicted in the truth table below, this function performes the standard boolean OR operation, the extention with the None boolean type does not affect this operation. The truth value of every dynamic element is generated with the help of function dyn_get_bool_3.

OR True False None
True True True True
False True False None
None True None None

The result of this operation is stored within the first parameter dyn1, if this value is a reference, then a new value is created, otherwise the original value gets overwritten.

See also
dyn_get_bool_3
dyn_get_bool
Parameters
[out]dyn1in- and output dynamic element
[in]dyn2second operand
Returns
DYN_TRUE, operation can be applied on every combination of dynamic data types

Definition at line 582 of file dynamic_op.c.

583 {
584  dyn_char o1 = dyn_get_bool_3(dyn1);
585  dyn_char o2 = dyn_get_bool_3(dyn2);
586 
587  if (o1 != DYN_NONE && o2 != DYN_NONE)
588  dyn_set_bool(dyn1, o1 || o2);
589  else if (o1 == DYN_TRUE || o2 == DYN_TRUE)
590  dyn_set_bool(dyn1, DYN_TRUE);
591  else
592  dyn_free(dyn1);
593 
594  return DYN_TRUE;
595 }
represents boolean true
Definition: dynamic_types.h:24
represents a third unknown state, which is not true or false
Definition: dynamic_types.h:25
char dyn_char
Basic 8bit signed integer.
Definition: dynamic_types.h:30
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77
trilean dyn_get_bool_3(const dyn_c *dyn)
Returns the trinary truth value (DYN_TRUE|DYN_FALSE|DYN_NONE) of an element.
Definition: dynamic_op.c:509
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30

◆ dyn_op_pow()

trilean dyn_op_pow ( dyn_c dyn1,
dyn_c dyn2 
)

dyn1 to the power of dyn2

Power function is only applied onto NUMERIC values less than FLOAT, in case of a FLOAT value the system pow function gets applied or in case of the usage of an embedded system, fast_approx_pow algorithm is applied.

Parameters
[in,out]dyn1base value and result value
[in]dyn2exponent value
Return values
DYN_TRUEif operation could be applied onto the input data types
DYN_FALSEotherwise

Definition at line 453 of file dynamic_op.c.

454 {
455  CHECK_REFERENCE(dyn1, dyn2)
456 
457  if (DYN_IS_NONE(dyn1) || DYN_IS_NONE(dyn2)) {
458  dyn_free(dyn1);
459  return DYN_FALSE;
460  }
461 
462  if (DYN_TYPE(dyn1) <= FLOAT && DYN_TYPE(dyn2) == FLOAT) {
464  dyn_get_float(dyn2)));
465  return DYN_TRUE;
466  }
467 
468  if (DYN_TYPE(dyn2) == INTEGER) {
469  dyn_int exponent = dyn_get_int(dyn2);
470 
471  if (DYN_TYPE(dyn1) == INTEGER) {
472  dyn_int base = dyn_get_int(dyn1);
473  if (exponent > 0) {
474  while (--exponent)
475  dyn1->data.i *= base;
476  } else {
477  dyn_set_float(dyn1, base);
478  --exponent;
479  while (exponent++)
480  dyn1->data.f /= base;
481  }
482  return DYN_TRUE;
483  } else if (DYN_TYPE(dyn1) == FLOAT) {
484  dyn_float base = dyn_get_float(dyn1);
485  if (exponent > 0) {
486  while (--exponent)
487  dyn1->data.f *= base;
488  } else {
489  --exponent;
490  while (exponent++)
491  dyn1->data.f /= base;
492  }
493  return DYN_TRUE;
494  }
495  }
496 
497  dyn_free(dyn1);
498  return DYN_FALSE;
499 }
float 32 bit
Definition: dynamic_types.h:65
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
int32_t dyn_int
32bit signed integer, standard Integer type.
Definition: dynamic_types.h:49
dyn_float dyn_get_float(const dyn_c *dyn)
Return float value of a dynamic element.
dyn_float f
float value
dyn_int dyn_get_int(const dyn_c *dyn)
Return integer value of a dynamic element.
#define DYN_IS_NONE(dyn)
Check if dynamic element is of type NONE.
Definition: dynamic.h:42
float fast_approx_pow(float x, float p)
Power function approximation x^y.
Definition: dynamic_op.c:417
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
signed integer 32 bit
Definition: dynamic_types.h:64
void dyn_set_float(dyn_c *dyn, const dyn_float v)
Set dynamic element to FLOAT.
Definition: dynamic.c:99
dyn_int i
basic integer
float dyn_float
basic float definition (32 bit)
Definition: dynamic_types.h:55
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30

◆ dyn_op_sub()

trilean dyn_op_sub ( dyn_c dyn1,
dyn_c dyn2 
)

Subtract dyn2 from dyn1.

The subtract operation shows generates different results according to the input data types. Subtraction is allowed on numeric values and onto sets, where the second parameter defines the element/set that shoult be subtracted from the other set.

Parameters
[in,out]dyn1in- and output parameter
[in]dyn2input parameter
Return values
DYN_TRUEif operation could be applied onto the input data types
DYN_FALSEotherwise

Definition at line 211 of file dynamic_op.c.

212 {
213  CHECK_REFERENCE(dyn1, dyn2)
214 
215  if ( DYN_TYPE(dyn1) && DYN_TYPE(dyn2) ) {
216  switch (max_type(dyn1, dyn2)) {
217  case BOOL:
218  case INTEGER: dyn_set_int(dyn1, dyn_get_int(dyn1) - dyn_get_int(dyn2));
219  goto LABEL_OK;
220  case FLOAT: dyn_set_float(dyn1, dyn_get_float(dyn1) - dyn_get_float(dyn2));
221  goto LABEL_OK;
222  case SET: {
223  dyn_ushort pos;
224  if (DYN_TYPE(dyn1) == DYN_TYPE(dyn2)) {
225  dyn_ushort i;
226  for (i=0; i<DYN_LIST_LEN(dyn2); ++i) {
227  pos = search(dyn1, DYN_LIST_GET_REF(dyn2, i));
228  if (pos)
229  dyn_list_remove(dyn1, pos-1);
230  }
231  } else if (DYN_TYPE(dyn1) == SET) {
232  pos = search(dyn1, dyn2);
233  if (pos)
234  dyn_list_remove(dyn1, pos-1);
235  } else {
236  dyn_c tmp;
237  DYN_INIT(&tmp);
238  dyn_move(dyn1, &tmp);
239  dyn_copy(dyn2, dyn1);
240  pos = search(dyn1, &tmp);
241  if (pos)
242  dyn_list_remove(dyn1, pos-1);
243  }
244  goto LABEL_OK;
245  }
246  }
247  }
248 
249  dyn_free(dyn1);
250  return DYN_FALSE;
251 
252 LABEL_OK:
253  return DYN_TRUE;
254 }
float 32 bit
Definition: dynamic_types.h:65
represents boolean false
Definition: dynamic_types.h:23
represents boolean true
Definition: dynamic_types.h:24
dyn_float dyn_get_float(const dyn_c *dyn)
Return float value of a dynamic element.
trilean dyn_list_remove(dyn_c *list, dyn_ushort i)
Delete the ith element from a list.
Definition: dynamic_list.c:172
#define DYN_LIST_LEN(dyn)
Return list length.
Definition: dynamic.h:123
dyn_int dyn_get_int(const dyn_c *dyn)
Return integer value of a dynamic element.
dyn_int i
basic integer
Definition: dynamic_types.h:59
trilean dyn_copy(const dyn_c *dyn, dyn_c *copy)
Deep copy dynamic element.
set of type dyn_list
Definition: dynamic_types.h:68
#define DYN_INIT(dyn)
Mandatory initialization for dynamic elements (NONE)
Definition: dynamic.h:38
#define DYN_LIST_GET_REF(dyn, i)
Return the reference to the ith element within a dynamic list.
Definition: dynamic.h:125
Boolean 0==False, 1==True.
Definition: dynamic_types.h:62
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
signed integer 32 bit
Definition: dynamic_types.h:64
uint16_t dyn_ushort
16bit unsigned integer
Definition: dynamic_types.h:43
void dyn_move(dyn_c *from, dyn_c *to)
Move dynamic element to new reference, from is of type NONE afterwards.
void dyn_set_float(dyn_c *dyn, const dyn_float v)
Set dynamic element to FLOAT.
Definition: dynamic.c:99
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30
void dyn_set_int(dyn_c *dyn, const dyn_int v)
Set dynamic element to INTEGER.
Definition: dynamic.c:88
Basic container for dynamic data types.
Definition: dynamic_types.h:98

◆ dyn_op_xor()

trilean dyn_op_xor ( dyn_c dyn1,
dyn_c dyn2 
)

Logical (trinary) XOR operation.

As depicted in the truth table below, this function performes the standard boolean XOR operation, the extention with the None boolean type does not affect this operation. The truth value of every dynamic element is generated with the help of function dyn_get_bool_3.

XOR True False None
True False True None
False True False None
None None None None

The result of this operation is stored within the first parameter dyn1, if this value is a reference, then a new value is created, otherwise the original value gets overwritten.

See also
dyn_get_bool_3
dyn_get_bool
Parameters
[out]dyn1in- and output dynamic element
[in]dyn2second operand
Returns
DYN_TRUE, operation can be applied on every combination of dynamic data types

Definition at line 623 of file dynamic_op.c.

624 {
625  dyn_char o1 = dyn_get_bool_3(dyn1);
626  dyn_char o2 = dyn_get_bool_3(dyn2);
627 
628  if (o1 != DYN_NONE && o2 != DYN_NONE)
629  dyn_set_bool(dyn1, o1 != o2);
630  else
631  dyn_free(dyn1);
632 
633  return DYN_TRUE;
634 }
represents boolean true
Definition: dynamic_types.h:24
represents a third unknown state, which is not true or false
Definition: dynamic_types.h:25
char dyn_char
Basic 8bit signed integer.
Definition: dynamic_types.h:30
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77
trilean dyn_get_bool_3(const dyn_c *dyn)
Returns the trinary truth value (DYN_TRUE|DYN_FALSE|DYN_NONE) of an element.
Definition: dynamic_op.c:509
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30