Rapicorn - Experimental UI Toolkit - Source Code 10.08.1
sinfeximpl.hh
Go to the documentation of this file.
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__ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines