list/dictionary as case statement ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Stef Mientki

    #1

    list/dictionary as case statement ?


    If I'm not mistaken, I read somewhere that you can use
    function-names/references in lists and/or dictionaries, but now I can't
    find it anymore.

    The idea is to build a simulator for some kind of micro controller (just
    as a general practise, I expect it too be very slow ;-).

    opcodes ={
    1: ('MOV', function1, ...),
    2: ('ADD', function2, ),
    3: ('MUL', class3.function 3, )
    }

    def function1
    # do something complex


    Is this possible ?

    thanks,
    Stef Mientki
  • Grant Edwards

    #2
    Re: list/dictionary as case statement ?

    On 2007-01-02, Stef Mientki <S.Mientki-nospam@mailbox. kun.nlwrote:
    If I'm not mistaken, I read somewhere that you can use
    function-names/references in lists and/or dictionaries, but
    now I can't find it anymore.
    >
    The idea is to build a simulator for some kind of micro
    controller (just as a general practise, I expect it too be
    very slow ;-).
    >
    opcodes ={
    1: ('MOV', function1, ...),
    2: ('ADD', function2, ),
    3: ('MUL', class3.function 3, )
    }
    >
    def function1
    # do something complex
    >
    >
    Is this possible ?
    Yes.

    What you're implementing is commonly referred to as a
    "dispatcher ", and they're often done with a dictionary exactly
    as you show.

    --
    Grant Edwards grante Yow! I guess you guys got
    at BIG MUSCLES from doing too
    visi.com much STUDYING!

    Comment

    • Gary Herron

      #3
      Re: list/dictionary as case statement ?

      Stef Mientki wrote:
      If I'm not mistaken, I read somewhere that you can use
      function-names/references in lists and/or dictionaries, but now I can't
      find it anymore.
      >
      The idea is to build a simulator for some kind of micro controller (just
      as a general practise, I expect it too be very slow ;-).
      >
      opcodes ={
      1: ('MOV', function1, ...),
      2: ('ADD', function2, ),
      3: ('MUL', class3.function 3, )
      }
      >
      def function1
      # do something complex
      >
      >
      Is this possible ?
      >
      thanks,
      Stef Mientki
      >
      Yes. Functions are (so called) first class objects. You can refer to one
      by name, and pass that reference around in variables and other data
      structures.

      That said, your code above won't work as written because function1 is
      not in existence when you refer to it.

      Here's some working code which manipulates a reference to a function
      then calls it:
      >>def fn():
      .... print "Hello world!"
      ....
      >>x = fn
      >>y = [fn,fn]
      >>z = {1:fn, 2:fn}
      >>>
      >>x()
      Hello world!
      >>y[0]()
      Hello world!
      >>y[1]()
      Hello world!
      >>z[1]()
      Hello world!
      >>z[2]()
      Hello world!
      >>>
      Gary Herron


      Comment

      • Stef Mientki

        #4
        Re: list/dictionary as case statement ?

        >
        Yes. Functions are (so called) first class objects. You can refer to one
        by name, and pass that reference around in variables and other data
        structures.
        >
        That said, your code above won't work as written because function1 is
        not in existence when you refer to it.
        >
        Yes, I just found that out.

        Thanks Gary and Grant,
        this principle really works like a charm.

        cheers,
        Stef Mientki

        Comment

        • Bruno Desthuilliers

          #5
          Re: list/dictionary as case statement ?

          Stef Mientki a écrit :
          >
          If I'm not mistaken, I read somewhere that you can use
          function-names/references in lists and/or dictionaries,
          Python's functions are objects too - instances of the (builtin) class
          'function'. So yes, you can use them like any other object (store them
          in containers, pass them as arguments, return them from functions etc).

          but now I can't
          find it anymore.
          >
          The idea is to build a simulator for some kind of micro controller (just
          as a general practise, I expect it too be very slow ;-).
          >
          opcodes ={
          1: ('MOV', function1, ...),
          2: ('ADD', function2, ),
          3: ('MUL', class3.function 3, )
          }
          >
          def function1
          # do something complex
          >
          >
          Is this possible ?
          Why don't you just try ?

          def mov(what, where):
          print "mov() called with %s : %s" % (what, where)

          def add(what, towhat):
          print "add() called with %s : %s" % (what, towhat)


          opcodes = {
          1: ('MOV', mov),
          2: ('ADD', add),
          }

          opcodes[1][1](42, 'somewhere')
          opcodes[2][1](11, 38)

          The third example is a bit less straightforward . Unless class3.function 3
          is a classmethod or staticmethod, you'll need an instance of class3,
          either before constructing the 'opcodes' dict or when actually doing the
          call.

          class SomeClass(objec t):
          def some_method(sel f):
          print "some_metho d called, self : %s" % self

          some_obj = SomeClass()

          opcodes[3] = ('MUL', some_obj.some_m ethod)
          opcodes[3][1]()

          FWIW, using a dict of callables is a common Python idiom to replace the
          switch statement.

          HTH

          Comment

          • Hendrik van Rooyen

            #6
            Re: list/dictionary as case statement ?

            "Stef Mientki" <S.Mientki-nospam@mailbox. kun.nlwrote:
            >
            If I'm not mistaken, I read somewhere that you can use
            function-names/references in lists and/or dictionaries, but now I can't
            find it anymore.
            >
            The idea is to build a simulator for some kind of micro controller (just
            as a general practise, I expect it too be very slow ;-).
            >
            opcodes ={
            1: ('MOV', function1, ...),
            2: ('ADD', function2, ),
            3: ('MUL', class3.function 3, )
            }
            >
            def function1
            # do something complex
            >
            >
            Is this possible ?
            the short answer is : "Yes"

            a slightly longer answer depends on what you want to do

            If you want to write a simple assembler, your dict will look something like:

            Mnemonics_to_Op codes =
            {"MOV": [Functionnamefor opcodeandtwoope rands,movopcode],
            "NOP":[Functionnamefor opcodeonly,nopo pcode],
            "SETB":[Functionnamefor opcodeandoneope rand,setbopcode],
            "JMP":[Functionnamefor opcodeandoneope rand,jmpopcode],
            ....
            }

            if you want to write a simulator only that "executes" the hex or binary,
            then your dict needs to be something like this:

            Opcodes =
            {movopcode:[MovFunction,mov instructionlen],
            nopopcod:[NopFunction,nop instructionlen],
            setbopcode:[SetbFunction,se tbinstructionle n],
            jmpopcode:[JmpFunction,jmp instructionlen],
            ....
            }

            and then you write an "instructio n fetcher" based on the
            Program Counter that uses the length data in the dict and
            calls the various functions with the operands as fetched from
            memory. The easiest is to make the PC a global...

            It works well - and it is surprisingly fast too...
            And its easy if the opcodes are all say one byte,
            else you need an opcode length field too, and fancier
            parsing.

            This is not the hassle with this kind of thing - the hassle comes
            in trying to simulate the behaviour of the I/O of a real system...

            hth - Hendrik


            Comment

            • Tom Plunket

              #7
              Re: list/dictionary as case statement ?

              Hendrik van Rooyen wrote:
              It works well - and it is surprisingly fast too...
              And its easy if the opcodes are all say one byte,
              else you need an opcode length field too, and fancier
              parsing.
              Often (always?) RISC architectures' instruction+ope rand lengths are
              fixed to the word size of the machine. E.g. the MIPS 3000 and 4000 were
              32 bits for every instruction, and PC was always a multiple of four.
              ....which means the parsing is pretty straight forward, but as you say,
              simulating the rest of the machine is the hard part.


              -tom!

              --

              Comment

              • Bjoern Schliessmann

                #8
                Re: list/dictionary as case statement ?

                Tom Plunket wrote:
                Often (always?) RISC architectures' instruction+ope rand lengths
                are fixed to the word size of the machine. E.g. the MIPS 3000 and
                4000 were 32 bits for every instruction, and PC was always a
                ^^
                multiple of four.
                Intels aren't RISC, are they?

                But for PowerPC it's the same, every instruction has 32 bit.

                Regards,


                Björn

                --
                BOFH excuse #278:

                The Dilithium Crystals need to be rotated.

                Comment

                • Tom Plunket

                  #9
                  Re: list/dictionary as case statement ?

                  Bjoern Schliessmann wrote:
                  Intels aren't RISC, are they?
                  Not the ones in PCs. The OP didn't specify the CPU that's being used,
                  however.


                  -tom!

                  --

                  Comment

                  • MRAB

                    #10
                    Re: list/dictionary as case statement ?


                    Bjoern Schliessmann wrote:
                    Tom Plunket wrote:
                    >
                    Often (always?) RISC architectures' instruction+ope rand lengths
                    are fixed to the word size of the machine. E.g. the MIPS 3000 and
                    4000 were 32 bits for every instruction, and PC was always a
                    ^^
                    multiple of four.
                    >
                    Intels aren't RISC, are they?
                    >
                    I think that "PC" referred to the CPU's Program Counter.

                    The x86 CPUs if typical Windows PCs aren't RISC but Intel also
                    manufacture X-Scale (ARM core) processors which are.
                    But for PowerPC it's the same, every instruction has 32 bit.
                    >
                    As are those of ARM processors like X-Scale (although some ARM
                    processors support the Thumb instruction set).

                    Comment

                    • Bjoern Schliessmann

                      #11
                      Re: list/dictionary as case statement ?

                      MRAB wrote:
                      I think that "PC" referred to the CPU's Program Counter.
                      Argh, thanks. :)
                      The x86 CPUs if typical Windows PCs aren't RISC but Intel also
                      manufacture X-Scale (ARM core) processors which are.
                      Okay, sorry for lack of precision. I was referring to x86.

                      Regards,


                      Björn

                      --
                      BOFH excuse #101:

                      Collapsed Backbone

                      Comment

                      • Stef Mientki

                        #12
                        Re: list/dictionary as case statement ?

                        Tom Plunket wrote:
                        Bjoern Schliessmann wrote:
                        >
                        >Intels aren't RISC, are they?
                        >
                        Not the ones in PCs. The OP didn't specify the CPU that's being used,
                        however.
                        >
                        Well it was meant for a small micro-controller, the PIC-14-series,
                        e.g. PIC16F877.

                        I already build a simulator for this device in Delphi,
                        but it seemed a nice idea, and a good exercise for me,
                        to see how this could be done in Python.

                        And thanks to you all,
                        I've the core (not the pheripherals) working now,
                        and my experience with Python are very positive.

                        The main advantages of the simulator in Python are:
                        - very elegant and lean code
                        - the treshold of Python is much lower
                        (in my opinion, simulators only live when more people are involved)
                        The main disadvantages (I think, not yet tested)
                        - the speed is much lower
                        - the GUI is much more complex

                        For those who are interested,

                        The rough code of the Python code can be seen here
                        (I might have committed a mortal sin, by changing "self" into "S" ??)

                        btw, as I'm a total newbie, any comment is welcome !!

                        The Delphi simulator can be seen here


                        thanks again,
                        for all your fast and very adequate responses !!

                        cheers,
                        Stef Mientki

                        Comment

                        Working...