|
Rapicorn - Experimental UI Toolkit - Source Code 10.08.1
|
00001 /* Rapicorn 00002 * Copyright (C) 2008 Tim Janik 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * A copy of the GNU Lesser General Public License should ship along 00015 * with this library; if not, see http://www.gnu.org/copyleft/. 00016 */ 00017 #ifndef __RAPICORN_SINFEX_IMPL_HH__ 00018 #define __RAPICORN_SINFEX_IMPL_HH__ 00019 00020 #include "sinfex.hh" 00021 #include <math.h> 00022 00023 namespace Rapicorn { 00024 00025 typedef enum { 00026 SINFEX_0, 00027 SINFEX_REAL, 00028 SINFEX_STRING, 00029 SINFEX_VARIABLE, 00030 SINFEX_ENTITY_VARIABLE, 00031 SINFEX_OR, 00032 SINFEX_AND, 00033 SINFEX_NOT, 00034 SINFEX_NEG, 00035 SINFEX_POS, 00036 SINFEX_ADD, 00037 SINFEX_SUB, 00038 SINFEX_MUL, 00039 SINFEX_DIV, 00040 SINFEX_POW, 00041 SINFEX_EQ, 00042 SINFEX_NE, 00043 SINFEX_LT, 00044 SINFEX_GT, 00045 SINFEX_LE, 00046 SINFEX_GE, 00047 SINFEX_ARG, 00048 SINFEX_FUNCTION, 00049 } SinfexOp; 00050 00051 class SinfexExpressionStack { 00052 uint *start; 00053 union { 00054 uint *up; 00055 char *cp; 00056 double *dp; 00057 } mark; 00058 void 00059 grow (uint free_bytes = 128) 00060 { 00061 uint size = start ? start[0] : 0; 00062 uint current = mark.cp - (char*) start; 00063 if (current + free_bytes > size) 00064 { 00065 const uint alignment = 256; 00066 size = (size + free_bytes + alignment - 1) / alignment; 00067 size *= alignment; 00068 start = (uint*) realloc (start, size); 00069 if (!start) 00070 fatal ("SinfexExpressionStack: out of memory (trying to allocate %u bytes)", size); 00071 mark.cp = current + (char*) start; 00072 start[0] = size; 00073 } 00074 } 00075 uint index () const { return mark.up - start; } 00076 void put_double (double d) { grow (sizeof (d)); *mark.dp++ = d; } 00077 void put_uint (uint u) { grow (sizeof (u)); *mark.up++ = u; } 00078 void 00079 put_string (String s) 00080 { 00081 uint l = s.size(); 00082 grow (sizeof (l) + l); 00083 *mark.up++ = l; 00084 memcpy (mark.cp, &s[0], l); 00085 mark.cp += l; 00086 while (ptrdiff_t (mark.cp) & 3) 00087 *mark.cp++ = 0; 00088 } 00089 public: 00090 SinfexExpressionStack () : 00091 start (NULL), mark () 00092 { 00093 mark.up = start; 00094 grow (sizeof (*mark.up)); 00095 mark.up++; // byte_size 00096 put_uint (0); // start offset 00097 } 00098 ~SinfexExpressionStack () 00099 { 00100 if (start) 00101 free (start); 00102 mark.up = start = NULL; 00103 } 00104 uint* startmem () const { return start; } 00105 uint push_or (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_OR); put_uint (ex1); put_uint (ex2); return ix; } 00106 uint push_and (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_AND); put_uint (ex1); put_uint (ex2); return ix; } 00107 uint push_not (uint ex1) { uint ix = index(); put_uint (SINFEX_NOT); put_uint (ex1); return ix; } 00108 uint push_neg (uint ex1) { uint ix = index(); put_uint (SINFEX_NEG); put_uint (ex1); return ix; } 00109 uint push_pos (uint ex1) { uint ix = index(); put_uint (SINFEX_POS); put_uint (ex1); return ix; } 00110 uint push_add (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_ADD); put_uint (ex1); put_uint (ex2); return ix; } 00111 uint push_sub (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_SUB); put_uint (ex1); put_uint (ex2); return ix; } 00112 uint push_mul (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_MUL); put_uint (ex1); put_uint (ex2); return ix; } 00113 uint push_div (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_DIV); put_uint (ex1); put_uint (ex2); return ix; } 00114 uint push_pow (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_POW); put_uint (ex1); put_uint (ex2); return ix; } 00115 uint push_eq (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_EQ); put_uint (ex1); put_uint (ex2); return ix; } 00116 uint push_ne (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_NE); put_uint (ex1); put_uint (ex2); return ix; } 00117 uint push_lt (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_LT); put_uint (ex1); put_uint (ex2); return ix; } 00118 uint push_gt (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_GT); put_uint (ex1); put_uint (ex2); return ix; } 00119 uint push_le (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_LE); put_uint (ex1); put_uint (ex2); return ix; } 00120 uint push_ge (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_GE); put_uint (ex1); put_uint (ex2); return ix; } 00121 uint push_arg (uint ex1, uint ex2) { uint ix = index(); put_uint (SINFEX_ARG); put_uint (ex1); put_uint (ex2); return ix; } 00122 uint push_double (double d) { uint ix = index(); put_uint (SINFEX_REAL); put_double (d); return ix; } 00123 uint push_string (const String &s) { uint ix = index(); put_uint (SINFEX_STRING); put_string (s); return ix; } 00124 uint push_variable (const String &name) { uint ix = index(); put_uint (SINFEX_VARIABLE); put_string (name); return ix; } 00125 uint 00126 push_entity_variable (const String &entity, 00127 const String &name) 00128 { uint ix = index(); 00129 put_uint (SINFEX_ENTITY_VARIABLE); 00130 put_string (entity); 00131 put_string (name); 00132 return ix; 00133 } 00134 uint 00135 push_func (const String &func_name, 00136 uint argx1) 00137 { uint ix = index(); 00138 put_uint (SINFEX_FUNCTION); 00139 put_uint (argx1); 00140 put_string (func_name); 00141 return ix; 00142 } 00143 void 00144 set_start (uint ex1) 00145 { 00146 assert (start[1] == 0); 00147 start[1] = ex1; 00148 } 00149 }; 00150 00151 } // Rapicorn 00152 00153 #endif /* __RAPICORN_SINFEX_IMPL_HH__ */
1.7.4