Action Walkthrough, part 3

The discussion of how an Action works continues with a detailed list of Action start-up events. The example code for the Action under discussion is shown in the first article.

An Actor object is linked to an Action object. In a virtual sense, an Actor is an instance of an Action. (In a similar sense, Instance objects are instances of some Model object.) There can be many instances of Actor objects linked to one Action. Each Actor invokes the Action.

An Actor also has a clause parameters list with one or more clause objects. Each clause object is a list that begins with a clause name followed zero or more input parameters for that clause.

Sending a Message to an Actor object (which invokes its meta-object) causes the Actor to find its linked Action and invoke it, passing the clause parameters list. Upon return, the Actor pops the Action result off the stack and into a local TEMP object. Then it can apply its received Message to that result object.

In detail, the sequence goes like this:

1. The @hypot Actor receives a Q: message from the set: Message object, which is telling its parameter (the Actor object) to push a value onto the stack. This requires the Actor to invoke its linked Action to provide that value, so…

2. The Actor calls the invoke() method of the @hypot Action and passes in the clause parameters list. In this case, the list has a single clause object: ('hypot', address-1, address-2). (The addresses are of two constant *int objects.)

3. The @hypot Action starts by initializing its input and output objects. It does this by sending an X: message to each (Instance) object on its init-list. This causes each object to initialize and populate the Action Call Frame (CF) slot with a new data object.

4. Next the Action loops over its clause list, matching each clause against the input clause list. In this case, as with all single-clause Actions, there is a single match. The Action’s clause list, ('hypot', 2, @000C), matches the input clause object, ('hypot', address-1, address-2), so…

5. The Action copies the input parameters (address-1 and address-2) into the respective CF slots (which requires releasing the existing new values from step #3 above), and…

6. Invokes the clause’s execution list (located at @000C). It does this by sending an X: message to the List object, which…

7. Causes the List object to send the received X: message to each member, thus effectively “executing” that Action clause. Because of the X: message, no item executed from the List returns any object, nor does the List object.

8. The Action sees there are no more matches (in fact, no more input clause objects) to the clause. It also sees there are no more clauses, so execution is complete, therefore…

9. It pushes the object on the exit-list onto the stack and…

10. Cleans up the Call Frame (releasing any dynamic objects).

11. The Actor regains control and immediately pops the return object into its associated TEMP object (which moves the data object from the stack to the local CF).

12. The Actor sends its received message to the TEMP object.

In this case the Actor received a Q: message to apply to the returned object (which happens to be an Instance object). The Instance object behavior for a Q: message is to push its address onto the stack.

The end result is the local address of the Action’s result object on the stack and the data object of that result in the local CF. Presumably the set: Message object’s target will use the stack value.

Note an important distinction: The Action pushes the data object from its Call Frame to the stack. The Actor pops the data object into its own Call Frame in the slot allocated for the associated TEMP Instance object. But upon receiving the Q: message, the Instance object pushes its address onto the stack (rather than its data object). This behavior is particular to Actions.

The sequence of events described applies to how all Actors invoke their Actions. The only difference is the clause list. All single-clause Actions (which is most Actions) differ only in the number of input parameters.

In particular, the sequence of events above applies to how the @sqrt Action is invoked in the @hypot Action’s execution list. The next article describes the sequence of events for Message objects in that list.

%d bloggers like this: