muse_opcodes.h

Go to the documentation of this file.
00001 
00013 #ifndef __MUSE_OPCODES_H__
00014 #define __MUSE_OPCODES_H__
00015 
00016 #ifndef __MUSE_H__
00017 #include "muse.h"
00018 #endif
00019 
00020 BEGIN_MUSE_C_FUNCTIONS
00021 
00027 typedef longlong_t muse_int_cell;
00028 
00032 typedef double muse_float_cell;
00033 
00041 typedef struct { muse_cell head, tail; } muse_cons_cell;
00042 
00051 typedef struct { muse_nativefn_t fn; void *context; }   muse_nativefn_cell;
00052 
00062 typedef struct { muse_char *start, *end; }  muse_text_cell;
00063 
00076 typedef union
00077 {
00078     muse_int_cell       i;
00079     muse_float_cell     f;
00080     muse_cons_cell      cons;
00081     muse_nativefn_cell  fn;
00082     muse_text_cell      text;
00083 } muse_cell_data;
00084 
00091 typedef struct 
00092 {
00093     int size;           
00094     muse_cell *bottom;  
00095     muse_cell *top;     
00097 } muse_stack;
00098 
00103 typedef struct
00104 {
00105     int                 size_cells; 
00106     muse_cell_data      *cells;     
00107     unsigned char       *marks;     
00112     muse_cell           free_cells;     
00113     int                 free_cell_count; 
00116 } muse_heap;
00117 
00124 struct _muse_env
00125 {
00126     muse_heap           heap;
00127     muse_stack          stack;
00128     muse_stack          symbol_stack;
00129     int                 num_symbols;
00130     muse_stack          bindings_stack;
00140     muse_cell           specials;
00141     muse_cell           *builtin_symbols;
00142     int                 *parameters;
00143     void                *stack_base;
00144 };
00145 
00146 extern muse_env *g_muse_env;
00147 extern const char *g_muse_typenames[];
00148 
00149 static inline muse_env *_env() 
00150 { 
00151     return g_muse_env; 
00152 }
00153 
00158 static inline muse_cell _t()
00159 {
00160     return _env()->builtin_symbols[MUSE_T];
00161 }
00162 
00168 static inline muse_cell _celli( muse_cell cell ) 
00169 { 
00170     return cell >> 3; 
00171 }
00172 
00177 static inline muse_cell _cellati( int i )
00178 {
00179     return i << 3;
00180 }
00181 
00187 static inline muse_cell_t _cellt( muse_cell cell ) 
00188 { 
00189     return (muse_cell_t)(cell & 7); 
00190 }
00191 static inline const char *_typename( muse_cell cell )
00192 {
00193     return g_muse_typenames[_cellt(cell)];
00194 }
00195 static inline muse_boolean _isnumbert( int cell_t )
00196 {
00197     return (cell_t == MUSE_INT_CELL || cell_t == MUSE_FLOAT_CELL) ? MUSE_TRUE : MUSE_FALSE;
00198 }
00199 static inline muse_boolean _isnumber( muse_cell cell )
00200 {
00201     return _isnumbert(_cellt(cell));
00202 }
00203 static inline muse_boolean _isfn( muse_cell cell )
00204 {
00205     int t = _cellt(cell);
00206     return (t == MUSE_NATIVEFN_CELL || t == MUSE_LAMBDA_CELL) ? MUSE_TRUE : MUSE_FALSE;
00207 }
00208 static inline muse_boolean _isquote( muse_cell cell )
00209 {
00210     return (cell == _env()->builtin_symbols[MUSE_QUOTE]) ? MUSE_TRUE : MUSE_FALSE;
00211 }
00212 static inline muse_cell _setcellt( muse_cell cell, muse_cell_t t ) 
00213 { 
00214     return (muse_cell)((cell & ~7) | t); 
00215 }
00216 static inline muse_cell_data *_ptr( muse_cell cell )
00217 {
00218     muse_assert( cell >= 0 );
00219     muse_assert( _celli(cell) < _env()->heap.size_cells );
00220     return _env()->heap.cells + _celli(cell);
00221 }
00222 static inline muse_functional_object_t *_fnobjdata( muse_cell c )
00223 {
00224     if ( _cellt(c) == MUSE_NATIVEFN_CELL )
00225     {
00226         muse_functional_object_t *d = (muse_functional_object_t*)_ptr(c)->fn.context;
00227         if ( d && d->magic_word == 'muSE' )
00228             return d;
00229     }
00230 
00231     return NULL;
00232 }
00233 static inline muse_int _intvalue( muse_cell c )
00234 {
00235     switch ( _cellt(c) )
00236     {
00237         case MUSE_INT_CELL : return _ptr(c)->i;
00238         case MUSE_FLOAT_CELL : return (muse_int)_ptr(c)->f;
00239         default : return 0;
00240     }
00241 }
00242 static inline muse_float _floatvalue( muse_cell c )
00243 {
00244     switch ( _cellt(c) )
00245     {
00246         case MUSE_INT_CELL : return (muse_float)_ptr(c)->i;
00247         case MUSE_FLOAT_CELL : return _ptr(c)->f;
00248         default : return 0.0;
00249     }
00250 }
00251 static inline muse_heap *_heap()
00252 {
00253     return &_env()->heap;
00254 }
00255 static inline muse_stack *_stack()
00256 {
00257     return &_env()->stack;
00258 }
00259 static inline muse_cell _spush( muse_cell cell )
00260 {
00261     if ( cell )
00262     {
00263         muse_assert( _env()->stack.top - _env()->stack.bottom < _env()->stack.size );
00264         muse_assert( _celli(cell) >= 0 && _celli(cell) < _env()->heap.size_cells );
00265         return *(_env()->stack.top++) = cell;
00266     }
00267     else
00268         return MUSE_NIL;
00269 }
00270 static inline int _spos()
00271 {
00272     return (int)(_env()->stack.top - _env()->stack.bottom);
00273 }
00274 static inline void _unwind( int stack_pos )
00275 {
00276     _env()->stack.top = _env()->stack.bottom + stack_pos;
00277 }
00278 static inline muse_stack *_symstack()
00279 {
00280     return &_env()->symbol_stack;
00281 }
00282 static inline muse_cell _head( muse_cell c )
00283 {
00284     muse_assert( _cellt(c) == MUSE_CONS_CELL || _cellt(c) == MUSE_SYMBOL_CELL || _cellt(c) == MUSE_LAMBDA_CELL );
00285     return _ptr(c)->cons.head;
00286 }
00287 static inline muse_cell _tail( muse_cell c )
00288 {
00289     muse_assert( _cellt(c) == MUSE_CONS_CELL || _cellt(c) == MUSE_SYMBOL_CELL || _cellt(c) == MUSE_LAMBDA_CELL );
00290     return _ptr(c)->cons.tail;
00291 }
00292 static inline muse_cell _symname( muse_cell sym )
00293 {
00294     return _tail(_head(_tail(sym)));
00295 }
00296 static inline muse_cell _step( muse_cell *c )
00297 {
00298     muse_cell _c = *c;
00299     (*c) = _tail(*c);
00300     return _c;
00301 }
00302 static inline muse_cell _next( muse_cell *c )
00303 {
00304     return _head(_step(c));
00305 }
00306 static inline void _lpush( muse_cell h, muse_cell *l )
00307 {
00308     _ptr(h)->cons.tail = *l;
00309     (*l) = h;
00310 }
00311 static inline void _seth( muse_cell c, muse_cell h )
00312 {
00313     muse_assert( _cellt(c) == MUSE_CONS_CELL || _cellt(c) == MUSE_SYMBOL_CELL || _cellt(c) == MUSE_LAMBDA_CELL );
00314     muse_assert( h < 0 || _celli(h) < _env()->heap.size_cells );
00315     _ptr(c)->cons.head = h;
00316 }
00317 static inline void _sett( muse_cell c, muse_cell t )
00318 {
00319     muse_assert( _cellt(c) == MUSE_CONS_CELL || _cellt(c) == MUSE_SYMBOL_CELL || _cellt(c) == MUSE_LAMBDA_CELL );
00320     muse_assert( t < 0 || _celli(t) < _env()->heap.size_cells );
00321     _ptr(c)->cons.tail = t;
00322 }
00323 static inline void _setht( muse_cell c, muse_cell h, muse_cell t )
00324 {
00325     muse_cell_data *p = _ptr(c);
00326     muse_assert( _cellt(c) == MUSE_CONS_CELL || _cellt(c) == MUSE_SYMBOL_CELL || _cellt(c) == MUSE_LAMBDA_CELL );
00327     p->cons.head = h;
00328     p->cons.tail = t;
00329 }
00330 static inline muse_cell _def( muse_cell symbol, muse_cell value )
00331 {
00332     _seth(symbol,value);
00333     return value;
00334 }
00335 static inline muse_cell _symval( muse_cell symbol )
00336 {
00337     return _head(symbol);
00338 }
00339 static inline int _bspos()
00340 {
00341     return (int)(_env()->bindings_stack.top - _env()->bindings_stack.bottom);
00342 }
00343 static inline void _push_binding( muse_cell symbol )
00344 {
00345     muse_stack *s = &_env()->bindings_stack;
00346     muse_assert( s->top - s->bottom < s->size - 1 );
00347     *(s->top++) = symbol;
00348     *(s->top++) = _symval(symbol);
00349 }
00350 static inline void _unwind_bindings( int pos )
00351 {
00352     muse_stack *s = &_env()->bindings_stack;
00353     muse_assert( pos >= 0 && pos <= s->top - s->bottom );
00354 
00355     {
00356         muse_cell *p = s->bottom + pos;
00357         while ( s->top > p )
00358         {
00359             s->top -= 2;
00360             _def( s->top[0], s->top[1] );
00361         }
00362     }
00363 }
00364 static inline void _mark( muse_cell c )
00365 {
00366     int ci = _celli(c);
00367     unsigned char *m = _heap()->marks + (ci >> 3);
00368     muse_assert( ci >= 0 && ci < _heap()->size_cells );
00369     (*m) |= (1 << (ci & 7));
00370 }
00371 static inline void _unmark( muse_cell c )
00372 {
00373     int ci = _celli(c);
00374     unsigned char *m = _heap()->marks + (ci >> 3);
00375     muse_assert( ci >= 0 && ci < _heap()->size_cells );
00376     (*m) &= ~(1 << (ci & 7));
00377 }
00378 static inline int _ismarked( muse_cell c )
00379 {
00380     int ci = _celli(c);
00381     const unsigned char *m = _heap()->marks + (ci >> 3);
00382     muse_assert( ci >= 0 && ci < _heap()->size_cells );
00383     return (*m) & (1 << (ci & 7));
00384 }
00385 static inline int _iscompound( muse_cell c )
00386 {
00387     return _cellt(c) < MUSE_NATIVEFN_CELL;
00388 }
00389 static inline muse_cell _takefreecell()
00390 {
00391     muse_cell c;
00392     c = _step( &(_env()->heap.free_cells) );
00393     _sett(c,MUSE_NIL);
00394     _env()->heap.free_cell_count--;
00395     return c;
00396 }
00397 static inline void _returncell( muse_cell c )
00398 {
00399     muse_cell *f = &_env()->heap.free_cells;
00400     _setht(c, MUSE_NIL, *f);
00401     (*f) = c;
00402     _env()->heap.free_cell_count++;
00403 }
00404 static inline muse_cell _qq( muse_cell c )
00405 {
00406     return c > 0 ? -c : c;
00407 }
00408 static inline muse_cell _quq( muse_cell c )
00409 {
00410     return c < 0 ? -c : c;
00411 }
00412 
00413 END_MUSE_C_FUNCTIONS
00414 
00415 #endif /* __MUSE_OPCODES_H__ */

Generated on Mon Sep 25 23:12:47 2006 for muSE by  doxygen 1.4.7