Rapicorn - Experimental UI Toolkit - Source Code
13.07.0
|
00001 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html 00002 #ifndef __RAPICORN_SINFEX_IMPL_HH__ 00003 #define __RAPICORN_SINFEX_IMPL_HH__ 00004 00005 #include "sinfex.hh" 00006 #include <math.h> 00007 00008 namespace Rapicorn { 00009 00010 typedef enum { 00011 SINFEX_0, 00012 SINFEX_REAL, 00013 SINFEX_STRING, 00014 SINFEX_VARIABLE, 00015 SINFEX_ENTITY_VARIABLE, 00016 SINFEX_OR, 00017 SINFEX_AND, 00018 SINFEX_NOT, 00019 SINFEX_NEG, 00020 SINFEX_POS, 00021 SINFEX_ADD, 00022 SINFEX_SUB, 00023 SINFEX_MUL, 00024 SINFEX_DIV, 00025 SINFEX_POW, 00026 SINFEX_EQ, 00027 SINFEX_NE, 00028 SINFEX_LT, 00029 SINFEX_GT, 00030 SINFEX_LE, 00031 SINFEX_GE, 00032 SINFEX_ARG, 00033 SINFEX_FUNCTION, 00034 } SinfexOp; 00035 00036 class SinfexExpressionStack { 00037 uint *start; 00038 union { 00039 uint *up; 00040 char *cp; 00041 double *dp; 00042 } mark; 00043 void 00044 grow (uint free_bytes = 128) 00045 { 00046 uint size = start ? start[0] : 0; 00047 uint current = mark.cp - (char*) start; 00048 if (current + free_bytes > size) 00049 { 00050 const uint alignment = 256; 00051 size = (size + free_bytes + alignment - 1) / alignment; 00052 size *= alignment; 00053 start = (uint*) realloc (start, size); 00054 if (!start) 00055 fatal ("SinfexExpressionStack: out of memory (trying to allocate %u bytes)", size); 00056 mark.cp = current + (char*) start; 00057 start[0] = size; 00058 } 00059 } 00060 uint index () const { return mark.up - start; } 00061 void put_double (double d) { grow (sizeof (d)); *mark.dp++ = d; } 00062 void put_uint (uint u) { grow (sizeof (u)); *mark.up++ = u; } 00063 void 00064 put_string (String s) 00065 { 00066 uint l = s.size(); 00067 grow (sizeof (l) + l); 00068 *mark.up++ = l; 00069 memcpy (mark.cp, &s[0], l); 00070 mark.cp += l; 00071 while (ptrdiff_t (mark.cp) & 3) 00072 *mark.cp++ = 0; 00073 } 00074 public: 00075 SinfexExpressionStack () : 00076 start (NULL), mark () 00077 { 00078 mark.up = start; 00079 grow (sizeof (*mark.up)); 00080 mark.up++; // byte_size 00081 put_uint (0); // start offset 00082 } 00083 ~SinfexExpressionStack () 00084 { 00085 if (start) 00086 free (start); 00087 mark.up = start = NULL; 00088 } 00089 uint* startmem () const { return start; } 00090 uint push_or (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_OR); put_uint (ex1); put_uint (ex2); return ix; } 00091 uint push_and (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_AND); put_uint (ex1); put_uint (ex2); return ix; } 00092 uint push_not (uint ex1) { uint ix = index(); put_uint (SINFEX_NOT); put_uint (ex1); return ix; } 00093 uint push_neg (uint ex1) { uint ix = index(); put_uint (SINFEX_NEG); put_uint (ex1); return ix; } 00094 uint push_pos (uint ex1) { uint ix = index(); put_uint (SINFEX_POS); put_uint (ex1); return ix; } 00095 uint push_add (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_ADD); put_uint (ex1); put_uint (ex2); return ix; } 00096 uint push_sub (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_SUB); put_uint (ex1); put_uint (ex2); return ix; } 00097 uint push_mul (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_MUL); put_uint (ex1); put_uint (ex2); return ix; } 00098 uint push_div (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_DIV); put_uint (ex1); put_uint (ex2); return ix; } 00099 uint push_pow (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_POW); put_uint (ex1); put_uint (ex2); return ix; } 00100 uint push_eq (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_EQ); put_uint (ex1); put_uint (ex2); return ix; } 00101 uint push_ne (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_NE); put_uint (ex1); put_uint (ex2); return ix; } 00102 uint push_lt (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_LT); put_uint (ex1); put_uint (ex2); return ix; } 00103 uint push_gt (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_GT); put_uint (ex1); put_uint (ex2); return ix; } 00104 uint push_le (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_LE); put_uint (ex1); put_uint (ex2); return ix; } 00105 uint push_ge (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_GE); put_uint (ex1); put_uint (ex2); return ix; } 00106 uint push_arg (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_ARG); put_uint (ex1); put_uint (ex2); return ix; } 00107 uint push_double (double d) { uint ix = index(); put_uint (SINFEX_REAL); put_double (d); return ix; } 00108 uint push_string (const String &s) { uint ix = index(); put_uint (SINFEX_STRING); put_string (s); return ix; } 00109 uint push_variable (const String &name) { uint ix = index(); put_uint (SINFEX_VARIABLE); put_string (name); return ix; } 00110 uint 00111 push_entity_variable (const String &entity, 00112 const String &name) 00113 { uint ix = index(); 00114 put_uint (SINFEX_ENTITY_VARIABLE); 00115 put_string (entity); 00116 put_string (name); 00117 return ix; 00118 } 00119 uint 00120 push_func (const String &func_name, 00121 uint argx1) 00122 { uint ix = index(); 00123 put_uint (SINFEX_FUNCTION); 00124 put_uint (argx1); 00125 put_string (func_name); 00126 return ix; 00127 } 00128 void 00129 set_start (uint ex1) 00130 { 00131 assert (start[1] == 0); 00132 start[1] = ex1; 00133 } 00134 }; 00135 00136 } // Rapicorn 00137 00138 #endif /* __RAPICORN_SINFEX_IMPL_HH__ */