list/dictionary as case statement ?

S

Stef Mientki

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
 
G

Grant Edwards

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.
 
G

Gary Herron

Stef said:
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:
.... 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
 
S

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.
Yes, I just found that out.

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

cheers,
Stef Mientki
 
B

Bruno Desthuilliers

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
 
H

Hendrik van Rooyen

Stef Mientki said:
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
 
T

Tom Plunket

Hendrik said:
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!

--
 
B

Bjoern Schliessmann

Tom said:
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
 
M

MRAB

Bjoern said:
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).
 
B

Bjoern Schliessmann

MRAB said:
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
 
S

Stef Mientki

Tom said:
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_www/pic/jalss/jalss.html

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

cheers,
Stef Mientki
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,591
Members
45,103
Latest member
VinaykumarnNevatia
Top