Copyright ã 1994 by Sean Luke

COWS
Protocols
COWS Version 1.4
May 29, 1994

One of the key parts to the COWS interpreter is the COWS protocols package, which is still in a state of flux, but I think fairly robust.  These protocols describe how interpreters communicate with libraries, with applications, and even with interpreters in other applications.

Controlling an Interpreter from an Application

The protocol LibraryControl describes the standard suite of methods a COWS-compliant interpreter should have to be controllable by a library:

- addLibraryFunction:(const char*) this_name
	selector: (SEL) this_selector
	target: this_target;			Adds a compliant library method
									to be registered as the function name 
									this_name.  See the next section about
									requirements of what these methods
									must look like.
									
- makeMeALibraryDelegate:sender	Adds sender to the list of
									library objects to be sent
									delegate messages.  See the
									InterpreterToLibraryDelegate
									method below.

- (BOOL) canPause;					Returns Yes if the interpreter
									in question can be pause.  If
									not, returns No.
									
- pauseInterpreting;				Pauses the interpreter.  This is not
									to be used in general situations, but
									only in special times when it's
									necessary to stop the interpreter
									temporarily until you can complete
									a COWS function call request by
									the interpreter.  This only has effect
									on background interpreters.
									
- resumeInterpreting;				Resumes the interpreter after pausing.
									If an interpreter was paused and
									resumed within the scope of the
									same method call, this resume method
									should be used.  After using this
									method, a COWS function call is
									expected to return a value like it
									normally does.  As an example, see
									the COWS System Library ("alert"
									COWS method).

- resumeInterpretingWithValue:(COWSStringNode*)this_value;
 									Resumes the interperpreter after
									pausing and returns a value from
									a COWS function call.  This is only to
									be used if the interpreter was paused
									after it requested a COWS function
									call, then the scope of the function
									left the called method (to allow for
									events to come in, for example),
									and then something new started up
									the interpreter.  As an example, see
									the COWS IPC Library.

Communicating with Libraries

The protocol InterpreterToLibrary describes the methods interpreters may call on libraries:

- loadLibrary:sender;				Instructs a library to start loading
									functions into the interpreter using
									addLibraryFunction:selector:target
									as described above.
									
In addition, each library function registered by the library is expected to comply with the following format:

- functionName: arg_list;

Where arg_list is always a COWSArgumentList of arguments the user's passing to the function.  The method is free to rip into the argument list (any nodes it pops it must free), but must not free the argument list object itself.  The method then should return a fresh COWSStringNode containing the function's return value.  The interpreter will free this node.  If the function needs to report an error, it can do so by placing an error message in this node, and setting the node to error using setError: (see COWSStringNode.h).

Informing a Library Delegate

The protocol InterpreterToLibraryDelegate describes the methods interpreters may call on libraries that have set themselves up as library delegates:

- interpreterDidStop:sender;		Tells a library that, for one reason or
									another, the interpreter has stopped
									interpreting a program.

- interpreterDidStart:sender;		Tells a library that, the interpreter has
									begun interpreting a program.

Informing a Delegate

When an interpreter has finished interpreting, it returns its answer to the application (or to a remote calling interpreter) through an assigned delegate.  InterpreterToDelegate describes the methods this delegate must have.  Libraries should not use this protocol but InterpreterToLibraryDelegate above.

- interpreterStarted:sender;		Tells the delegate that the interpreter
									has started interpreting.

- finishedInterpreting:
	(const char*)returnValue:(int)thisMessage:sender;									Tells the delegate that the interpreter
									stopped interpreting naturally, and 
									that its return value is returnValue.  
									thisMessage is currently unused.
									
- errorInterpreting:(int) thisError:(const char*)thisFunction:
	(int)thisPosition:(const char*)thisString:sender;									Tells the delegate that an error
									occured interpreting, and that the
									interpreter stopped interpreting
									unnaturally.  thisError is the
									error (error codes are in 
									COWSInterpreter.h).  thisFunction
									is the function body in which the error
									occured.  thisPosition is the position in
									the function where the error occured.
									thisString is usually the token in error,
									unless the error was a library error, in
									which case thisString is an error
									message from the library.
									
- interpreterStopped:sender;		Tells the delegate that the interpreter
									has, for one reason or another,
									stopped interpreting.  This message is
									always sent in addition to the two
									above.  If sent alone, this message
									indicates that the user cancelled the
									interpretation of a program, instead
									of the interpreter stopping naturally
									or due to error.

