Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
09/02/07 08:49
Modified:
  09/02/07 09:08

Read: times


 
Msg Score: +1
 +1 Informative
#143884 - Good topic!
Responding to: ???'s previous message
I'd say that the most valuable programming techniques are the really fundamental and universal ones that a lot of us take for granted these days and don't really think about too much. We just use them.

I'm talking about techniques like functional decomposition, which lets us tackle overwhelming problems by breaking them down into manageable pieces. Another biggie is the 40-year old idea of structured programming, which seems to have done a fairly good job of constraining the amount of spaghetti code in the world. (Except in 8052.com weekend quizzes, of course.)

My favorite technique that's more along the lines of what Erik has suggested is that of encoding a program's logic in its data rather than in its procedures. The trick is to invent a table that somehow describes what you want to happen, and then build a short interpreter that reads the table and does what it says. This lets you express your solution in terms more closely related to the problem, and often results in a more compact program than you would get otherwise. One of the old Bell Labs UNIX gurus, Jon Bentley, discusses this idea in detail in one of his books--it's either Programming Pearls or More Programming Pearls: Confessions of a Coder, I can't remember which. (What, you haven't read these books yet? Do so! They're great.)

As it turns out, a really good example of this technique is the implementation of a state machine! Very often, you see a state machine coded procedurally, with its logic specified by nested switch statements, something like this
state = STATE_1;                                // Initialize state variable
while (1) {                                     // Run forever
    event = GetNextEvent();
    switch (state) {
        case STATE_1:                           // STATE_1
            switch (event) {
                case EVENT_1:
                    DoSomething();
                    state = STATE_1;
                    break;
                case EVENT_2:
                    DoSomethingElse();
                    state = STATE_2;
                    break;
                case EVENT_3:
                    DoNothing();
                    state = STATE_3;
                    break;
                }
            break;                              // End STATE_1
        case STATE_2:                           // STATE_2
            switch (event) {
                case EVENT_1:
                    DoSomethingExotic();
                    state = STATE_3;
                    break;
                case EVENT_2:
                    DoSomethingEsoterik();
                    state = STATE_3;
                    break;
                case EVENT_3:
                    EatDirtAndDie();
                    state = STATE_1;
                    break;
                }
            break;                              // End STATE_2
        case STATE_3:                           // STATE_3
            switch (event) {
                case EVENT_1:
                    Etc();
                    state = STATE_1;
                    break;
                case EVENT_2:
                    EtcEtc();
                    state = STATE_1;
                    break;
                case EVENT_3:
                    EtcEtcEtc();
                    state = STATE_2;
                    break;
                }
            break;                              // End STATE_3
        }
    }                                           // End 'run forever'

This is already pretty nasty, and it can get a lot worse if you need a lot of different states and/or a lot of events. I think it works a lot better to specify the state machine in a table, something like this:
typedef struct {
    void (*pEventHandler)();
    int nextState;
    } CEventInfo;

typedef struct {
    CEventInfo events[NUMBER_OF_EVENTS];
    } CStateInfo;

CStateInfo stateTable[] = {
    {{DoSomething,              STATE_1},
     {DoSomethingElse,          STATE_2},
     {DoNothing,                STATE_3}},
    {{DoSomethingExotic,        STATE_3},
     {DoSomethingEsoterik,      STATE_3},
     {EatDirtAndDie,            STATE_1}},
    {{Etc,                      STATE_1},
     {EtcEtc,                   STATE_1},
     {EatEtcEtc,                STATE_2}}};

With a table like that in place, then, the "engine" that runs the state machine can be just a few lines long:
state = STATE_1;                                // Initialize state variable
while (1) {                                     // Run forever
    event = GetNextEvent();
    (*stateTable[state].events[event].pEventHandler)();
    state = stateTable[state].events[event].nextState;
    }                                           // End 'run forever'

-- Russ

PS: Please regard the above as C-like pseudocode, and not as ready-to-run code. I haven't tried to compile or run any of it.



List of 62 messages in thread
TopicAuthorDate
weekend survey            01/01/70 00:00      
   1. programming through the whole night            01/01/70 00:00      
   two things at once            01/01/70 00:00      
      not entirely correct            01/01/70 00:00      
   I'm afraid, but...            01/01/70 00:00      
      stealing codes?            01/01/70 00:00      
         A lesson learned by many            01/01/70 00:00      
         They are way faster...            01/01/70 00:00      
            sounds like a bitter experience            01/01/70 00:00      
   3)Math            01/01/70 00:00      
      0) Math            01/01/70 00:00      
   I have to agree with Erik            01/01/70 00:00      
   For hardware design(VHDL)            01/01/70 00:00      
      then, throw out the crap            01/01/70 00:00      
   Math, experience, tools and code libraries            01/01/70 00:00      
   Why?            01/01/70 00:00      
      tradeoffs            01/01/70 00:00      
         Well said, but not what I asked            01/01/70 00:00      
            different question            01/01/70 00:00      
               technique v tool            01/01/70 00:00      
      two reasons            01/01/70 00:00      
         valuation            01/01/70 00:00      
            that's a given, but            01/01/70 00:00      
            Lookup tables are good for lots of stuff            01/01/70 00:00      
   Good topic!            01/01/70 00:00      
      common tool, but            01/01/70 00:00      
         Function Pointers on the 8051            01/01/70 00:00      
            table-driven whatever and function pointers            01/01/70 00:00      
               reduce a task to its basic elements            01/01/70 00:00      
                  Good idea, bad example            01/01/70 00:00      
                     I didn't really want to use 805x instructions            01/01/70 00:00      
                        I can\'t find my old, (t)rusty 65C02 cheatsheet...            01/01/70 00:00      
                           Only the Rockwell version had it            01/01/70 00:00      
                              Oh, mea culpa...            01/01/70 00:00      
                        A very simple example would be helpful            01/01/70 00:00      
                           let\\\'s start at your end            01/01/70 00:00      
                              Here's what's confusing            01/01/70 00:00      
                                 FAQ?            01/01/70 00:00      
                                 Yes, you're quite right ... ... Mea culpa            01/01/70 00:00      
                  inconsistent instruction set            01/01/70 00:00      
                     I ask you, seriously, to inform us            01/01/70 00:00      
                        a few things            01/01/70 00:00      
                           so much \'fun\' with ajmp            01/01/70 00:00      
                              I give up            01/01/70 00:00      
                                 the answer            01/01/70 00:00      
                           My intuition            01/01/70 00:00      
                              mhm            01/01/70 00:00      
      to russ            01/01/70 00:00      
         to erik            01/01/70 00:00      
            to Russ            01/01/70 00:00      
               to Erik            01/01/70 00:00      
               To Erik            01/01/70 00:00      
                  WOW, a companion CD            01/01/70 00:00      
   the bad ideas            01/01/70 00:00      
      Anachronism?            01/01/70 00:00      
         he's certainly not a HW guy...            01/01/70 00:00      
      Hardware protection slated            01/01/70 00:00      
         this is an academic view...            01/01/70 00:00      
            Proving correctness            01/01/70 00:00      
   Why state machine / lookup tables?            01/01/70 00:00      
      Not to disagree ... but ...            01/01/70 00:00      
         A good reference            01/01/70 00:00      

Back to Subject List