On 03.10.14 16:26, Stephen Dubovsky wrote:
  Somebody wrote:
> > There are plenty of ways to use goto that are clean and structured.
> > And every one of those ways is better done using if/else/endif or
> > while/endwhile or do/while instead of goto.

> Thats an awful absolute statement!  There are some cases where gotos are
> appropriate and FAR more clean then if/else/etc.  I write code for a living
> and have one particular case that is a nightmare to solve w/o one.  The
> LWIP stack uses them in a handful of places.  Clean and non-offensive.
> 
> I don't see why some are getting their panties in a wad over it.

<Chuckle>, ya need 4WD to go over or around densely wadded dogma.
Here is one of those cases you refer to, I think. The code is part of an
event-handling state machine, written in my own dialect resembling SDL,
and in this case is a snippet from a menu system which handles a 12-key
keyboard and a 2 x 16 character LCD, running on an ATmega328p. (A hacked
Arduino board)

The plot so far:
The event-drive OS delivers an incoming event to the current state, and
at state INDEX, we handle a keystroke of "1" or "2", which are used as
softkeys, aligning under the display's bottom line, currently showing
"By_Size By_N/rev", following a prior selection of "Index" at the higher
menu level.

It is worth remembering that in an SDL state machine, execution for an
event is called a "transition", and comprises one string of code,
without subroutines. (In this case, the code is a bunch of assembler
macros, so not particularly recognisable out of context.)

The "join IN1" is effectively a Goto, which makes 6 lines of code common
to the two modes. That's how the SDL language handles "transition"
merging. Admittedly, commercial tools do it graphically, with automated
code generation, so the Goto is just a line on the page, which makes it
immune to dogmatic attack.

state INDEX
   if_event 1                       ; "By_Size" (raw) mode.
      display indx_11 L1            ; indx_11 is "Hops  Size #=Ent"
IN1:  vst   mode event              ; Save mode, and use INDEX_HOPS for both.
      display prompt_1 L2           ; "            *=bs" (backspace)
      write_lcd control 0x0F        ; Set cursor blinking.
      place_cursor 0 L2             ; at start of line 2.
      send self First               ; Make stuff happen there, before
   next_state INDEX_HOPS            ; any external events.

   if_event 2                       ; "By_N/rev" mode.
      display indx_10 L1            ; "Hops N/rev #=Ent"
      delay 1000                    ; LCD ignores next line if we're too quick.
   join IN1
   
state INDEX_HOPS                    ; ACCU_DISP collects any keyed data entry, &
   if_event First                   ; sends a Return event to the calling state.
      vst   tmp zero_reg            ; Instance variable "tmp" = 0
   call_state ACCU_DISP
   ...

OK, it would have been possible to cook up a prettier artificial
example, but this code is running on the little Arduino board on the
corner of my desk at the moment, and I've just added the join while
adding the new mode, so it'll have to do as an example. Dogmatists
please note that it is 100% legit SDL to whiz off to merge into a
transition tail at another state, and that is in fact its most common
use in industry.

Why use such a state-based code architecture? Each event is handled with
extreme efficiency, delivered to the current state by the event-OS,
handled in a few lines of code, i.e. in microseconds, often. (All those
macros are in-line code, so no call/return overhead.) Each instance gets
a couple of negligible-overhead timers, eliminating the need for spin
delays, which cannot exist in a multi-threaded real-time environment.

And if you've used this stuff to control a turret, toolchanger, or other
gizmo, then later add a second one to the machine, it is only necessary
to change

   define_sm turret TURRET_INIT 1         to

   define_sm turret TURRET_INIT 2

and a second instance comes into existence, sharing the code, but with
private instance (thread) variables and instance ID. (Whoops, sorry,
this was just supposed to be a code example.)

Erik

P.S. The macros for the action "primitives" are a moving feast,
     hopefully improving in elegance over time, but even now providing a
     useful level of abstraction over the raw assembler underneath.

-- 
The surest way to corrupt a youth is to instruct him to hold in higher
regard those who think alike than those who think differently.
                                                            - Nietzsche

------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
Emc-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/emc-users

Reply via email to