General Interpreter Control

The protocol InterpreterControl describes methods an application can use to control an interpreter in general.

- addLibrary:this_library;			Adds a compliant library.
									This tells the interperter to call
									the library's loadLibrary:sender
									method, which in turn repeatedly 
									calls...
	
- clearLibraryFunctions;			Clears all library functions.

- (int) setProgram:(const char*) this_string;
									Loads a user-specified program into
									the interpreter and breaks it up.  The
									interpreter returns an error code
									(see COWSInterpreter.h) if there's 
									an error in parsing through the
									program initially.  Even if the program
									loads properly, it may still have 
									syntax errors reported later.
									
- setDelegate:this_delegate;
- delegate;							Sets and queries for the delegate.

- setTempDelegate:this_delegate;
- tempDelegate;						Sets and queries for a temporary
									delegate seperate from the main
									delegate.  This should only be used
									by libraries that have paused an
									interpreter and need to know 
									special information.  Currently it's
									used only by the IPC libraries.  These
									two methods may soon disappear...be
									warned.

- interpretFunction:(const char*) this_name 
	arguments:(COWSArgumentList*)these_arguments;
									Interprets a function, passing it
									arguments.  This function must actually
									exist in the program or in some library,
									and the program must already have
									 been loaded with setProgram: above.
									 This is how users start COWS macros.
									 
- stopInterpreting;					Cancels the interpreter's current work.
									This could be connected to a big red
									CANCEL button in the application
									which the user can press...
									
- setLocked:(BOOL) yes_or_no;		Sets whether or not an interpreter is
									accessible by outside applications
									through, say, the IPC library.

- (BOOL) locked;					Returns YES if the interpreter is
									accessible by outside applications
									through the IPC library.
									
- (BOOL) working;					Returns YES if the interpreter is
									working on interpreting a function.
									
- (BOOL) running;					Returns YES if the interpreter is
									working on intepreting a function and
									hasn't been paused by a function
									temporarily.

- setForeground:(BOOL) yes_or_no;	Sets whether or not an interpreter is
									running in the foreground (is running
									modally).

- (BOOL) foreground;				Returns YES if the interpreter is
									running in the foreground (is running
									modally).

- printErrors:(BOOL) yes_or_no;	Sets whether or not an interpreter
									should print errors to stdout.

- (BOOL) printingErrors;			Returns YES if the interpreter is
									printing errors to stdout.

Inter-Process Communication

The protocol InterpreterIPC is used by the COWS IPC Library to communicate to other COWS IPC libraries and ultimately to other interpreters in other applications.  It is not actually used by interpreters themselves.

- (oneway void) sendFunction:(const char*) this_name;
									Starts up an interpreter in a remote
									application to perform some function.
									This method tells the remote
									interpreter that this interpreter will
									be pestering it for a return value, and
									that it should eventually return one.
									This message is considered 
									synchronous.
									
- (oneway void) sendOutFunction:(const char*) this_name;
									Starts up an interpreter in a remote
									application to perform some function.
									This method tells the remote
									interpreter that this interpreter does
									not expect or want a return value and
									will not ask for one.  It is sent 
									asynchronously.									
- (int) state;						Asks an interpreter for its current
									state.  The state should be one of three
									items:  
							COWSIPCLIBRARY_ARGSTATE_READY
									indicates that the interpreter is ready
									to accept a new request, or has
									finished a current request.
							COWSIPCLIBRARY_ARGSTATE_WORKING
									indicates that the interpreter is
									working on a request and should not
									be bothered.
							COWSIPCLIBRARY_ARGSTATE_ADDING
									indicates that the interpreter is
									adding arguments to a soon-to-be
									carried-out request and should not
									be bothered.
									
									If the remote interpreter cannot 
									respond, this method should time out.
									
- (const char*) result;			Asks a remote interpreter for a result.
									If the remote interpreter cannot 
									respond, this method should time out
									or return NULL.
									
- (BOOL) resultIsError;			Asks a remote interpreter if a given
									result is a return value or error
									message.
									
- addArgument:(const char*)this_argument;									Called from a remote application to
									begin loading arguments for an up-and-
									coming request (one of the two above).
									Arguments are added first-to-last.
									This method should return NULL.
									
- (BOOL) isForeground;				This should return whether or not your
									interpreter is running in a foreground
									(work-to-the-end) or background
									(event-driven) mode.