|
 |
CS 3723
Programming Languages |
3.4 Dictionaries
|
|
Reference links given below will be to the online book:
Building skills in Python
3.4. Dictionaries
See
Dictionaries.
These are a familiar feature in Perl and other scripting languages,
called "hashes" or "associative arrays" in Perl.
First is a program that translates simple one-operand assignments
for our Tiny project into MIPS assembly language. The first dictionary
gives the offset corresponding to each single-character operand. This
offset could be calculated with two simple formulas, but the
method here is far more general and is used for illustrative purposes.
Similarly, the second dictionary translates from a single-character
operand to the MIPS op-code.
Translate Assigns to MIPS |
Output (plus exec frame) |
#!/usr/bin/python
import sys
# MIPS offsets for constants and variables
d = {"0":0, "1": 8, "2": 16, "3": 24, "4": 32,
"5": 40, "6": 48, "7": 56, "8": 64, "9": 72,
"a": 80, "b": 88, "c": 96, "d": 104, "e": 112,
"f": 120, "g": 128, "h": 136, "i": 144, "j": 152,
"k": 160, "l": 168, "m": 176, "n": 184, "o": 192,
"p": 200, "q": 208, "r": 216, "s": 224, "t": 232,
"u": 240, "v": 248, "w": 256, "x": 264, "y": 272,
"z": 280}
# MIPS opcodes for operators
op = {"+":"add", "-":"sub", "*":"mul", "/":"div"}
def instr(x):
s = x[2]
t = x[4]
a = x[3]
r = x[0]
sys.stdout.write( "\tl.d $f2, " +
str(d[s]) + "($s1)\n")
sys.stdout.write( "\tl.d $f4, " +
str(d[t]) + "($s1)\n")
sys.stdout.write("\t" + str(op[a]) +
".d $f6, $f2, $f4\n")
sys.stdout.write( "\ts.d $f6, " +
str(d[r]) + "($s1)\n\n")
instr("a=8*2")
instr("b=7*a")
instr("c=b+1")
instr("d=a/c")
instr("e=3+d")
| main: addu $s7, $ra, $zero
la $s1, M
l.d $f2, 64($s1)
l.d $f4, 16($s1)
mul.d $f6, $f2, $f4
s.d $f6, 80($s1)
l.d $f2, 56($s1)
l.d $f4, 80($s1)
mul.d $f6, $f2, $f4
s.d $f6, 88($s1)
l.d $f2, 88($s1)
l.d $f4, 8($s1)
add.d $f6, $f2, $f4
s.d $f6, 96($s1)
l.d $f2, 80($s1)
l.d $f4, 96($s1)
div.d $f6, $f2, $f4
s.d $f6, 104($s1)
l.d $f2, 24($s1)
l.d $f4, 104($s1)
add.d $f6, $f2, $f4
s.d $f6, 112($s1)
# Print result + newl
li $v0, 3
l.d $f12, 112($s1)
syscall
li $v0, 4
la $a0, NewL
syscall
# Stuff at end ################
addu $ra, $s7, $zero
jr $ra # ret
.data
.align 3
M: .double 0.,1.,2.,3.,4.
.double 5.,6.,7.,8.,9.
.space 208 # a to z
NewL: .asciiz "\n"
|
The output of running the MIPS program is:
3.14159292035398252 ( = 355/113).
Items of Interest or for study:
- Continuation: The definition of the dictionary d can be
continued on later lines in any way at all as soon as the {
appears. However, you can't start this declaration with d =
as the only thing on the line but would need d = \ .
Inverting a Dictionary:
The second components have to be "hashable" for this to work.
(I didn't write this code myself. I edited the output to
group items together with the same precedence.)
Inverting a Dictionary |
#!/usr/bin/python
# example with no duplicate 2nd components
op = {"+":"add", "-":"sub", "*":"mul", "/":"div"}
inv_op = {}
for k, v in op.items():
inv_op[v] = k
print inv_op
# Has duplicate 2nd components (prec of C ops)
prec = {",":0,
"=":1, "+=":1, "-=":1, "*=":1, "/=":1, "%=":1,
"&=":1, "^=":1, "|=":1, "<<=":1, ">>=":1,
"?:":2,
"||":3,
"&&":4,
"|":5,
"^":6,
"&":7,
"==":8, "!=":8,
"<":9, "<=":9, ">":9, ">=": 9,
"<<":10, ">>":10,
"+":11, "-":11,
"*": 12, "/": 12, "%":12,
"!":13, "~":13, "++":13, "--":13, "+(u)":13,
"-(u)":13, "*(p)":13, "&(a)":13, "(type)":13, "sizeof":13,
"(group)":14, "[]":14, "->":14, ".":14,}
inv_prec = {}
for k, v in prec.iteritems():
inv_prec[v] = inv_prec.get(v, [])
inv_prec[v].append(k)
print inv_prec
|
Output |
{'mul': '*', 'add': '+', 'div': '/', 'sub': '-'}
{ 0: [','],
1: ['%=', '>>=', '|=', '-=', '^=', '<<=', '=', '*=', '&=', '/=', '+='],
2: ['?:'],
3: ['||'],
4: ['&&'],
5: ['|'],
6: ['^'],
7: ['&'],
8: ['!=', '=='],
9: ['>=', '<', '>', '<='],
10: ['>>', '<<'],
11: ['+', '-'],
12: ['*', '%', '/'],
13: ['+(u)', '&(a)', '-(u)', '--', '~', 'sizeof', '!', '(type)', '++', '*(p)'],
14: ['[]', '.', '(group)', '->']}
|
(Revision date: 2014-05-24.
Please use ISO 8601,
the International Standard.)
|