By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,002 Members | 1,171 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,002 IT Pros & Developers. It's quick & easy.

list/dictionary as case statement ?

P: n/a

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.function3, )
}

def function1
# do something complex
Is this possible ?

thanks,
Stef Mientki
Jan 2 '07 #1
Share this Question
Share on Google+
11 Replies


P: n/a
On 2007-01-02, Stef Mientki <S.**************@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.function3, )
}

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!
Jan 2 '07 #2

P: n/a
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.function3, )
}

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
Jan 2 '07 #3

P: n/a
>
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

Jan 2 '07 #4

P: n/a
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.function3, )
}

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.function3
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(object):
def some_method(self):
print "some_method called, self : %s" % self

some_obj = SomeClass()

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

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

HTH
Jan 2 '07 #5

P: n/a
"Stef Mientki" <S.**************@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.function3, )
}

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_Opcodes =
{"MOV": [Functionnameforopcodeandtwooperands,movopcode],
"NOP":[Functionnameforopcodeonly,nopopcode],
"SETB":[Functionnameforopcodeandoneoperand,setbopcode],
"JMP":[Functionnameforopcodeandoneoperand,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,movinstructionlen],
nopopcod:[NopFunction,nopinstructionlen],
setbopcode:[SetbFunction,setbinstructionlen],
jmpopcode:[JmpFunction,jmpinstructionlen],
....
}

and then you write an "instruction 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
Jan 3 '07 #6

P: n/a
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+operand 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!

--
Jan 3 '07 #7

P: n/a
Tom Plunket wrote:
Often (always?) RISC architectures' instruction+operand 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.

Jan 3 '07 #8

P: n/a
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!

--
Jan 3 '07 #9

P: n/a

Bjoern Schliessmann wrote:
Tom Plunket wrote:
Often (always?) RISC architectures' instruction+operand 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).

Jan 3 '07 #10

P: n/a
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

Jan 3 '07 #11

P: n/a
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" ??)
http://oase.uci.kun.nl/~mientki/download/cpu2.txt
btw, as I'm a total newbie, any comment is welcome !!

The Delphi simulator can be seen here
http://oase.uci.kun.nl/~mientki/data...lss/jalss.html

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

cheers,
Stef Mientki
Jan 3 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.