14479Sbinkertn@umich.edu# This file provides the runtime support for running a basic program 24479Sbinkertn@umich.edu# Assumes the program has been parsed using basparse.py 34479Sbinkertn@umich.edu 44479Sbinkertn@umich.eduimport sys 54479Sbinkertn@umich.eduimport math 64479Sbinkertn@umich.eduimport random 74479Sbinkertn@umich.edu 84479Sbinkertn@umich.educlass BasicInterpreter: 94479Sbinkertn@umich.edu 104479Sbinkertn@umich.edu # Initialize the interpreter. prog is a dictionary 114479Sbinkertn@umich.edu # containing (line,statement) mappings 124479Sbinkertn@umich.edu def __init__(self,prog): 134479Sbinkertn@umich.edu self.prog = prog 144479Sbinkertn@umich.edu 154479Sbinkertn@umich.edu self.functions = { # Built-in function table 164479Sbinkertn@umich.edu 'SIN' : lambda z: math.sin(self.eval(z)), 174479Sbinkertn@umich.edu 'COS' : lambda z: math.cos(self.eval(z)), 184479Sbinkertn@umich.edu 'TAN' : lambda z: math.tan(self.eval(z)), 194479Sbinkertn@umich.edu 'ATN' : lambda z: math.atan(self.eval(z)), 204479Sbinkertn@umich.edu 'EXP' : lambda z: math.exp(self.eval(z)), 214479Sbinkertn@umich.edu 'ABS' : lambda z: abs(self.eval(z)), 224479Sbinkertn@umich.edu 'LOG' : lambda z: math.log(self.eval(z)), 234479Sbinkertn@umich.edu 'SQR' : lambda z: math.sqrt(self.eval(z)), 244479Sbinkertn@umich.edu 'INT' : lambda z: int(self.eval(z)), 254479Sbinkertn@umich.edu 'RND' : lambda z: random.random() 264479Sbinkertn@umich.edu } 274479Sbinkertn@umich.edu 284479Sbinkertn@umich.edu # Collect all data statements 294479Sbinkertn@umich.edu def collect_data(self): 304479Sbinkertn@umich.edu self.data = [] 314479Sbinkertn@umich.edu for lineno in self.stat: 324479Sbinkertn@umich.edu if self.prog[lineno][0] == 'DATA': 334479Sbinkertn@umich.edu self.data = self.data + self.prog[lineno][1] 344479Sbinkertn@umich.edu self.dc = 0 # Initialize the data counter 354479Sbinkertn@umich.edu 364479Sbinkertn@umich.edu # Check for end statements 374479Sbinkertn@umich.edu def check_end(self): 384479Sbinkertn@umich.edu has_end = 0 394479Sbinkertn@umich.edu for lineno in self.stat: 404479Sbinkertn@umich.edu if self.prog[lineno][0] == 'END' and not has_end: 414479Sbinkertn@umich.edu has_end = lineno 424479Sbinkertn@umich.edu if not has_end: 436498Snate@binkert.org print("NO END INSTRUCTION") 444479Sbinkertn@umich.edu self.error = 1 456498Snate@binkert.org return 464479Sbinkertn@umich.edu if has_end != lineno: 476498Snate@binkert.org print("END IS NOT LAST") 484479Sbinkertn@umich.edu self.error = 1 494479Sbinkertn@umich.edu 504479Sbinkertn@umich.edu # Check loops 514479Sbinkertn@umich.edu def check_loops(self): 524479Sbinkertn@umich.edu for pc in range(len(self.stat)): 534479Sbinkertn@umich.edu lineno = self.stat[pc] 544479Sbinkertn@umich.edu if self.prog[lineno][0] == 'FOR': 554479Sbinkertn@umich.edu forinst = self.prog[lineno] 564479Sbinkertn@umich.edu loopvar = forinst[1] 574479Sbinkertn@umich.edu for i in range(pc+1,len(self.stat)): 584479Sbinkertn@umich.edu if self.prog[self.stat[i]][0] == 'NEXT': 594479Sbinkertn@umich.edu nextvar = self.prog[self.stat[i]][1] 604479Sbinkertn@umich.edu if nextvar != loopvar: continue 614479Sbinkertn@umich.edu self.loopend[pc] = i 624479Sbinkertn@umich.edu break 634479Sbinkertn@umich.edu else: 646498Snate@binkert.org print("FOR WITHOUT NEXT AT LINE %s" % self.stat[pc]) 654479Sbinkertn@umich.edu self.error = 1 666498Snate@binkert.org 674479Sbinkertn@umich.edu # Evaluate an expression 684479Sbinkertn@umich.edu def eval(self,expr): 694479Sbinkertn@umich.edu etype = expr[0] 704479Sbinkertn@umich.edu if etype == 'NUM': return expr[1] 714479Sbinkertn@umich.edu elif etype == 'GROUP': return self.eval(expr[1]) 724479Sbinkertn@umich.edu elif etype == 'UNARY': 734479Sbinkertn@umich.edu if expr[1] == '-': return -self.eval(expr[2]) 744479Sbinkertn@umich.edu elif etype == 'BINOP': 754479Sbinkertn@umich.edu if expr[1] == '+': return self.eval(expr[2])+self.eval(expr[3]) 764479Sbinkertn@umich.edu elif expr[1] == '-': return self.eval(expr[2])-self.eval(expr[3]) 774479Sbinkertn@umich.edu elif expr[1] == '*': return self.eval(expr[2])*self.eval(expr[3]) 784479Sbinkertn@umich.edu elif expr[1] == '/': return float(self.eval(expr[2]))/self.eval(expr[3]) 794479Sbinkertn@umich.edu elif expr[1] == '^': return abs(self.eval(expr[2]))**self.eval(expr[3]) 804479Sbinkertn@umich.edu elif etype == 'VAR': 814479Sbinkertn@umich.edu var,dim1,dim2 = expr[1] 824479Sbinkertn@umich.edu if not dim1 and not dim2: 836498Snate@binkert.org if var in self.vars: 844479Sbinkertn@umich.edu return self.vars[var] 854479Sbinkertn@umich.edu else: 866498Snate@binkert.org print("UNDEFINED VARIABLE %s AT LINE %s" % (var, self.stat[self.pc])) 874479Sbinkertn@umich.edu raise RuntimeError 884479Sbinkertn@umich.edu # May be a list lookup or a function evaluation 894479Sbinkertn@umich.edu if dim1 and not dim2: 906498Snate@binkert.org if var in self.functions: 914479Sbinkertn@umich.edu # A function 924479Sbinkertn@umich.edu return self.functions[var](dim1) 934479Sbinkertn@umich.edu else: 944479Sbinkertn@umich.edu # A list evaluation 956498Snate@binkert.org if var in self.lists: 964479Sbinkertn@umich.edu dim1val = self.eval(dim1) 974479Sbinkertn@umich.edu if dim1val < 1 or dim1val > len(self.lists[var]): 986498Snate@binkert.org print("LIST INDEX OUT OF BOUNDS AT LINE %s" % self.stat[self.pc]) 994479Sbinkertn@umich.edu raise RuntimeError 1004479Sbinkertn@umich.edu return self.lists[var][dim1val-1] 1014479Sbinkertn@umich.edu if dim1 and dim2: 1026498Snate@binkert.org if var in self.tables: 1034479Sbinkertn@umich.edu dim1val = self.eval(dim1) 1044479Sbinkertn@umich.edu dim2val = self.eval(dim2) 1054479Sbinkertn@umich.edu if dim1val < 1 or dim1val > len(self.tables[var]) or dim2val < 1 or dim2val > len(self.tables[var][0]): 1066498Snate@binkert.org print("TABLE INDEX OUT OUT BOUNDS AT LINE %s" % self.stat[self.pc]) 1074479Sbinkertn@umich.edu raise RuntimeError 1084479Sbinkertn@umich.edu return self.tables[var][dim1val-1][dim2val-1] 1096498Snate@binkert.org print("UNDEFINED VARIABLE %s AT LINE %s" % (var, self.stat[self.pc])) 1104479Sbinkertn@umich.edu raise RuntimeError 1114479Sbinkertn@umich.edu 1124479Sbinkertn@umich.edu # Evaluate a relational expression 1134479Sbinkertn@umich.edu def releval(self,expr): 1144479Sbinkertn@umich.edu etype = expr[1] 1154479Sbinkertn@umich.edu lhs = self.eval(expr[2]) 1164479Sbinkertn@umich.edu rhs = self.eval(expr[3]) 1174479Sbinkertn@umich.edu if etype == '<': 1184479Sbinkertn@umich.edu if lhs < rhs: return 1 1194479Sbinkertn@umich.edu else: return 0 1204479Sbinkertn@umich.edu 1214479Sbinkertn@umich.edu elif etype == '<=': 1224479Sbinkertn@umich.edu if lhs <= rhs: return 1 1234479Sbinkertn@umich.edu else: return 0 1244479Sbinkertn@umich.edu 1254479Sbinkertn@umich.edu elif etype == '>': 1264479Sbinkertn@umich.edu if lhs > rhs: return 1 1274479Sbinkertn@umich.edu else: return 0 1284479Sbinkertn@umich.edu 1294479Sbinkertn@umich.edu elif etype == '>=': 1304479Sbinkertn@umich.edu if lhs >= rhs: return 1 1314479Sbinkertn@umich.edu else: return 0 1324479Sbinkertn@umich.edu 1334479Sbinkertn@umich.edu elif etype == '=': 1344479Sbinkertn@umich.edu if lhs == rhs: return 1 1354479Sbinkertn@umich.edu else: return 0 1364479Sbinkertn@umich.edu 1374479Sbinkertn@umich.edu elif etype == '<>': 1384479Sbinkertn@umich.edu if lhs != rhs: return 1 1394479Sbinkertn@umich.edu else: return 0 1404479Sbinkertn@umich.edu 1414479Sbinkertn@umich.edu # Assignment 1424479Sbinkertn@umich.edu def assign(self,target,value): 1434479Sbinkertn@umich.edu var, dim1, dim2 = target 1444479Sbinkertn@umich.edu if not dim1 and not dim2: 1454479Sbinkertn@umich.edu self.vars[var] = self.eval(value) 1464479Sbinkertn@umich.edu elif dim1 and not dim2: 1474479Sbinkertn@umich.edu # List assignment 1484479Sbinkertn@umich.edu dim1val = self.eval(dim1) 1496498Snate@binkert.org if not var in self.lists: 1504479Sbinkertn@umich.edu self.lists[var] = [0]*10 1514479Sbinkertn@umich.edu 1524479Sbinkertn@umich.edu if dim1val > len(self.lists[var]): 1536498Snate@binkert.org print ("DIMENSION TOO LARGE AT LINE %s" % self.stat[self.pc]) 1544479Sbinkertn@umich.edu raise RuntimeError 1554479Sbinkertn@umich.edu self.lists[var][dim1val-1] = self.eval(value) 1564479Sbinkertn@umich.edu elif dim1 and dim2: 1574479Sbinkertn@umich.edu dim1val = self.eval(dim1) 1584479Sbinkertn@umich.edu dim2val = self.eval(dim2) 1596498Snate@binkert.org if not var in self.tables: 1604479Sbinkertn@umich.edu temp = [0]*10 1614479Sbinkertn@umich.edu v = [] 1624479Sbinkertn@umich.edu for i in range(10): v.append(temp[:]) 1634479Sbinkertn@umich.edu self.tables[var] = v 1644479Sbinkertn@umich.edu # Variable already exists 1654479Sbinkertn@umich.edu if dim1val > len(self.tables[var]) or dim2val > len(self.tables[var][0]): 1666498Snate@binkert.org print("DIMENSION TOO LARGE AT LINE %s" % self.stat[self.pc]) 1674479Sbinkertn@umich.edu raise RuntimeError 1684479Sbinkertn@umich.edu self.tables[var][dim1val-1][dim2val-1] = self.eval(value) 1694479Sbinkertn@umich.edu 1704479Sbinkertn@umich.edu # Change the current line number 1714479Sbinkertn@umich.edu def goto(self,linenum): 1726498Snate@binkert.org if not linenum in self.prog: 1736498Snate@binkert.org print("UNDEFINED LINE NUMBER %d AT LINE %d" % (linenum, self.stat[self.pc])) 1744479Sbinkertn@umich.edu raise RuntimeError 1754479Sbinkertn@umich.edu self.pc = self.stat.index(linenum) 1764479Sbinkertn@umich.edu 1774479Sbinkertn@umich.edu # Run it 1784479Sbinkertn@umich.edu def run(self): 1794479Sbinkertn@umich.edu self.vars = { } # All variables 1804479Sbinkertn@umich.edu self.lists = { } # List variables 1814479Sbinkertn@umich.edu self.tables = { } # Tables 1824479Sbinkertn@umich.edu self.loops = [ ] # Currently active loops 1834479Sbinkertn@umich.edu self.loopend= { } # Mapping saying where loops end 1844479Sbinkertn@umich.edu self.gosub = None # Gosub return point (if any) 1854479Sbinkertn@umich.edu self.error = 0 # Indicates program error 1864479Sbinkertn@umich.edu 1876498Snate@binkert.org self.stat = list(self.prog) # Ordered list of all line numbers 1884479Sbinkertn@umich.edu self.stat.sort() 1894479Sbinkertn@umich.edu self.pc = 0 # Current program counter 1904479Sbinkertn@umich.edu 1914479Sbinkertn@umich.edu # Processing prior to running 1924479Sbinkertn@umich.edu 1934479Sbinkertn@umich.edu self.collect_data() # Collect all of the data statements 1944479Sbinkertn@umich.edu self.check_end() 1954479Sbinkertn@umich.edu self.check_loops() 1964479Sbinkertn@umich.edu 1974479Sbinkertn@umich.edu if self.error: raise RuntimeError 1984479Sbinkertn@umich.edu 1994479Sbinkertn@umich.edu while 1: 2004479Sbinkertn@umich.edu line = self.stat[self.pc] 2014479Sbinkertn@umich.edu instr = self.prog[line] 2026498Snate@binkert.org 2034479Sbinkertn@umich.edu op = instr[0] 2044479Sbinkertn@umich.edu 2054479Sbinkertn@umich.edu # END and STOP statements 2064479Sbinkertn@umich.edu if op == 'END' or op == 'STOP': 2074479Sbinkertn@umich.edu break # We're done 2084479Sbinkertn@umich.edu 2094479Sbinkertn@umich.edu # GOTO statement 2104479Sbinkertn@umich.edu elif op == 'GOTO': 2114479Sbinkertn@umich.edu newline = instr[1] 2124479Sbinkertn@umich.edu self.goto(newline) 2134479Sbinkertn@umich.edu continue 2144479Sbinkertn@umich.edu 2154479Sbinkertn@umich.edu # PRINT statement 2164479Sbinkertn@umich.edu elif op == 'PRINT': 2174479Sbinkertn@umich.edu plist = instr[1] 2184479Sbinkertn@umich.edu out = "" 2194479Sbinkertn@umich.edu for label,val in plist: 2204479Sbinkertn@umich.edu if out: 2214479Sbinkertn@umich.edu out += ' '*(15 - (len(out) % 15)) 2224479Sbinkertn@umich.edu out += label 2234479Sbinkertn@umich.edu if val: 2244479Sbinkertn@umich.edu if label: out += " " 2254479Sbinkertn@umich.edu eval = self.eval(val) 2264479Sbinkertn@umich.edu out += str(eval) 2274479Sbinkertn@umich.edu sys.stdout.write(out) 2284479Sbinkertn@umich.edu end = instr[2] 2296498Snate@binkert.org if not (end == ',' or end == ';'): 2304479Sbinkertn@umich.edu sys.stdout.write("\n") 2314479Sbinkertn@umich.edu if end == ',': sys.stdout.write(" "*(15-(len(out) % 15))) 2324479Sbinkertn@umich.edu if end == ';': sys.stdout.write(" "*(3-(len(out) % 3))) 2336498Snate@binkert.org 2344479Sbinkertn@umich.edu # LET statement 2354479Sbinkertn@umich.edu elif op == 'LET': 2364479Sbinkertn@umich.edu target = instr[1] 2374479Sbinkertn@umich.edu value = instr[2] 2384479Sbinkertn@umich.edu self.assign(target,value) 2394479Sbinkertn@umich.edu 2404479Sbinkertn@umich.edu # READ statement 2414479Sbinkertn@umich.edu elif op == 'READ': 2424479Sbinkertn@umich.edu for target in instr[1]: 2434479Sbinkertn@umich.edu if self.dc < len(self.data): 2444479Sbinkertn@umich.edu value = ('NUM',self.data[self.dc]) 2454479Sbinkertn@umich.edu self.assign(target,value) 2464479Sbinkertn@umich.edu self.dc += 1 2474479Sbinkertn@umich.edu else: 2484479Sbinkertn@umich.edu # No more data. Program ends 2494479Sbinkertn@umich.edu return 2504479Sbinkertn@umich.edu elif op == 'IF': 2514479Sbinkertn@umich.edu relop = instr[1] 2524479Sbinkertn@umich.edu newline = instr[2] 2534479Sbinkertn@umich.edu if (self.releval(relop)): 2544479Sbinkertn@umich.edu self.goto(newline) 2554479Sbinkertn@umich.edu continue 2564479Sbinkertn@umich.edu 2574479Sbinkertn@umich.edu elif op == 'FOR': 2584479Sbinkertn@umich.edu loopvar = instr[1] 2594479Sbinkertn@umich.edu initval = instr[2] 2604479Sbinkertn@umich.edu finval = instr[3] 2614479Sbinkertn@umich.edu stepval = instr[4] 2626498Snate@binkert.org 2634479Sbinkertn@umich.edu # Check to see if this is a new loop 2644479Sbinkertn@umich.edu if not self.loops or self.loops[-1][0] != self.pc: 2654479Sbinkertn@umich.edu # Looks like a new loop. Make the initial assignment 2664479Sbinkertn@umich.edu newvalue = initval 2674479Sbinkertn@umich.edu self.assign((loopvar,None,None),initval) 2684479Sbinkertn@umich.edu if not stepval: stepval = ('NUM',1) 2694479Sbinkertn@umich.edu stepval = self.eval(stepval) # Evaluate step here 2704479Sbinkertn@umich.edu self.loops.append((self.pc,stepval)) 2714479Sbinkertn@umich.edu else: 2724479Sbinkertn@umich.edu # It's a repeat of the previous loop 2734479Sbinkertn@umich.edu # Update the value of the loop variable according to the step 2744479Sbinkertn@umich.edu stepval = ('NUM',self.loops[-1][1]) 2754479Sbinkertn@umich.edu newvalue = ('BINOP','+',('VAR',(loopvar,None,None)),stepval) 2764479Sbinkertn@umich.edu 2774479Sbinkertn@umich.edu if self.loops[-1][1] < 0: relop = '>=' 2784479Sbinkertn@umich.edu else: relop = '<=' 2794479Sbinkertn@umich.edu if not self.releval(('RELOP',relop,newvalue,finval)): 2804479Sbinkertn@umich.edu # Loop is done. Jump to the NEXT 2814479Sbinkertn@umich.edu self.pc = self.loopend[self.pc] 2824479Sbinkertn@umich.edu self.loops.pop() 2834479Sbinkertn@umich.edu else: 2844479Sbinkertn@umich.edu self.assign((loopvar,None,None),newvalue) 2854479Sbinkertn@umich.edu 2864479Sbinkertn@umich.edu elif op == 'NEXT': 2874479Sbinkertn@umich.edu if not self.loops: 2886498Snate@binkert.org print("NEXT WITHOUT FOR AT LINE %s" % line) 2894479Sbinkertn@umich.edu return 2906498Snate@binkert.org 2914479Sbinkertn@umich.edu nextvar = instr[1] 2924479Sbinkertn@umich.edu self.pc = self.loops[-1][0] 2934479Sbinkertn@umich.edu loopinst = self.prog[self.stat[self.pc]] 2944479Sbinkertn@umich.edu forvar = loopinst[1] 2954479Sbinkertn@umich.edu if nextvar != forvar: 2966498Snate@binkert.org print("NEXT DOESN'T MATCH FOR AT LINE %s" % line) 2974479Sbinkertn@umich.edu return 2984479Sbinkertn@umich.edu continue 2994479Sbinkertn@umich.edu elif op == 'GOSUB': 3004479Sbinkertn@umich.edu newline = instr[1] 3014479Sbinkertn@umich.edu if self.gosub: 3026498Snate@binkert.org print("ALREADY IN A SUBROUTINE AT LINE %s" % line) 3034479Sbinkertn@umich.edu return 3044479Sbinkertn@umich.edu self.gosub = self.stat[self.pc] 3054479Sbinkertn@umich.edu self.goto(newline) 3064479Sbinkertn@umich.edu continue 3074479Sbinkertn@umich.edu 3084479Sbinkertn@umich.edu elif op == 'RETURN': 3094479Sbinkertn@umich.edu if not self.gosub: 3106498Snate@binkert.org print("RETURN WITHOUT A GOSUB AT LINE %s" % line) 3114479Sbinkertn@umich.edu return 3124479Sbinkertn@umich.edu self.goto(self.gosub) 3134479Sbinkertn@umich.edu self.gosub = None 3144479Sbinkertn@umich.edu 3154479Sbinkertn@umich.edu elif op == 'FUNC': 3164479Sbinkertn@umich.edu fname = instr[1] 3174479Sbinkertn@umich.edu pname = instr[2] 3184479Sbinkertn@umich.edu expr = instr[3] 3194479Sbinkertn@umich.edu def eval_func(pvalue,name=pname,self=self,expr=expr): 3204479Sbinkertn@umich.edu self.assign((pname,None,None),pvalue) 3214479Sbinkertn@umich.edu return self.eval(expr) 3224479Sbinkertn@umich.edu self.functions[fname] = eval_func 3234479Sbinkertn@umich.edu 3244479Sbinkertn@umich.edu elif op == 'DIM': 3254479Sbinkertn@umich.edu for vname,x,y in instr[1]: 3264479Sbinkertn@umich.edu if y == 0: 3274479Sbinkertn@umich.edu # Single dimension variable 3284479Sbinkertn@umich.edu self.lists[vname] = [0]*x 3294479Sbinkertn@umich.edu else: 3304479Sbinkertn@umich.edu # Double dimension variable 3314479Sbinkertn@umich.edu temp = [0]*y 3324479Sbinkertn@umich.edu v = [] 3334479Sbinkertn@umich.edu for i in range(x): 3344479Sbinkertn@umich.edu v.append(temp[:]) 3354479Sbinkertn@umich.edu self.tables[vname] = v 3364479Sbinkertn@umich.edu 3376498Snate@binkert.org self.pc += 1 3384479Sbinkertn@umich.edu 3394479Sbinkertn@umich.edu # Utility functions for program listing 3404479Sbinkertn@umich.edu def expr_str(self,expr): 3414479Sbinkertn@umich.edu etype = expr[0] 3424479Sbinkertn@umich.edu if etype == 'NUM': return str(expr[1]) 3434479Sbinkertn@umich.edu elif etype == 'GROUP': return "(%s)" % self.expr_str(expr[1]) 3444479Sbinkertn@umich.edu elif etype == 'UNARY': 3454479Sbinkertn@umich.edu if expr[1] == '-': return "-"+str(expr[2]) 3464479Sbinkertn@umich.edu elif etype == 'BINOP': 3474479Sbinkertn@umich.edu return "%s %s %s" % (self.expr_str(expr[2]),expr[1],self.expr_str(expr[3])) 3484479Sbinkertn@umich.edu elif etype == 'VAR': 3494479Sbinkertn@umich.edu return self.var_str(expr[1]) 3504479Sbinkertn@umich.edu 3514479Sbinkertn@umich.edu def relexpr_str(self,expr): 3524479Sbinkertn@umich.edu return "%s %s %s" % (self.expr_str(expr[2]),expr[1],self.expr_str(expr[3])) 3534479Sbinkertn@umich.edu 3544479Sbinkertn@umich.edu def var_str(self,var): 3554479Sbinkertn@umich.edu varname,dim1,dim2 = var 3564479Sbinkertn@umich.edu if not dim1 and not dim2: return varname 3574479Sbinkertn@umich.edu if dim1 and not dim2: return "%s(%s)" % (varname, self.expr_str(dim1)) 3584479Sbinkertn@umich.edu return "%s(%s,%s)" % (varname, self.expr_str(dim1),self.expr_str(dim2)) 3594479Sbinkertn@umich.edu 3604479Sbinkertn@umich.edu # Create a program listing 3614479Sbinkertn@umich.edu def list(self): 3626498Snate@binkert.org stat = list(self.prog) # Ordered list of all line numbers 3634479Sbinkertn@umich.edu stat.sort() 3644479Sbinkertn@umich.edu for line in stat: 3654479Sbinkertn@umich.edu instr = self.prog[line] 3664479Sbinkertn@umich.edu op = instr[0] 3674479Sbinkertn@umich.edu if op in ['END','STOP','RETURN']: 3686498Snate@binkert.org print("%s %s" % (line, op)) 3694479Sbinkertn@umich.edu continue 3704479Sbinkertn@umich.edu elif op == 'REM': 3716498Snate@binkert.org print("%s %s" % (line, instr[1])) 3724479Sbinkertn@umich.edu elif op == 'PRINT': 3736498Snate@binkert.org _out = "%s %s " % (line, op) 3744479Sbinkertn@umich.edu first = 1 3754479Sbinkertn@umich.edu for p in instr[1]: 3766498Snate@binkert.org if not first: _out += ", " 3776498Snate@binkert.org if p[0] and p[1]: _out += '"%s"%s' % (p[0],self.expr_str(p[1])) 3786498Snate@binkert.org elif p[1]: _out += self.expr_str(p[1]) 3796498Snate@binkert.org else: _out += '"%s"' % (p[0],) 3804479Sbinkertn@umich.edu first = 0 3816498Snate@binkert.org if instr[2]: _out += instr[2] 3826498Snate@binkert.org print(_out) 3834479Sbinkertn@umich.edu elif op == 'LET': 3846498Snate@binkert.org print("%s LET %s = %s" % (line,self.var_str(instr[1]),self.expr_str(instr[2]))) 3854479Sbinkertn@umich.edu elif op == 'READ': 3866498Snate@binkert.org _out = "%s READ " % line 3874479Sbinkertn@umich.edu first = 1 3884479Sbinkertn@umich.edu for r in instr[1]: 3896498Snate@binkert.org if not first: _out += "," 3906498Snate@binkert.org _out += self.var_str(r) 3914479Sbinkertn@umich.edu first = 0 3926498Snate@binkert.org print(_out) 3934479Sbinkertn@umich.edu elif op == 'IF': 3946498Snate@binkert.org print("%s IF %s THEN %d" % (line,self.relexpr_str(instr[1]),instr[2])) 3954479Sbinkertn@umich.edu elif op == 'GOTO' or op == 'GOSUB': 3966498Snate@binkert.org print("%s %s %s" % (line, op, instr[1])) 3974479Sbinkertn@umich.edu elif op == 'FOR': 3986498Snate@binkert.org _out = "%s FOR %s = %s TO %s" % (line,instr[1],self.expr_str(instr[2]),self.expr_str(instr[3])) 3996498Snate@binkert.org if instr[4]: _out += " STEP %s" % (self.expr_str(instr[4])) 4006498Snate@binkert.org print(_out) 4014479Sbinkertn@umich.edu elif op == 'NEXT': 4026498Snate@binkert.org print("%s NEXT %s" % (line, instr[1])) 4034479Sbinkertn@umich.edu elif op == 'FUNC': 4046498Snate@binkert.org print("%s DEF %s(%s) = %s" % (line,instr[1],instr[2],self.expr_str(instr[3]))) 4054479Sbinkertn@umich.edu elif op == 'DIM': 4066498Snate@binkert.org _out = "%s DIM " % line 4074479Sbinkertn@umich.edu first = 1 4084479Sbinkertn@umich.edu for vname,x,y in instr[1]: 4096498Snate@binkert.org if not first: _out += "," 4104479Sbinkertn@umich.edu first = 0 4114479Sbinkertn@umich.edu if y == 0: 4126498Snate@binkert.org _out += "%s(%d)" % (vname,x) 4134479Sbinkertn@umich.edu else: 4146498Snate@binkert.org _out += "%s(%d,%d)" % (vname,x,y) 4156498Snate@binkert.org 4166498Snate@binkert.org print(_out) 4174479Sbinkertn@umich.edu elif op == 'DATA': 4186498Snate@binkert.org _out = "%s DATA " % line 4194479Sbinkertn@umich.edu first = 1 4204479Sbinkertn@umich.edu for v in instr[1]: 4216498Snate@binkert.org if not first: _out += "," 4224479Sbinkertn@umich.edu first = 0 4236498Snate@binkert.org _out += v 4246498Snate@binkert.org print(_out) 4254479Sbinkertn@umich.edu 4264479Sbinkertn@umich.edu # Erase the current program 4274479Sbinkertn@umich.edu def new(self): 4284479Sbinkertn@umich.edu self.prog = {} 4296498Snate@binkert.org 4304479Sbinkertn@umich.edu # Insert statements 4314479Sbinkertn@umich.edu def add_statements(self,prog): 4324479Sbinkertn@umich.edu for line,stat in prog.items(): 4334479Sbinkertn@umich.edu self.prog[line] = stat 4344479Sbinkertn@umich.edu 4354479Sbinkertn@umich.edu # Delete a statement 4364479Sbinkertn@umich.edu def del_line(self,lineno): 4374479Sbinkertn@umich.edu try: 4384479Sbinkertn@umich.edu del self.prog[lineno] 4394479Sbinkertn@umich.edu except KeyError: 4404479Sbinkertn@umich.edu pass 4414479Sbinkertn@umich.edu 442