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