#ifndef PROCESS_H #define PROCESS_H #pragma interface #include "value.h" #include "Structures.h" #include "storage.h" #include "tokentable.h" #include "Scheduler.h" /******************************************************************* pictorally, this structure looks like this: | Process --> Frame --> Frame --> Frame | A Process has a bunch of stored frames from each of the objects that have been called and not exited from yet. Each frame represents process control moving to a different object. *********************************************************************/ const Value* anon_nm = new Value (new String ("an anonymous method")); class lvarstack : public SymVal_List { public: Value* assign (String* s, Value* v); }; class Frame { friend class Process; friend class Value; friend class Scheduler; public: Frame(int obj_on , Value* mthd_nm , Val_List* actuals , Process* process_ptr , Frame* prev = NULL , Value* method_val = NULL); ~Frame(); int do_operation (); /** returns the number of ticks it took **/ int try_operation (); int expression_depth () {return expression_stack.depth;} protected: Value_Stack data_stack; /** for storing evaluated values **/ Value_Stack expression_stack; /** holds the expressions being evaluated **/ SymVal_List local_vars; /** a list of all local variables. **/ Value_Stack method_names; intlist ignore_list; /** stores error codes to ignore **/ intlist method_on; int this_obj; /** the object number this frame is running on **/ Frame* previous; /** pointer to frame waiting for this one **/ Process* proc; /** points to root level process structure **/ int exprpop(); void push_method (Value* mthd_nm = anon_nm); void pop_method (); void returned_val (Value*); void dump_state (); /** for debugging **/ int check_error_raise (Value* errnum, String* msg = NULL); int transfer_to_data(); /** transfers a value from expr --> data **/ Value* lookup (Value*); /** looks up that variable name **/ int handle_reserved (); void dump_local_vars(); int assert_type (Value*, Value_Type); int is_handling_error (int err_code, Value* err_string); /******* prototypes for operators: *********/ op_EQ(); op_LT(); op_GT(); op_MOD(); op_DIV(); op_SUB(); op_ADD(); op_MUL(); op_SET(); op_NOT(); op_OR(); op_AND(); op_INDEX(); op_RANGE(); op_TONUM(); op_TOREAL(); op_TOSTR(); op_TOOBJ(); op_TIME(); op_RANDOM(); op_LENGTH(); op_INSERT(); op_CRYPT(); op_IF(); op_DOTIMES(); op_FOREACH(); op_WHILE(); op_PASS(); op_PASS_TO(); op_SLEEP(); op_FORK(); op_KILL(); op_ECHO_CMD(); op_SETPARENTS(); op_VAR(); op_RMVAR(); op_ADDCMD(); op_RMCMD(); op_MATCHCMD(); op_CALL(); op_METHOD(); op_COMMANDS(); op_VARS(); op_CLONE(); op_DISCONNECT(); op_RECONNECT(); op_SHUTDOWN(); op_RETURN(); op_BEGIN_CMD(); op_TOERROR(); op_TOLIST(); op_IGNORE(); op_COMPILE(); op_SEARCH(); op_PARENTS(); op_EXPLODE(); op_PURGECMDS(); op_CAR(); op_CDR(); op_CONS(); op_TOSYM(); op_AFTER(); op_BEFORE(); op_QUOTE(); op_EVAL(); op_TYPEOF(); op_FILETEXT(); op_RUNSCRIPT(); op_CLASS(); op_SQRT(); op_REGSPLIT(); op_CONNOUT(); op_HANDLE(); op_SEMAPHORE(); op_ADDRESS(); op_GTE(); op_LTE(); op_FORMAT(); op_IMPLODE(); op_SETS(); op_NUM2CHAR(); op_CHAR2NUM(); op_COLLECT(); op_MATCHONE(); op_LOG(); }; #define MAX_DEPTH 2500 // the greatest expression depth allowed ... to // prevent runaway recursion. class Process { friend class Frame; friend class Scheduler; protected: int process_id; int sleeping_til; int ticks_left; int player_obj; Frame* active_frame; String last_error_msg; Value* last_error; void add_sleeping (int); public: Process (int obj_on , int pid , Value* mthd_nm , int ticks , Val_List* actuals); ~Process (); int give_ticks (int tick_slice); }; #endif /* PROCESS_H */