00001 // 00002 // protos/express.h 00003 // 00004 // Copyright (c) 2008-2009, Mike Austin 00005 // All rights reserved. 00006 // 00007 00008 #ifndef _IMPULSE_EXPRESS_H_ 00009 #define _IMPULSE_EXPRESS_H_ 00010 00011 #include "array.h" 00012 00013 namespace impulse { 00014 00015 // 00016 // class Block 00017 // 00018 // A block is a lexically scoped, deferred execution block of code, or closure. A block takes 00019 // the current execution context and arguments for the block as arguments. 00020 // 00021 00022 // 00023 // class Express 00024 // 00025 00026 class Express : public Frame { 00027 00028 public: 00029 00030 // Constructors 00031 00032 Express() { } 00033 Express( Express& parent ) : _parent( &parent ) { } 00034 00035 // Runtime overrides 00036 00037 Value eval( Array& args, Value self ); 00038 00039 string inspect() { return "[Express]"; } 00040 00041 Value invoke( Array& args, Value self ); 00042 00043 void push( Value value ) { _code2.push( value ); } 00044 void clear() { _code2.clear(); } 00045 00046 Express& parent() { return *_parent; } 00047 00048 private: 00049 00050 Array _code2; 00051 Express* _parent; 00052 00053 }; 00054 00055 // 00056 // class Express 00057 // 00058 00059 Value Express::eval( Array& args, Value self ) 00060 { 00061 Value result = -1.0; 00062 00063 BEG( "Express::eval()" ); 00064 00065 result = invoke( args, self ); 00066 00067 END( "" ); 00068 00069 return result; 00070 } 00071 00072 00073 Value Express::invoke( Array& args, Value self ) 00074 { 00075 Value* ip = _code2.data(); 00076 Value* end = _code2.data() + _code2.size(); 00077 Value value = self; 00078 00079 Array margs( self ); 00080 00081 while (ip < end) 00082 { 00083 value = ip++->eval( margs, value ); 00084 } 00085 00086 return value; 00087 } 00088 00089 } 00090 00091 #endif