IRP Execution Model

From JP1 Remotes
Revision as of 23:55, 27 September 2014 by The Robman (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Data structures

The dynamic aspect of the execution model processes the main bitspec and irstream of a protocol in a context set by the timer and carrier generator and certain parameters of fixed global scope. Since there can be further bitspecs and irstreams nested within the main irstream, the model uses stacks to keep track of which ones are current at any stage of the processing. The following data structures are used to model these various items.

STRUCT timer
BEGIN

clock: real-time clock counting microseconds;
now: the current time on the clock;
START: operation that sets clock to zero and starts it running;
STOP: operation that stops the clock;

END

STRUCT carrier generator
BEGIN

frequency: the frequency in kilohertz of the carrier square wave;
duty cycle: the duty cycle of the carrier square wave;
TRANSMIT FOR: an operation that turns on the carrier for a specified time;
WAIT FOR: an operation that waits with the carrier turned off for a specified time;

END

STRUCT global
BEGIN

sequencing rule: an enumerated value, either "lsb" or "msb", that specifies the manner in which binary forms are converted to bit sequences;
duration unit: the unit of time in microseconds in which durations and extents without a suffix are expressed;

END

STRUCT bitspec
BEGIN

(* The bitspec buffer performs the process of converting binary forms to bit sequences *)
N: the length of the bit sequences mapped by the bitspec;
buffer: a FIFO buffer of bits awaiting processing by the bitspec, initially empty; PUSH pushes a binary form into the buffer one bit at a time (conceptually into the right hand end) in the order given by the global sequencing rule, PULL pulls a timeordered bit sequence of N bits out one at a time (conceptually out of the left hand end), earliest bit first;
MAP: operation that maps bit sequences of length N to their corresponding bare irstreams;

END

STRUCT irstream
BEGIN

content: the bare irstream (a list of irstream items)
min count: the minimum number of times that the irstream should be executed, as specified by the repeat marker - in the case of a definite repeat number this is the actual number;
repeat flag: boolean that is false if the repeat marker gives a definite number and is true if the repeat marker gives only a minimum number;
bitspec flag: boolean specifying whether or not the irstream immediately follows a bitspec, set during parsing;
final flag: boolean that controls the ending of an indefinite repeat sequence, tested at the start of a potential repeat execution it the button is then no longer held - if this is false then that repeat is not performed, if it is true then that repeat is performed;
var3 flag: boolean that is set true during execution of an irstream if during that execution a variation is encountered that has three alternatives - used in the setting of the final flag;
skip flag: boolean specifying whether processing of the remainder of this irstream should be skipped, initially false - used in the processing of an empty alternative;
count: the number of transmissions currently made or in progress, initially zero
start time: a time value set when processing of the irstream starts

END

STRUCT <item> stack
BEGIN

stack: an ordered list of <item>, conceptually thought of as climbing upward
pointer: a pointer to a (possibly empty) position in the stack; INCREMENT moves the pointer up one position, DECREMENT moves it down one position
CREATE: an operation that creates an empty stack of <item> with pointer set to first (bottom) position;
DESTROY: an operation that deletes a stack, empty or otherwise;
INSERT INTO: a stack operation in which the <item>s at and beyond the pointer position are moved up one place, a specified new item is inserted at the pointer position and the pointer is then incremented;
DELETE FROM: a stack operation in which the pointer is decremented, the <item> at the pointer position is deleted and all <item>s beyond the pointer position are moved down one place;
current: the <item> one position lower than the pointer position (null if the pointer is at the bottom of the stack);
(* In normal circumstances <item>s will only be added and removed at the top of the stack, in which case INSERT INTO and DELETE FROM correspond to PUSH and PULL. Unless there have been explicit pointer increments or decrements the current <item> will then be the one at the top of the stack. The recursion allowed by IRP notation can however cause <item>s to be inserted part way up. *)

END

Evaluation

The static operation of EVALUATE was described in 14.1 Although evaluation is static in the sense that it is not concerned with the progress of time during execution, evaluations are perfomed in the context of the state of the environment at the time that the EVALUATE operation is called. Successive evaluations of the same item may therefore give different results.

Although the process of evaluation is described by the semantics of the item being evaluated, descriptions are given here for each item type on which EVALUATE can act.

EVALUATE number
BEGIN

RETURN value of the number as an integer in accordance with number semantics;

END

EVALUATE name
BEGIN

IF name is bound to a value THEN
RETURN value;
ELSE IF name is bound to an expression THEN
EVALUATE expression AS value;
RETURN value;
END IF;
(* A name that has not been bound explicitly will still return a value. The description of the persistence of the global environment in 14.1 explains how this can be used to model remotes with "state" where this internal state affects the execution of the protocol. *)

END

EVALUATE expression

Parse the expression in accordance with expression syntax;
EVALUATE each primary item in the parse tree according to its type;
Convert any binary form arising from a bitfield to its numerical value in accordance with expression semantics;
RETURN value given by performing the unary and binary operations in the parse tree in accordance with expression semantics;

END

EVALUATE duration
BEGIN

EVALUATE its name or number;
Convert value to a time period in microseconds in accordance with the duration suffix and the duration semantics in the context of the global duration unit and carrier generator frequency;
RETURN time period in microseconds;

END

EVALUATE extent
BEGIN

EVALUATE its name or number;
Convert value to a time period in microseconds in accordance with the extent suffix and the extent semantics in the context of the global duration unit and carrier generator frequency;
RETURN time period in microseconds;

END

EVALUATE bitfield
BEGIN

EVALUATE each primary item according to its type;
Convert bitfield to binary form in accordance with bitfield semantics;
RETURN binary form

END

Execution

As described in 14.1, execution processing is initiated by the pressing of a button on the conceptual remote control. By means outside the scope of IRP notation, this binds certain names to values in the global environment and sets the carrier generator duty cycle. It then initiates the procedure PROCESS protocol. This section describes the chain of processes that this initiates.

Processing of item types is specified in terms of their parsing by the EBNF syntax and the data structures that represent them in accordance with 14.2. In logical constructions, AND takes precedence over OR. The pronoun ITS is used to identify a part of the parsing structure or data structure of the item being processed, OF is used to identify a part of a different item. For example, the EBNF syntax for a bare irstream is

bare irstream = | irstream item, [",", bare irstream];

So in "PROCESS bare irstream", "IF bare irstream IS NOT EMPTY" refers to the bare irstream being processed (the one on the left of the syntax expression) but "PROCESS ITS bare irstream" refers to the one on the right. In the same context, "PROCESS buffer OF current bitspec" refers to a constituent of the data structure that represents the current bitspec, not to one of the bare irstream being processed. Comments have been made where there is potential ambiguity.

The processes of the execution model now follow.

PROCESS protocol
BEGIN

CREATE bitspec stack;
CREATE irstream stack;
PROCESS ITS generalspec;
PROCESS ITS definitions;
START clock;
PROCESS ITS bitspec;
PROCESS ITS irstream;
STOP clock;
(* The binding of names to values is preserved in the persistence of the environment but the binding of names to bare expressions produced by the processing of definitions is not preserved. *)
CLEAR ITS definitions;
DESTROY irstream stack;
DESTROY bitspec stack;

END

PROCESS generalspec
BEGIN

SET carrier generator frequency FROM ITS frequency item;
SET global duration unit FROM ITS unit item;
SET global sequencing rule FROM ITS order item;

END

PROCESS definitions
BEGIN

PROCESS ITS definitions list;

END

PROCESS definitions list
BEGIN

IF definitions list IS NOT EMPTY THEN
PROCESS ITS (* first *) definition;
UNLESS ABSENT PROCESS ITS (* remaining *) definitions list;
END IF

END

PROCESS definition
BEGIN

BIND ITS name TO ITS bare expression;

END

PROCESS bitspec
BEGIN

INSERT bitspec INTO bitspec stack;

END

PROCESS irstream
BEGIN

INSERT irstream INTO irstream stack;
SET ITS final flag = FALSE;
SET ITS count = 0;
DO WHILE ITS count < ITS min count OR (ITS repeat flag IS TRUE AND
(button still held OR ITS final flag IS TRUE))
SET ITS var3 flag = FALSE;
SET ITS skip flag = FALSE;
INCREMENT ITS count;
SET ITS start time = now;
(* Evaluate content in current environment settings *)
PROCESS ITS bare irstream;
(* Treat end of bare irstream like item that is not a bitfield *)
PROCESS buffer OF current bitspec;
IF NOT (ITS repeat flag IS TRUE AND button still held)
(* this could never be known in advance to be final *)
IF (ITS var3 flag IS TRUE OR ITS count EQUALS (ITS min count - 1) )
AND ITS final flag IS FALSE THEN
(* next execution needed and known to be final *)
SET ITS final flag = TRUE;
ELSE
(* current execution was final, whether this was known when it started or not *)
SET ITS final flag = FALSE;
END IF;
END IF;
END DO;
IF ITS bitspec flag IS TRUE THEN
(* We have finished with the bitspec that preceded this irstream *)
DELETE FROM bitspec stack;
END IF
DELETE FROM irstream stack;

END

PROCESS bare irstream
BEGIN

IF skip flag OF current irstream IS FALSE AND bare irstream IS NOT EMPTY THEN
(* Process first item *)
IF ITS irstream item IS NOT bitfield THEN
PROCESS buffer OF current bitspec;
END IF;
PROCESS ITS irstream item;
(* Process the remaining items - if skip flag has just been set then this will be skipped due to the conditional at the start of this process *)
UNLESS ABSENT PROCESS ITS bare irstream;
END IF
(* If the remaining bare irstream is absent, so we have completed the processing, it seems we should process bitspec buffer, treating the end of the recursion as an item other than a bare irstream, but this would be wrong as another bare irstream may follow, starting with a bitfield whose bits need to be concatenated with any left over here. We defer any final processing of the bitspec buffer till the end of the enclosing irstream. *)

END

PROCESS irstream item
BEGIN

IF irstream item IS duration THEN
EVALUATE duration AS time period;
IF duration IS flash duration THEN
TRANSMIT FOR time period;
ELSE (* duration is gap duration *)
WAIT FOR time period;
END IF;
ELSE IF irstream item IS extent THEN
EVALUATE extent AS time period;
IF now < (start time OF current irstream) + time period THEN
WAIT UNTIL now = (start time OF current irstream) + time period;
END IF;
ELSE IF irstream item IS bitfield THEN
EVALUATE bitfield AS binary form;
IF current bitspec IS NULL THEN
ERROR;
ELSE
PUSH binary form INTO buffer OF current bitspec;
END IF;
ELSE IF irstream item IS assignment THEN
EVALUATE ITS expression AS value;
BIND ITS name TO value;
ELSE IF irstream item IS variation THEN
IF number of alternatives in variation IS 3 THEN
SET var3 flag OF current irstream = TRUE;
END IF;
IF count OF current irstream IS 1 THEN
PROCESS ITS first alternative;
ELSE IF ITS third alternative IS PRESENT AND final flag OF current irstream IS TRUE THEN
PROCESS ITS third alternative;
ELSE
PROCESS second alternative;
END IF;
ELSE IF irstream item IS bitspec THEN
PROCESS irstream item AS bitspec;
ELSE IF irstream item IS irstream THEN
PROCESS irstream item AS irstream;
END IF;

END

PROCESS alternative
BEGIN

IF ITS bare irstream IS EMPTY THEN
SET skip flag OF current irstream = TRUE;
ELSE
PROCESS ITS bare irstream
END IF

END

PROCESS buffer
BEGIN

(* This buffer is in scope of previous bitspec, if any *)
IF buffer IS NOT EMPTY THEN
DECREMENT bitspec stack pointer;
DO WHILE number of bits in buffer >= N
PULL bit sequence FROM buffer;
MAP bit sequence TO bare irstream;
PROCESS bare irstream;
END DO;
(* The current bitspec now was the previous bitspec on entry *)
IF current bitspec IS NOT NULL THEN
(* if an attempt has been made to push bits into its buffer, it will already have generated an error *)
PROCESS buffer OF current bitspec;
END IF;
IF number of bits in buffer <> 0 THEN
(* Consecutive bit sequences have been concatenated by processing of bare irstream so if any bits are left over, it is an error. *)
ERROR;
END IF;
(* Finished with the new current bitspec, restore the old one *)
INCREMENT bitspec stack pointer;
END IF;

END;

CLEAR definitions
BEGIN

CLEAR ITS definitions list;

END

CLEAR definitions list
BEGIN

IF definitions list IS NOT EMPTY THEN
CLEAR ITS (* first *) definition;
UNLESS ABSENT CLEAR ITS (* remaining *) definitions list;
END IF;

END

Personal tools
Namespaces

Variants
Actions
Navigation
Tools