dynamiC  0.1
dynamic_op.c
Go to the documentation of this file.
1 
15 #include "dynamic.h"
16 
17 #define max_type(A, B) (DYN_TYPE(A) > DYN_TYPE(B)) ? DYN_TYPE(A) : DYN_TYPE(B)
18 
19 #define CHECK_COPY_REFERENCE(X1) \
20  if (DYN_TYPE(X1) == REFERENCE2) \
21  DYN_TYPE(X1) = REFERENCE; \
22  if(DYN_TYPE(X1) == REFERENCE) \
23  dyn_copy(X1->data.ref, X1); \
24 
25 #define CHECK_NOCOPY_REFERENCE(X2) \
26  if(DYN_IS_REFERENCE(X2)) \
27  X2=X2->data.ref; \
28 
29 
30 #define CHECK_REFERENCE(X1, X2) \
31  CHECK_COPY_REFERENCE(X1) \
32  CHECK_NOCOPY_REFERENCE(X2)
33 
34 
35 static dyn_ushort search (const dyn_c *container, dyn_c *element)
36 {
37  dyn_ushort i = 0;
38 
39  switch (DYN_TYPE(container)) {
40  case DICT: {
41  dyn_str key = dyn_get_string(element);
42  i = dyn_dict_has_key(container, key);
43  free(key);
44  return i;
45  }
46  case SET:
47  case LIST: {
48  dyn_c tmp;
49  DYN_INIT(&tmp);
50  for (; i<DYN_LIST_LEN(container); ++i) {
51  dyn_set_ref(&tmp, DYN_LIST_GET_REF(container, i));
52  dyn_op_id(&tmp, element);
53 
54  if (dyn_get_bool(&tmp))
55  return ++i;
56  }
57  }
58  }
59 
60  return 0;
61 }
62 
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 }
92 
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 }
198 
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 }
255 
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 }
345 
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 }
376 
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 }
403 
417 float fast_approx_pow (float x, float p)
418 {
419  union { float f;
420  unsigned int i;
421  } vx = { x };
422 
423  union { unsigned int i;
424  float f;
425  } mx = { (vx.i & 0x007FFFFF) | 0x3f000000 };
426 
427  x = vx.i * 1.1920928955078125e-7f
428  - 124.22551499f
429  - 1.498030302f * mx.f
430  - 1.72587999f / (0.3520887068f + mx.f);
431 
432  x *= p;
433 
434  float offset = (x < 0) ? 1.0f : 0.0f;
435  float clipp = (x < -126) ? -126.0f : x;
436  float z = clipp - (int) clipp + offset;
437  mx.i = (unsigned int) ( (1 << 23) * (clipp + 121.2740575f + 27.7280233f / (4.84252568f - z) - 1.49012907f * z) );
438 
439  return mx.f;
440 }
441 
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 }
500 
510 {
511  if(DYN_IS_REFERENCE(dyn))
512  dyn=dyn->data.ref;
513 
514  return (DYN_IS_NONE(dyn) || DYN_TYPE(dyn) == FUNCTION) ? DYN_NONE : dyn_get_bool(dyn);
515 }
516 
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 }
556 
582 trilean dyn_op_or (dyn_c* dyn1, dyn_c* dyn2)
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 }
596 
597 
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 }
635 
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 }
667 
684 {
685  enum{EQ,LT,GT,NEQ,TYPE,MARK};//0,1,2,3,4
686 
687  dyn_c *tmp = DYN_IS_REFERENCE(dyn1) ? dyn1->data.ref : dyn1;
688  dyn_char ret;
689  dyn_c tmp2;
690  DYN_INIT(&tmp2);
691  dyn_ushort i;
692 
693  if(DYN_IS_REFERENCE(dyn2))
694  dyn2=dyn2->data.ref;
695 
696  if (DYN_IS_NONE(tmp) && DYN_IS_NONE(dyn2))
697  goto GOTO_EQ;
698 
699  if (DYN_IS_NONE(tmp) && DYN_NOT_NONE(dyn2))
700  goto GOTO_LT;
701 
702  if (DYN_NOT_NONE(tmp) && DYN_IS_NONE(dyn2))
703  goto GOTO_GT;
704 
705  //this switch has no breaks goto is used to leave to desired return
706  switch (max_type(tmp, dyn2)) {
707  case BOOL:
708  if (dyn_get_bool(tmp) < dyn_get_bool(dyn2))
709  goto GOTO_LT;
710  if (dyn_get_bool(tmp) > dyn_get_bool(dyn2))
711  goto GOTO_GT;
712  goto GOTO_EQ;
713  case INTEGER:
714  if (dyn_get_int(tmp) < dyn_get_int(dyn2))
715  goto GOTO_LT;
716  if (dyn_get_int(tmp) > dyn_get_int(dyn2))
717  goto GOTO_GT;
718  goto GOTO_EQ;
719  case FLOAT:
720  if (dyn_get_float(tmp) < dyn_get_float(dyn2))
721  goto GOTO_LT;
722  if (dyn_get_float(tmp) > dyn_get_float(dyn2))
723  goto GOTO_GT;
724  goto GOTO_EQ;
725  case STRING: {
726  if (DYN_TYPE(tmp) != DYN_TYPE(dyn2))
727  goto GOTO_TYPE;
728  //i = dyn_strcmp(tmp->data.str, dyn2->data.str);
729  //if (i < 0)
730  ret = dyn_strcmp(tmp->data.str, dyn2->data.str);
731  if (ret < 0)
732  goto GOTO_LT;
733  //if (i > 0)
734  if (ret > 0)
735  goto GOTO_GT;
736  goto GOTO_EQ;
737  }
738  case SET: {
739  if (DYN_TYPE(tmp) != DYN_TYPE(dyn2))
740  goto GOTO_TYPE;
741  {
742  dyn_c * lset = NULL;
743  dyn_c * rset;
744  if (DYN_LIST_LEN(tmp) == DYN_LIST_LEN(dyn2)){
745  // list might be EQ
746  ret = EQ;
747  lset = tmp;
748  rset = dyn2;
749  } else if (DYN_LIST_LEN(tmp) < DYN_LIST_LEN(dyn2)) {
750  // list might be EQ
751  ret = LT;
752  lset = tmp;
753  rset = dyn2;
754  } else /*if (DYN_LIST_LEN(tmp) > DYN_LIST_LEN(dyn2)) */{
755  // list might be GT
756  ret = GT;
757  lset = dyn2;
758  rset = tmp;
759  }
760  //check if all elements of lset are in rset
761  //break to NEQ or complete to confirm
762  for (i=0; i<DYN_LIST_LEN(lset); ++i) {
763  dyn_set_ref(&tmp2, DYN_LIST_GET_REF(lset, i));
764  dyn_op_in(&tmp2, rset);
765  if (!dyn_get_bool(&tmp2)){
766  ret = NEQ;
767  break;
768  }
769 
770  }
771  goto GOTO_RET;
772 
773  }
774  //unreachable
775  }
776  case LIST: {
777  if (DYN_TYPE(tmp) != DYN_TYPE(dyn2))
778  goto GOTO_TYPE;
779  if (DYN_LIST_LEN(tmp) < DYN_LIST_LEN(dyn2))
780  goto GOTO_LT;
781  if (DYN_LIST_LEN(tmp) > DYN_LIST_LEN(dyn2))
782  goto GOTO_GT;
783  if (DYN_LIST_LEN(tmp) == DYN_LIST_LEN(dyn2)) {
784  if (DYN_LIST_LEN(tmp) == 0)
785  goto GOTO_EQ;
786 
787  //put marker into return value
788  ret = MARK;
789  for (i=0; i<DYN_LIST_LEN(tmp); ++i) {
790  dyn_set_ref(&tmp2, DYN_LIST_GET_REF(tmp, i));
791  ret = dyn_op_cmp(&tmp2, DYN_LIST_GET_REF(dyn2, i));
792  if (ret != EQ)
793  break;
794  }
795  //reached the end of the for loop
796  goto GOTO_RET;
797  }
798  //unreachable
799  }
800  }
801  //unreachable
802  // break with diffent type (string, list and set)
803  goto GOTO_TYPE;
804 GOTO_TYPE:
805  ret = TYPE;
806  goto GOTO_RET;
807 
808 GOTO_EQ:
809  ret = EQ;
810  goto GOTO_RET;
811 GOTO_LT:
812  ret = LT;
813  goto GOTO_RET;
814 GOTO_GT:
815  ret = GT;
816  goto GOTO_RET;
817 /*
818 GOTO_NEQ:
819  ret = NEQ;
820  goto GOTO_RET;
821 */
822 GOTO_RET:
823  //dyn_set_int(dyn1, ret);
824  return ret;
825 
826 }
827 
834 trilean dyn_op_id (dyn_c* dyn1, dyn_c* dyn2)
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 }
843 
850 trilean dyn_op_eq (dyn_c* dyn1, dyn_c* dyn2)
851 {
852  dyn_set_bool(dyn1, dyn_op_cmp(dyn1, dyn2)
853  ? DYN_FALSE
854  : DYN_TRUE);
855  return DYN_TRUE;
856 }
857 
864 trilean dyn_op_ne (dyn_c* dyn1, dyn_c* dyn2)
865 {
866  dyn_set_bool(dyn1, dyn_op_cmp(dyn1, dyn2)
867  ? DYN_TRUE
868  : DYN_FALSE);
869  return DYN_TRUE;
870 }
871 
878 trilean dyn_op_lt (dyn_c* dyn1, dyn_c* dyn2)
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 }
891 
898 trilean dyn_op_ge (dyn_c* dyn1, dyn_c* dyn2)
899 {
900  dyn_op_lt(dyn1, dyn2);
901  dyn_op_not(dyn1); // NONE remains NONE
902 
903  return DYN_TRUE;
904 }
905 
912 trilean dyn_op_gt (dyn_c* dyn1, dyn_c* dyn2)
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 }
925 
932 trilean dyn_op_le (dyn_c* dyn1, dyn_c* dyn2)
933 {
934  dyn_op_gt(dyn1, dyn2);
935  dyn_op_not(dyn1); // NONE remains NONE
936 
937  return DYN_TRUE;
938 }
939 
949 trilean dyn_op_in (dyn_c *element, dyn_c *container)
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 }
967 
968 
970 {
971  if (DYN_TYPE(dyn) == REFERENCE2)
972  DYN_TYPE(dyn) = REFERENCE;
973 
974  if(DYN_TYPE(dyn) == REFERENCE)
975  dyn_copy(dyn->data.ref, dyn);
976 
977  if (DYN_TYPE(dyn)==INTEGER) {
978  dyn->data.i = ~dyn->data.i;
979  return DYN_TRUE;
980  }
981 
982  dyn_free(dyn);
983  return DYN_FALSE;
984 }
985 
986 
988 {
989  CHECK_REFERENCE(dyn1, dyn2)
990 
991  if (DYN_TYPE(dyn1)==INTEGER && DYN_TYPE(dyn2)==INTEGER) {
992  dyn1->data.i = dyn1->data.i & dyn2->data.i;
993  return DYN_TRUE;
994  }
995 
996  dyn_free(dyn1);
997  return DYN_FALSE;
998 }
999 
1001 {
1002  CHECK_REFERENCE(dyn1, dyn2)
1003 
1004  if (DYN_TYPE(dyn1)==INTEGER && DYN_TYPE(dyn2)==INTEGER) {
1005  dyn1->data.i = dyn1->data.i | dyn2->data.i;
1006  return DYN_TRUE;
1007  }
1008 
1009  dyn_free(dyn1);
1010  return DYN_FALSE;
1011 }
1012 
1013 
1015 {
1016  CHECK_REFERENCE(dyn1, dyn2)
1017 
1018  if (DYN_TYPE(dyn1)==INTEGER && DYN_TYPE(dyn2)==INTEGER) {
1019  dyn1->data.i ^= dyn2->data.i;
1020  return DYN_TRUE;
1021  }
1022 
1023  dyn_free(dyn1);
1024  return DYN_FALSE;
1025 }
1026 
1027 
1029 {
1030  CHECK_REFERENCE(dyn1, dyn2)
1031 
1032  if (DYN_TYPE(dyn1)==INTEGER && DYN_TYPE(dyn2)==INTEGER) {
1033  dyn1->data.i <<= dyn2->data.i;
1034  return DYN_TRUE;
1035  }
1036 
1037  dyn_free(dyn1);
1038  return DYN_FALSE;
1039 }
1040 
1042 {
1043  CHECK_REFERENCE(dyn1, dyn2)
1044 
1045  if (DYN_TYPE(dyn1)==INTEGER && DYN_TYPE(dyn2)==INTEGER) {
1046  dyn1->data.i >>= dyn2->data.i;
1047  return DYN_TRUE;
1048  }
1049 
1050  dyn_free(dyn1);
1051  return DYN_FALSE;
1052 }
dyn_c * ref
reference pointer to dynamic elements
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
trilean dyn_op_le(dyn_c *dyn1, dyn_c *dyn2)
Relational Less Than or Equal.
Definition: dynamic_op.c:932
dyn_float dyn_get_float(const dyn_c *dyn)
Return float value of a dynamic element.
trilean dyn_op_ge(dyn_c *dyn1, dyn_c *dyn2)
Relational Greater Than or Equal.
Definition: dynamic_op.c:898
dictionary of type dyn_dict
Definition: dynamic_types.h:69
trilean dyn_op_b_not(dyn_c *dyn)
Binary complement.
Definition: dynamic_op.c:969
trilean dyn_op_b_shift_r(dyn_c *dyn1, dyn_c *dyn2)
Binary shift right.
Definition: dynamic_op.c:1041
dyn_ushort dyn_strlen(dyn_const_str str)
Returns the length of an string.
trilean dyn_op_id(dyn_c *dyn1, dyn_c *dyn2)
Type and Value Equality.
Definition: dynamic_op.c:834
trilean dyn_list_remove(dyn_c *list, dyn_ushort i)
Delete the ith element from a list.
Definition: dynamic_list.c:172
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_IS_REFERENCE(dyn)
Check if dynamic element is of type REFERENCE.
Definition: dynamic.h:46
dyn_char b
boolean value
dyn_c* for internal usage only
Definition: dynamic_types.h:73
#define DYN_LIST_LEN(dyn)
Return list length.
Definition: dynamic.h:123
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
dyn_ushort dyn_dict_has_key(const dyn_c *dict, dyn_const_str key)
Check if dict has key and return its position - 1 (returns 0 if not found)
Definition: dynamic_dict.c:145
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
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.
Dynamic data types as part of the SelectScript-VM implementation.
trilean dyn_op_in(dyn_c *element, dyn_c *container)
Check if dyn2 is element of dyn1.
Definition: dynamic_op.c:949
set of type dyn_list
Definition: dynamic_types.h:68
#define DYN_NOT_NONE(dyn)
Check if dynamic element is not of type NONE.
Definition: dynamic.h:44
trilean dyn_op_mod(dyn_c *dyn1, dyn_c *dyn2)
dyn1 Modulo dyn2
Definition: dynamic_op.c:388
#define DYN_INIT(dyn)
Mandatory initialization for dynamic elements (NONE)
Definition: dynamic.h:38
trilean dyn_op_or(dyn_c *dyn1, dyn_c *dyn2)
Logical (trinary) OR operation.
Definition: dynamic_op.c:582
function pointer of type dyn_fct
Definition: dynamic_types.h:71
trilean dyn_op_eq(dyn_c *dyn1, dyn_c *dyn2)
Relational Equality.
Definition: dynamic_op.c:850
#define DYN_LIST_GET_REF(dyn, i)
Return the reference to the ith element within a dynamic list.
Definition: dynamic.h:125
trilean dyn_op_add(dyn_c *dyn1, dyn_c *dyn2)
Add dyn2 to dyn1.
Definition: dynamic_op.c:124
represents a third unknown state, which is not true or false
Definition: dynamic_types.h:25
Boolean 0==False, 1==True.
Definition: dynamic_types.h:62
trilean dyn_op_neg(dyn_c *dyn)
Negate dynamic value in param dyn.
Definition: dynamic_op.c:72
float fast_approx_pow(float x, float p)
Power function approximation x^y.
Definition: dynamic_op.c:417
dyn_str dyn_get_string(const dyn_c *dyn)
Return string representation value of a dynamic element.
trilean dyn_op_and(dyn_c *dyn1, dyn_c *dyn2)
Logical (trinary) AND operation.
Definition: dynamic_op.c:542
trilean dyn_get_bool(const dyn_c *dyn)
Return boolean value of an dynamic element.
Definition: dynamic.c:241
trilean dyn_op_ne(dyn_c *dyn1, dyn_c *dyn2)
Relational Not Equal.
Definition: dynamic_op.c:864
#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
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
#define DYN_DICT_LEN(dyn)
Return number of elements within a dictionary.
Definition: dynamic.h:188
trilean dyn_op_b_xor(dyn_c *dyn1, dyn_c *dyn2)
Binary XOR.
Definition: dynamic_op.c:1014
signed integer 32 bit
Definition: dynamic_types.h:64
char*
Definition: dynamic_types.h:66
trilean dyn_op_div(dyn_c *dyn1, dyn_c *dyn2)
Divide dyn1 by dyn2.
Definition: dynamic_op.c:356
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.
dyn_float f
float value
Definition: dynamic_types.h:60
None type without any value.
Definition: dynamic_types.h:61
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_c*, explicite reference
Definition: dynamic_types.h:74
TYPE
Basic data type definitions.
Definition: dynamic_types.h:60
dyn_c * container
pointer to an array of dynamic elements
Definition: dynamic_types.h:58
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.
trilean dyn_op_not(dyn_c *dyn)
Logical (trinary) Negation.
Definition: dynamic_op.c:658
trilean dyn_op_pow(dyn_c *dyn1, dyn_c *dyn2)
dyn1 to the power of dyn2
Definition: dynamic_op.c:453
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
trilean dyn_op_gt(dyn_c *dyn1, dyn_c *dyn2)
Relational Greater Than.
Definition: dynamic_op.c:912
dyn_int i
basic integer
dyn_str * key
array to C strings used as identifiers
Definition: dynamic_types.h:56
trilean dyn_op_lt(dyn_c *dyn1, dyn_c *dyn2)
Relational Less Than.
Definition: dynamic_op.c:878
trilean
basic return type for truth values
Definition: dynamic_types.h:22
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
trilean dyn_op_b_shift_l(dyn_c *dyn1, dyn_c *dyn2)
Binary shift left.
Definition: dynamic_op.c:1028
dyn_char dyn_strcmp(dyn_const_str a, dyn_const_str b)
Compares the string a to the string b.
trilean dyn_op_b_or(dyn_c *dyn1, dyn_c *dyn2)
Binary OR.
Definition: dynamic_op.c:1000
void dyn_set_ref(dyn_c *ref, dyn_c *orig)
Set dynamic element as reference to another dynamic element.
Definition: dynamic.c:149
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
trilean dyn_op_sub(dyn_c *dyn1, dyn_c *dyn2)
Subtract dyn2 from dyn1.
Definition: dynamic_op.c:211
trilean dyn_list_resize(dyn_c *list, const dyn_ushort size)
Change the maximal space of a list.
Definition: dynamic_list.c:91
trilean dyn_op_xor(dyn_c *dyn1, dyn_c *dyn2)
Logical (trinary) XOR operation.
Definition: dynamic_op.c:623
trilean dyn_op_mul(dyn_c *dyn1, dyn_c *dyn2)
Multiply dyn1 with dyn2.
Definition: dynamic_op.c:271
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
trilean dyn_op_b_and(dyn_c *dyn1, dyn_c *dyn2)
Binary AND.
Definition: dynamic_op.c:987
dyn_char dyn_op_cmp(dyn_c *dyn1, dyn_c *dyn2)
Common compare function for dynamic elements.
Definition: dynamic_op.c:683
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
Basic container for dynamic data types.
Definition: dynamic_types.h:98