basinterp.py (4479:61d3ed46e373) | basinterp.py (6498:e21e9ab5fad0) |
---|---|
1# This file provides the runtime support for running a basic program 2# Assumes the program has been parsed using basparse.py 3 4import sys 5import math 6import random 7 8class BasicInterpreter: --- 26 unchanged lines hidden (view full) --- 35 36 # Check for end statements 37 def check_end(self): 38 has_end = 0 39 for lineno in self.stat: 40 if self.prog[lineno][0] == 'END' and not has_end: 41 has_end = lineno 42 if not has_end: | 1# This file provides the runtime support for running a basic program 2# Assumes the program has been parsed using basparse.py 3 4import sys 5import math 6import random 7 8class BasicInterpreter: --- 26 unchanged lines hidden (view full) --- 35 36 # Check for end statements 37 def check_end(self): 38 has_end = 0 39 for lineno in self.stat: 40 if self.prog[lineno][0] == 'END' and not has_end: 41 has_end = lineno 42 if not has_end: |
43 print "NO END INSTRUCTION" | 43 print("NO END INSTRUCTION") |
44 self.error = 1 | 44 self.error = 1 |
45 return |
|
45 if has_end != lineno: | 46 if has_end != lineno: |
46 print "END IS NOT LAST" | 47 print("END IS NOT LAST") |
47 self.error = 1 48 49 # Check loops 50 def check_loops(self): 51 for pc in range(len(self.stat)): 52 lineno = self.stat[pc] 53 if self.prog[lineno][0] == 'FOR': 54 forinst = self.prog[lineno] 55 loopvar = forinst[1] 56 for i in range(pc+1,len(self.stat)): 57 if self.prog[self.stat[i]][0] == 'NEXT': 58 nextvar = self.prog[self.stat[i]][1] 59 if nextvar != loopvar: continue 60 self.loopend[pc] = i 61 break 62 else: | 48 self.error = 1 49 50 # Check loops 51 def check_loops(self): 52 for pc in range(len(self.stat)): 53 lineno = self.stat[pc] 54 if self.prog[lineno][0] == 'FOR': 55 forinst = self.prog[lineno] 56 loopvar = forinst[1] 57 for i in range(pc+1,len(self.stat)): 58 if self.prog[self.stat[i]][0] == 'NEXT': 59 nextvar = self.prog[self.stat[i]][1] 60 if nextvar != loopvar: continue 61 self.loopend[pc] = i 62 break 63 else: |
63 print "FOR WITHOUT NEXT AT LINE" % self.stat[pc] | 64 print("FOR WITHOUT NEXT AT LINE %s" % self.stat[pc]) |
64 self.error = 1 | 65 self.error = 1 |
65 | 66 |
66 # Evaluate an expression 67 def eval(self,expr): 68 etype = expr[0] 69 if etype == 'NUM': return expr[1] 70 elif etype == 'GROUP': return self.eval(expr[1]) 71 elif etype == 'UNARY': 72 if expr[1] == '-': return -self.eval(expr[2]) 73 elif etype == 'BINOP': 74 if expr[1] == '+': return self.eval(expr[2])+self.eval(expr[3]) 75 elif expr[1] == '-': return self.eval(expr[2])-self.eval(expr[3]) 76 elif expr[1] == '*': return self.eval(expr[2])*self.eval(expr[3]) 77 elif expr[1] == '/': return float(self.eval(expr[2]))/self.eval(expr[3]) 78 elif expr[1] == '^': return abs(self.eval(expr[2]))**self.eval(expr[3]) 79 elif etype == 'VAR': 80 var,dim1,dim2 = expr[1] 81 if not dim1 and not dim2: | 67 # Evaluate an expression 68 def eval(self,expr): 69 etype = expr[0] 70 if etype == 'NUM': return expr[1] 71 elif etype == 'GROUP': return self.eval(expr[1]) 72 elif etype == 'UNARY': 73 if expr[1] == '-': return -self.eval(expr[2]) 74 elif etype == 'BINOP': 75 if expr[1] == '+': return self.eval(expr[2])+self.eval(expr[3]) 76 elif expr[1] == '-': return self.eval(expr[2])-self.eval(expr[3]) 77 elif expr[1] == '*': return self.eval(expr[2])*self.eval(expr[3]) 78 elif expr[1] == '/': return float(self.eval(expr[2]))/self.eval(expr[3]) 79 elif expr[1] == '^': return abs(self.eval(expr[2]))**self.eval(expr[3]) 80 elif etype == 'VAR': 81 var,dim1,dim2 = expr[1] 82 if not dim1 and not dim2: |
82 if self.vars.has_key(var): | 83 if var in self.vars: |
83 return self.vars[var] 84 else: | 84 return self.vars[var] 85 else: |
85 print "UNDEFINED VARIABLE", var, "AT LINE", self.stat[self.pc] | 86 print("UNDEFINED VARIABLE %s AT LINE %s" % (var, self.stat[self.pc])) |
86 raise RuntimeError 87 # May be a list lookup or a function evaluation 88 if dim1 and not dim2: | 87 raise RuntimeError 88 # May be a list lookup or a function evaluation 89 if dim1 and not dim2: |
89 if self.functions.has_key(var): | 90 if var in self.functions: |
90 # A function 91 return self.functions[var](dim1) 92 else: 93 # A list evaluation | 91 # A function 92 return self.functions[var](dim1) 93 else: 94 # A list evaluation |
94 if self.lists.has_key(var): | 95 if var in self.lists: |
95 dim1val = self.eval(dim1) 96 if dim1val < 1 or dim1val > len(self.lists[var]): | 96 dim1val = self.eval(dim1) 97 if dim1val < 1 or dim1val > len(self.lists[var]): |
97 print "LIST INDEX OUT OF BOUNDS AT LINE", self.stat[self.pc] | 98 print("LIST INDEX OUT OF BOUNDS AT LINE %s" % self.stat[self.pc]) |
98 raise RuntimeError 99 return self.lists[var][dim1val-1] 100 if dim1 and dim2: | 99 raise RuntimeError 100 return self.lists[var][dim1val-1] 101 if dim1 and dim2: |
101 if self.tables.has_key(var): | 102 if var in self.tables: |
102 dim1val = self.eval(dim1) 103 dim2val = self.eval(dim2) 104 if dim1val < 1 or dim1val > len(self.tables[var]) or dim2val < 1 or dim2val > len(self.tables[var][0]): | 103 dim1val = self.eval(dim1) 104 dim2val = self.eval(dim2) 105 if dim1val < 1 or dim1val > len(self.tables[var]) or dim2val < 1 or dim2val > len(self.tables[var][0]): |
105 print "TABLE INDEX OUT OUT BOUNDS AT LINE", self.stat[self.pc] | 106 print("TABLE INDEX OUT OUT BOUNDS AT LINE %s" % self.stat[self.pc]) |
106 raise RuntimeError 107 return self.tables[var][dim1val-1][dim2val-1] | 107 raise RuntimeError 108 return self.tables[var][dim1val-1][dim2val-1] |
108 print "UNDEFINED VARIABLE", var, "AT LINE", self.stat[self.pc] | 109 print("UNDEFINED VARIABLE %s AT LINE %s" % (var, self.stat[self.pc])) |
109 raise RuntimeError 110 111 # Evaluate a relational expression 112 def releval(self,expr): 113 etype = expr[1] 114 lhs = self.eval(expr[2]) 115 rhs = self.eval(expr[3]) 116 if etype == '<': --- 23 unchanged lines hidden (view full) --- 140 # Assignment 141 def assign(self,target,value): 142 var, dim1, dim2 = target 143 if not dim1 and not dim2: 144 self.vars[var] = self.eval(value) 145 elif dim1 and not dim2: 146 # List assignment 147 dim1val = self.eval(dim1) | 110 raise RuntimeError 111 112 # Evaluate a relational expression 113 def releval(self,expr): 114 etype = expr[1] 115 lhs = self.eval(expr[2]) 116 rhs = self.eval(expr[3]) 117 if etype == '<': --- 23 unchanged lines hidden (view full) --- 141 # Assignment 142 def assign(self,target,value): 143 var, dim1, dim2 = target 144 if not dim1 and not dim2: 145 self.vars[var] = self.eval(value) 146 elif dim1 and not dim2: 147 # List assignment 148 dim1val = self.eval(dim1) |
148 if not self.lists.has_key(var): | 149 if not var in self.lists: |
149 self.lists[var] = [0]*10 150 151 if dim1val > len(self.lists[var]): | 150 self.lists[var] = [0]*10 151 152 if dim1val > len(self.lists[var]): |
152 print "DIMENSION TOO LARGE AT LINE", self.stat[self.pc] | 153 print ("DIMENSION TOO LARGE AT LINE %s" % self.stat[self.pc]) |
153 raise RuntimeError 154 self.lists[var][dim1val-1] = self.eval(value) 155 elif dim1 and dim2: 156 dim1val = self.eval(dim1) 157 dim2val = self.eval(dim2) | 154 raise RuntimeError 155 self.lists[var][dim1val-1] = self.eval(value) 156 elif dim1 and dim2: 157 dim1val = self.eval(dim1) 158 dim2val = self.eval(dim2) |
158 if not self.tables.has_key(var): | 159 if not var in self.tables: |
159 temp = [0]*10 160 v = [] 161 for i in range(10): v.append(temp[:]) 162 self.tables[var] = v 163 # Variable already exists 164 if dim1val > len(self.tables[var]) or dim2val > len(self.tables[var][0]): | 160 temp = [0]*10 161 v = [] 162 for i in range(10): v.append(temp[:]) 163 self.tables[var] = v 164 # Variable already exists 165 if dim1val > len(self.tables[var]) or dim2val > len(self.tables[var][0]): |
165 print "DIMENSION TOO LARGE AT LINE", self.stat[self.pc] | 166 print("DIMENSION TOO LARGE AT LINE %s" % self.stat[self.pc]) |
166 raise RuntimeError 167 self.tables[var][dim1val-1][dim2val-1] = self.eval(value) 168 169 # Change the current line number 170 def goto(self,linenum): | 167 raise RuntimeError 168 self.tables[var][dim1val-1][dim2val-1] = self.eval(value) 169 170 # Change the current line number 171 def goto(self,linenum): |
171 if not self.prog.has_key(linenum): 172 print "UNDEFINED LINE NUMBER %d AT LINE %d" % (linenum, self.stat[self.pc]) | 172 if not linenum in self.prog: 173 print("UNDEFINED LINE NUMBER %d AT LINE %d" % (linenum, self.stat[self.pc])) |
173 raise RuntimeError 174 self.pc = self.stat.index(linenum) 175 176 # Run it 177 def run(self): 178 self.vars = { } # All variables 179 self.lists = { } # List variables 180 self.tables = { } # Tables 181 self.loops = [ ] # Currently active loops 182 self.loopend= { } # Mapping saying where loops end 183 self.gosub = None # Gosub return point (if any) 184 self.error = 0 # Indicates program error 185 | 174 raise RuntimeError 175 self.pc = self.stat.index(linenum) 176 177 # Run it 178 def run(self): 179 self.vars = { } # All variables 180 self.lists = { } # List variables 181 self.tables = { } # Tables 182 self.loops = [ ] # Currently active loops 183 self.loopend= { } # Mapping saying where loops end 184 self.gosub = None # Gosub return point (if any) 185 self.error = 0 # Indicates program error 186 |
186 self.stat = self.prog.keys() # Ordered list of all line numbers | 187 self.stat = list(self.prog) # Ordered list of all line numbers |
187 self.stat.sort() 188 self.pc = 0 # Current program counter 189 190 # Processing prior to running 191 192 self.collect_data() # Collect all of the data statements 193 self.check_end() 194 self.check_loops() 195 196 if self.error: raise RuntimeError 197 198 while 1: 199 line = self.stat[self.pc] 200 instr = self.prog[line] | 188 self.stat.sort() 189 self.pc = 0 # Current program counter 190 191 # Processing prior to running 192 193 self.collect_data() # Collect all of the data statements 194 self.check_end() 195 self.check_loops() 196 197 if self.error: raise RuntimeError 198 199 while 1: 200 line = self.stat[self.pc] 201 instr = self.prog[line] |
201 | 202 |
202 op = instr[0] 203 204 # END and STOP statements 205 if op == 'END' or op == 'STOP': 206 break # We're done 207 208 # GOTO statement 209 elif op == 'GOTO': --- 10 unchanged lines hidden (view full) --- 220 out += ' '*(15 - (len(out) % 15)) 221 out += label 222 if val: 223 if label: out += " " 224 eval = self.eval(val) 225 out += str(eval) 226 sys.stdout.write(out) 227 end = instr[2] | 203 op = instr[0] 204 205 # END and STOP statements 206 if op == 'END' or op == 'STOP': 207 break # We're done 208 209 # GOTO statement 210 elif op == 'GOTO': --- 10 unchanged lines hidden (view full) --- 221 out += ' '*(15 - (len(out) % 15)) 222 out += label 223 if val: 224 if label: out += " " 225 eval = self.eval(val) 226 out += str(eval) 227 sys.stdout.write(out) 228 end = instr[2] |
228 if not (end == ',' or end == ';'): | 229 if not (end == ',' or end == ';'): |
229 sys.stdout.write("\n") 230 if end == ',': sys.stdout.write(" "*(15-(len(out) % 15))) 231 if end == ';': sys.stdout.write(" "*(3-(len(out) % 3))) | 230 sys.stdout.write("\n") 231 if end == ',': sys.stdout.write(" "*(15-(len(out) % 15))) 232 if end == ';': sys.stdout.write(" "*(3-(len(out) % 3))) |
232 | 233 |
233 # LET statement 234 elif op == 'LET': 235 target = instr[1] 236 value = instr[2] 237 self.assign(target,value) 238 239 # READ statement 240 elif op == 'READ': --- 12 unchanged lines hidden (view full) --- 253 self.goto(newline) 254 continue 255 256 elif op == 'FOR': 257 loopvar = instr[1] 258 initval = instr[2] 259 finval = instr[3] 260 stepval = instr[4] | 234 # LET statement 235 elif op == 'LET': 236 target = instr[1] 237 value = instr[2] 238 self.assign(target,value) 239 240 # READ statement 241 elif op == 'READ': --- 12 unchanged lines hidden (view full) --- 254 self.goto(newline) 255 continue 256 257 elif op == 'FOR': 258 loopvar = instr[1] 259 initval = instr[2] 260 finval = instr[3] 261 stepval = instr[4] |
261 | 262 |
262 # Check to see if this is a new loop 263 if not self.loops or self.loops[-1][0] != self.pc: 264 # Looks like a new loop. Make the initial assignment 265 newvalue = initval 266 self.assign((loopvar,None,None),initval) 267 if not stepval: stepval = ('NUM',1) 268 stepval = self.eval(stepval) # Evaluate step here 269 self.loops.append((self.pc,stepval)) --- 9 unchanged lines hidden (view full) --- 279 # Loop is done. Jump to the NEXT 280 self.pc = self.loopend[self.pc] 281 self.loops.pop() 282 else: 283 self.assign((loopvar,None,None),newvalue) 284 285 elif op == 'NEXT': 286 if not self.loops: | 263 # Check to see if this is a new loop 264 if not self.loops or self.loops[-1][0] != self.pc: 265 # Looks like a new loop. Make the initial assignment 266 newvalue = initval 267 self.assign((loopvar,None,None),initval) 268 if not stepval: stepval = ('NUM',1) 269 stepval = self.eval(stepval) # Evaluate step here 270 self.loops.append((self.pc,stepval)) --- 9 unchanged lines hidden (view full) --- 280 # Loop is done. Jump to the NEXT 281 self.pc = self.loopend[self.pc] 282 self.loops.pop() 283 else: 284 self.assign((loopvar,None,None),newvalue) 285 286 elif op == 'NEXT': 287 if not self.loops: |
287 print "NEXT WITHOUT FOR AT LINE",line | 288 print("NEXT WITHOUT FOR AT LINE %s" % line) |
288 return | 289 return |
289 | 290 |
290 nextvar = instr[1] 291 self.pc = self.loops[-1][0] 292 loopinst = self.prog[self.stat[self.pc]] 293 forvar = loopinst[1] 294 if nextvar != forvar: | 291 nextvar = instr[1] 292 self.pc = self.loops[-1][0] 293 loopinst = self.prog[self.stat[self.pc]] 294 forvar = loopinst[1] 295 if nextvar != forvar: |
295 print "NEXT DOESN'T MATCH FOR AT LINE", line | 296 print("NEXT DOESN'T MATCH FOR AT LINE %s" % line) |
296 return 297 continue 298 elif op == 'GOSUB': 299 newline = instr[1] 300 if self.gosub: | 297 return 298 continue 299 elif op == 'GOSUB': 300 newline = instr[1] 301 if self.gosub: |
301 print "ALREADY IN A SUBROUTINE AT LINE", line | 302 print("ALREADY IN A SUBROUTINE AT LINE %s" % line) |
302 return 303 self.gosub = self.stat[self.pc] 304 self.goto(newline) 305 continue 306 307 elif op == 'RETURN': 308 if not self.gosub: | 303 return 304 self.gosub = self.stat[self.pc] 305 self.goto(newline) 306 continue 307 308 elif op == 'RETURN': 309 if not self.gosub: |
309 print "RETURN WITHOUT A GOSUB AT LINE",line | 310 print("RETURN WITHOUT A GOSUB AT LINE %s" % line) |
310 return 311 self.goto(self.gosub) 312 self.gosub = None 313 314 elif op == 'FUNC': 315 fname = instr[1] 316 pname = instr[2] 317 expr = instr[3] --- 10 unchanged lines hidden (view full) --- 328 else: 329 # Double dimension variable 330 temp = [0]*y 331 v = [] 332 for i in range(x): 333 v.append(temp[:]) 334 self.tables[vname] = v 335 | 311 return 312 self.goto(self.gosub) 313 self.gosub = None 314 315 elif op == 'FUNC': 316 fname = instr[1] 317 pname = instr[2] 318 expr = instr[3] --- 10 unchanged lines hidden (view full) --- 329 else: 330 # Double dimension variable 331 temp = [0]*y 332 v = [] 333 for i in range(x): 334 v.append(temp[:]) 335 self.tables[vname] = v 336 |
336 self.pc += 1 | 337 self.pc += 1 |
337 338 # Utility functions for program listing 339 def expr_str(self,expr): 340 etype = expr[0] 341 if etype == 'NUM': return str(expr[1]) 342 elif etype == 'GROUP': return "(%s)" % self.expr_str(expr[1]) 343 elif etype == 'UNARY': 344 if expr[1] == '-': return "-"+str(expr[2]) --- 8 unchanged lines hidden (view full) --- 353 def var_str(self,var): 354 varname,dim1,dim2 = var 355 if not dim1 and not dim2: return varname 356 if dim1 and not dim2: return "%s(%s)" % (varname, self.expr_str(dim1)) 357 return "%s(%s,%s)" % (varname, self.expr_str(dim1),self.expr_str(dim2)) 358 359 # Create a program listing 360 def list(self): | 338 339 # Utility functions for program listing 340 def expr_str(self,expr): 341 etype = expr[0] 342 if etype == 'NUM': return str(expr[1]) 343 elif etype == 'GROUP': return "(%s)" % self.expr_str(expr[1]) 344 elif etype == 'UNARY': 345 if expr[1] == '-': return "-"+str(expr[2]) --- 8 unchanged lines hidden (view full) --- 354 def var_str(self,var): 355 varname,dim1,dim2 = var 356 if not dim1 and not dim2: return varname 357 if dim1 and not dim2: return "%s(%s)" % (varname, self.expr_str(dim1)) 358 return "%s(%s,%s)" % (varname, self.expr_str(dim1),self.expr_str(dim2)) 359 360 # Create a program listing 361 def list(self): |
361 stat = self.prog.keys() # Ordered list of all line numbers | 362 stat = list(self.prog) # Ordered list of all line numbers |
362 stat.sort() 363 for line in stat: 364 instr = self.prog[line] 365 op = instr[0] 366 if op in ['END','STOP','RETURN']: | 363 stat.sort() 364 for line in stat: 365 instr = self.prog[line] 366 op = instr[0] 367 if op in ['END','STOP','RETURN']: |
367 print line, op | 368 print("%s %s" % (line, op)) |
368 continue 369 elif op == 'REM': | 369 continue 370 elif op == 'REM': |
370 print line, instr[1] | 371 print("%s %s" % (line, instr[1])) |
371 elif op == 'PRINT': | 372 elif op == 'PRINT': |
372 print line, op, | 373 _out = "%s %s " % (line, op) |
373 first = 1 374 for p in instr[1]: | 374 first = 1 375 for p in instr[1]: |
375 if not first: print ",", 376 if p[0] and p[1]: print '"%s"%s' % (p[0],self.expr_str(p[1])), 377 elif p[1]: print self.expr_str(p[1]), 378 else: print '"%s"' % (p[0],), | 376 if not first: _out += ", " 377 if p[0] and p[1]: _out += '"%s"%s' % (p[0],self.expr_str(p[1])) 378 elif p[1]: _out += self.expr_str(p[1]) 379 else: _out += '"%s"' % (p[0],) |
379 first = 0 | 380 first = 0 |
380 if instr[2]: print instr[2] 381 else: print | 381 if instr[2]: _out += instr[2] 382 print(_out) |
382 elif op == 'LET': | 383 elif op == 'LET': |
383 print line,"LET",self.var_str(instr[1]),"=",self.expr_str(instr[2]) | 384 print("%s LET %s = %s" % (line,self.var_str(instr[1]),self.expr_str(instr[2]))) |
384 elif op == 'READ': | 385 elif op == 'READ': |
385 print line,"READ", | 386 _out = "%s READ " % line |
386 first = 1 387 for r in instr[1]: | 387 first = 1 388 for r in instr[1]: |
388 if not first: print ",", 389 print self.var_str(r), | 389 if not first: _out += "," 390 _out += self.var_str(r) |
390 first = 0 | 391 first = 0 |
391 print "" | 392 print(_out) |
392 elif op == 'IF': | 393 elif op == 'IF': |
393 print line,"IF %s THEN %d" % (self.relexpr_str(instr[1]),instr[2]) | 394 print("%s IF %s THEN %d" % (line,self.relexpr_str(instr[1]),instr[2])) |
394 elif op == 'GOTO' or op == 'GOSUB': | 395 elif op == 'GOTO' or op == 'GOSUB': |
395 print line, op, instr[1] | 396 print("%s %s %s" % (line, op, instr[1])) |
396 elif op == 'FOR': | 397 elif op == 'FOR': |
397 print line,"FOR %s = %s TO %s" % (instr[1],self.expr_str(instr[2]),self.expr_str(instr[3])), 398 if instr[4]: print "STEP %s" % (self.expr_str(instr[4])), 399 print | 398 _out = "%s FOR %s = %s TO %s" % (line,instr[1],self.expr_str(instr[2]),self.expr_str(instr[3])) 399 if instr[4]: _out += " STEP %s" % (self.expr_str(instr[4])) 400 print(_out) |
400 elif op == 'NEXT': | 401 elif op == 'NEXT': |
401 print line,"NEXT", instr[1] | 402 print("%s NEXT %s" % (line, instr[1])) |
402 elif op == 'FUNC': | 403 elif op == 'FUNC': |
403 print line,"DEF %s(%s) = %s" % (instr[1],instr[2],self.expr_str(instr[3])) | 404 print("%s DEF %s(%s) = %s" % (line,instr[1],instr[2],self.expr_str(instr[3]))) |
404 elif op == 'DIM': | 405 elif op == 'DIM': |
405 print line,"DIM", | 406 _out = "%s DIM " % line |
406 first = 1 407 for vname,x,y in instr[1]: | 407 first = 1 408 for vname,x,y in instr[1]: |
408 if not first: print ",", | 409 if not first: _out += "," |
409 first = 0 410 if y == 0: | 410 first = 0 411 if y == 0: |
411 print "%s(%d)" % (vname,x), | 412 _out += "%s(%d)" % (vname,x) |
412 else: | 413 else: |
413 print "%s(%d,%d)" % (vname,x,y), 414 415 print | 414 _out += "%s(%d,%d)" % (vname,x,y) 415 416 print(_out) |
416 elif op == 'DATA': | 417 elif op == 'DATA': |
417 print line,"DATA", | 418 _out = "%s DATA " % line |
418 first = 1 419 for v in instr[1]: | 419 first = 1 420 for v in instr[1]: |
420 if not first: print ",", | 421 if not first: _out += "," |
421 first = 0 | 422 first = 0 |
422 print v, 423 print | 423 _out += v 424 print(_out) |
424 425 # Erase the current program 426 def new(self): 427 self.prog = {} | 425 426 # Erase the current program 427 def new(self): 428 self.prog = {} |
428 | 429 |
429 # Insert statements 430 def add_statements(self,prog): 431 for line,stat in prog.items(): 432 self.prog[line] = stat 433 434 # Delete a statement 435 def del_line(self,lineno): 436 try: 437 del self.prog[lineno] 438 except KeyError: 439 pass 440 | 430 # Insert statements 431 def add_statements(self,prog): 432 for line,stat in prog.items(): 433 self.prog[line] = stat 434 435 # Delete a statement 436 def del_line(self,lineno): 437 try: 438 del self.prog[lineno] 439 except KeyError: 440 pass 441 |