annotate ply-3.8/example/BASIC/basinterp.py @ 12254:616be78bd12e draft

<oerjan> revert
author HackEso <hackeso@esolangs.org>
date Fri, 06 Dec 2019 07:54:58 +0000
parents 343ff337a19b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7267
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1 # This file provides the runtime support for running a basic program
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2 # Assumes the program has been parsed using basparse.py
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
4 import sys
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
5 import math
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
6 import random
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
7
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
8 class BasicInterpreter:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
9
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
10 # Initialize the interpreter. prog is a dictionary
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
11 # containing (line,statement) mappings
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
12 def __init__(self,prog):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
13 self.prog = prog
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
14
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
15 self.functions = { # Built-in function table
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
16 'SIN' : lambda z: math.sin(self.eval(z)),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
17 'COS' : lambda z: math.cos(self.eval(z)),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
18 'TAN' : lambda z: math.tan(self.eval(z)),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
19 'ATN' : lambda z: math.atan(self.eval(z)),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
20 'EXP' : lambda z: math.exp(self.eval(z)),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
21 'ABS' : lambda z: abs(self.eval(z)),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
22 'LOG' : lambda z: math.log(self.eval(z)),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
23 'SQR' : lambda z: math.sqrt(self.eval(z)),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
24 'INT' : lambda z: int(self.eval(z)),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
25 'RND' : lambda z: random.random()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
26 }
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
27
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
28 # Collect all data statements
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
29 def collect_data(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
30 self.data = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
31 for lineno in self.stat:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
32 if self.prog[lineno][0] == 'DATA':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
33 self.data = self.data + self.prog[lineno][1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
34 self.dc = 0 # Initialize the data counter
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
35
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
36 # Check for end statements
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
37 def check_end(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
38 has_end = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
39 for lineno in self.stat:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
40 if self.prog[lineno][0] == 'END' and not has_end:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
41 has_end = lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
42 if not has_end:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
43 print("NO END INSTRUCTION")
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
44 self.error = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
45 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
46 if has_end != lineno:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
47 print("END IS NOT LAST")
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
48 self.error = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
49
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
50 # Check loops
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
51 def check_loops(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
52 for pc in range(len(self.stat)):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
53 lineno = self.stat[pc]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
54 if self.prog[lineno][0] == 'FOR':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
55 forinst = self.prog[lineno]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
56 loopvar = forinst[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
57 for i in range(pc+1,len(self.stat)):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
58 if self.prog[self.stat[i]][0] == 'NEXT':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
59 nextvar = self.prog[self.stat[i]][1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
60 if nextvar != loopvar: continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
61 self.loopend[pc] = i
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
62 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
63 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
64 print("FOR WITHOUT NEXT AT LINE %s" % self.stat[pc])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
65 self.error = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
66
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
67 # Evaluate an expression
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
68 def eval(self,expr):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
69 etype = expr[0]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
70 if etype == 'NUM': return expr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
71 elif etype == 'GROUP': return self.eval(expr[1])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
72 elif etype == 'UNARY':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
73 if expr[1] == '-': return -self.eval(expr[2])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
74 elif etype == 'BINOP':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
75 if expr[1] == '+': return self.eval(expr[2])+self.eval(expr[3])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
76 elif expr[1] == '-': return self.eval(expr[2])-self.eval(expr[3])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
77 elif expr[1] == '*': return self.eval(expr[2])*self.eval(expr[3])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
78 elif expr[1] == '/': return float(self.eval(expr[2]))/self.eval(expr[3])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
79 elif expr[1] == '^': return abs(self.eval(expr[2]))**self.eval(expr[3])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
80 elif etype == 'VAR':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
81 var,dim1,dim2 = expr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
82 if not dim1 and not dim2:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
83 if var in self.vars:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
84 return self.vars[var]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
85 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
86 print("UNDEFINED VARIABLE %s AT LINE %s" % (var, self.stat[self.pc]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
87 raise RuntimeError
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
88 # May be a list lookup or a function evaluation
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
89 if dim1 and not dim2:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
90 if var in self.functions:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
91 # A function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
92 return self.functions[var](dim1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
93 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
94 # A list evaluation
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
95 if var in self.lists:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
96 dim1val = self.eval(dim1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
97 if dim1val < 1 or dim1val > len(self.lists[var]):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
98 print("LIST INDEX OUT OF BOUNDS AT LINE %s" % self.stat[self.pc])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
99 raise RuntimeError
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
100 return self.lists[var][dim1val-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
101 if dim1 and dim2:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
102 if var in self.tables:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
103 dim1val = self.eval(dim1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
104 dim2val = self.eval(dim2)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
105 if dim1val < 1 or dim1val > len(self.tables[var]) or dim2val < 1 or dim2val > len(self.tables[var][0]):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
106 print("TABLE INDEX OUT OUT BOUNDS AT LINE %s" % self.stat[self.pc])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
107 raise RuntimeError
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
108 return self.tables[var][dim1val-1][dim2val-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
109 print("UNDEFINED VARIABLE %s AT LINE %s" % (var, self.stat[self.pc]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
110 raise RuntimeError
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
111
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
112 # Evaluate a relational expression
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
113 def releval(self,expr):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
114 etype = expr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
115 lhs = self.eval(expr[2])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
116 rhs = self.eval(expr[3])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
117 if etype == '<':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
118 if lhs < rhs: return 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
119 else: return 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
120
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
121 elif etype == '<=':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
122 if lhs <= rhs: return 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
123 else: return 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
124
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
125 elif etype == '>':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
126 if lhs > rhs: return 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
127 else: return 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
128
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
129 elif etype == '>=':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
130 if lhs >= rhs: return 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
131 else: return 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
132
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
133 elif etype == '=':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
134 if lhs == rhs: return 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
135 else: return 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
136
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
137 elif etype == '<>':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
138 if lhs != rhs: return 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
139 else: return 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
140
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
141 # Assignment
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
142 def assign(self,target,value):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
143 var, dim1, dim2 = target
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
144 if not dim1 and not dim2:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
145 self.vars[var] = self.eval(value)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
146 elif dim1 and not dim2:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
147 # List assignment
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
148 dim1val = self.eval(dim1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
149 if not var in self.lists:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
150 self.lists[var] = [0]*10
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
151
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
152 if dim1val > len(self.lists[var]):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
153 print ("DIMENSION TOO LARGE AT LINE %s" % self.stat[self.pc])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
154 raise RuntimeError
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
155 self.lists[var][dim1val-1] = self.eval(value)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
156 elif dim1 and dim2:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
157 dim1val = self.eval(dim1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
158 dim2val = self.eval(dim2)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
159 if not var in self.tables:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
160 temp = [0]*10
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
161 v = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
162 for i in range(10): v.append(temp[:])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
163 self.tables[var] = v
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
164 # Variable already exists
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
165 if dim1val > len(self.tables[var]) or dim2val > len(self.tables[var][0]):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
166 print("DIMENSION TOO LARGE AT LINE %s" % self.stat[self.pc])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
167 raise RuntimeError
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
168 self.tables[var][dim1val-1][dim2val-1] = self.eval(value)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
169
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
170 # Change the current line number
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
171 def goto(self,linenum):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
172 if not linenum in self.prog:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
173 print("UNDEFINED LINE NUMBER %d AT LINE %d" % (linenum, self.stat[self.pc]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
174 raise RuntimeError
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
175 self.pc = self.stat.index(linenum)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
176
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
177 # Run it
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
178 def run(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
179 self.vars = { } # All variables
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
180 self.lists = { } # List variables
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
181 self.tables = { } # Tables
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
182 self.loops = [ ] # Currently active loops
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
183 self.loopend= { } # Mapping saying where loops end
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
184 self.gosub = None # Gosub return point (if any)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
185 self.error = 0 # Indicates program error
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
186
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
187 self.stat = list(self.prog) # Ordered list of all line numbers
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
188 self.stat.sort()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
189 self.pc = 0 # Current program counter
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
190
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
191 # Processing prior to running
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
192
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
193 self.collect_data() # Collect all of the data statements
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
194 self.check_end()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
195 self.check_loops()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
196
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
197 if self.error: raise RuntimeError
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
198
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
199 while 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
200 line = self.stat[self.pc]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
201 instr = self.prog[line]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
202
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
203 op = instr[0]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
204
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
205 # END and STOP statements
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
206 if op == 'END' or op == 'STOP':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
207 break # We're done
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
208
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
209 # GOTO statement
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
210 elif op == 'GOTO':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
211 newline = instr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
212 self.goto(newline)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
213 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
214
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
215 # PRINT statement
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
216 elif op == 'PRINT':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
217 plist = instr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
218 out = ""
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
219 for label,val in plist:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
220 if out:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
221 out += ' '*(15 - (len(out) % 15))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
222 out += label
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
223 if val:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
224 if label: out += " "
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
225 eval = self.eval(val)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
226 out += str(eval)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
227 sys.stdout.write(out)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
228 end = instr[2]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
229 if not (end == ',' or end == ';'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
230 sys.stdout.write("\n")
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
231 if end == ',': sys.stdout.write(" "*(15-(len(out) % 15)))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
232 if end == ';': sys.stdout.write(" "*(3-(len(out) % 3)))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
233
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
234 # LET statement
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
235 elif op == 'LET':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
236 target = instr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
237 value = instr[2]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
238 self.assign(target,value)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
239
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
240 # READ statement
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
241 elif op == 'READ':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
242 for target in instr[1]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
243 if self.dc < len(self.data):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
244 value = ('NUM',self.data[self.dc])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
245 self.assign(target,value)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
246 self.dc += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
247 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
248 # No more data. Program ends
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
249 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
250 elif op == 'IF':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
251 relop = instr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
252 newline = instr[2]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
253 if (self.releval(relop)):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
254 self.goto(newline)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
255 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
256
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
257 elif op == 'FOR':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
258 loopvar = instr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
259 initval = instr[2]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
260 finval = instr[3]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
261 stepval = instr[4]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
262
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
263 # Check to see if this is a new loop
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
264 if not self.loops or self.loops[-1][0] != self.pc:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
265 # Looks like a new loop. Make the initial assignment
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
266 newvalue = initval
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
267 self.assign((loopvar,None,None),initval)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
268 if not stepval: stepval = ('NUM',1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
269 stepval = self.eval(stepval) # Evaluate step here
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
270 self.loops.append((self.pc,stepval))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
271 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
272 # It's a repeat of the previous loop
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
273 # Update the value of the loop variable according to the step
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
274 stepval = ('NUM',self.loops[-1][1])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
275 newvalue = ('BINOP','+',('VAR',(loopvar,None,None)),stepval)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
276
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
277 if self.loops[-1][1] < 0: relop = '>='
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
278 else: relop = '<='
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
279 if not self.releval(('RELOP',relop,newvalue,finval)):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
280 # Loop is done. Jump to the NEXT
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
281 self.pc = self.loopend[self.pc]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
282 self.loops.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
283 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
284 self.assign((loopvar,None,None),newvalue)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
285
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
286 elif op == 'NEXT':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
287 if not self.loops:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
288 print("NEXT WITHOUT FOR AT LINE %s" % line)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
289 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
290
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
291 nextvar = instr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
292 self.pc = self.loops[-1][0]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
293 loopinst = self.prog[self.stat[self.pc]]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
294 forvar = loopinst[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
295 if nextvar != forvar:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
296 print("NEXT DOESN'T MATCH FOR AT LINE %s" % line)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
297 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
298 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
299 elif op == 'GOSUB':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
300 newline = instr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
301 if self.gosub:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
302 print("ALREADY IN A SUBROUTINE AT LINE %s" % line)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
303 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
304 self.gosub = self.stat[self.pc]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
305 self.goto(newline)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
306 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
307
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
308 elif op == 'RETURN':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
309 if not self.gosub:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
310 print("RETURN WITHOUT A GOSUB AT LINE %s" % line)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
311 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
312 self.goto(self.gosub)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
313 self.gosub = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
314
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
315 elif op == 'FUNC':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
316 fname = instr[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
317 pname = instr[2]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
318 expr = instr[3]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
319 def eval_func(pvalue,name=pname,self=self,expr=expr):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
320 self.assign((pname,None,None),pvalue)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
321 return self.eval(expr)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
322 self.functions[fname] = eval_func
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
323
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
324 elif op == 'DIM':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
325 for vname,x,y in instr[1]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
326 if y == 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
327 # Single dimension variable
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
328 self.lists[vname] = [0]*x
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
329 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
330 # Double dimension variable
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
331 temp = [0]*y
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
332 v = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
333 for i in range(x):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
334 v.append(temp[:])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
335 self.tables[vname] = v
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
336
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
337 self.pc += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
338
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
339 # Utility functions for program listing
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
340 def expr_str(self,expr):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
341 etype = expr[0]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
342 if etype == 'NUM': return str(expr[1])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
343 elif etype == 'GROUP': return "(%s)" % self.expr_str(expr[1])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
344 elif etype == 'UNARY':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
345 if expr[1] == '-': return "-"+str(expr[2])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
346 elif etype == 'BINOP':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
347 return "%s %s %s" % (self.expr_str(expr[2]),expr[1],self.expr_str(expr[3]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
348 elif etype == 'VAR':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
349 return self.var_str(expr[1])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
350
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
351 def relexpr_str(self,expr):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
352 return "%s %s %s" % (self.expr_str(expr[2]),expr[1],self.expr_str(expr[3]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
353
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
354 def var_str(self,var):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
355 varname,dim1,dim2 = var
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
356 if not dim1 and not dim2: return varname
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
357 if dim1 and not dim2: return "%s(%s)" % (varname, self.expr_str(dim1))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
358 return "%s(%s,%s)" % (varname, self.expr_str(dim1),self.expr_str(dim2))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
359
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
360 # Create a program listing
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
361 def list(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
362 stat = list(self.prog) # Ordered list of all line numbers
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
363 stat.sort()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
364 for line in stat:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
365 instr = self.prog[line]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
366 op = instr[0]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
367 if op in ['END','STOP','RETURN']:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
368 print("%s %s" % (line, op))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
369 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
370 elif op == 'REM':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
371 print("%s %s" % (line, instr[1]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
372 elif op == 'PRINT':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
373 _out = "%s %s " % (line, op)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
374 first = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
375 for p in instr[1]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
376 if not first: _out += ", "
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
377 if p[0] and p[1]: _out += '"%s"%s' % (p[0],self.expr_str(p[1]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
378 elif p[1]: _out += self.expr_str(p[1])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
379 else: _out += '"%s"' % (p[0],)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
380 first = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
381 if instr[2]: _out += instr[2]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
382 print(_out)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
383 elif op == 'LET':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
384 print("%s LET %s = %s" % (line,self.var_str(instr[1]),self.expr_str(instr[2])))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
385 elif op == 'READ':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
386 _out = "%s READ " % line
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
387 first = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
388 for r in instr[1]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
389 if not first: _out += ","
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
390 _out += self.var_str(r)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
391 first = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
392 print(_out)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
393 elif op == 'IF':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
394 print("%s IF %s THEN %d" % (line,self.relexpr_str(instr[1]),instr[2]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
395 elif op == 'GOTO' or op == 'GOSUB':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
396 print("%s %s %s" % (line, op, instr[1]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
397 elif op == 'FOR':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
398 _out = "%s FOR %s = %s TO %s" % (line,instr[1],self.expr_str(instr[2]),self.expr_str(instr[3]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
399 if instr[4]: _out += " STEP %s" % (self.expr_str(instr[4]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
400 print(_out)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
401 elif op == 'NEXT':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
402 print("%s NEXT %s" % (line, instr[1]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
403 elif op == 'FUNC':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
404 print("%s DEF %s(%s) = %s" % (line,instr[1],instr[2],self.expr_str(instr[3])))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
405 elif op == 'DIM':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
406 _out = "%s DIM " % line
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
407 first = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
408 for vname,x,y in instr[1]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
409 if not first: _out += ","
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
410 first = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
411 if y == 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
412 _out += "%s(%d)" % (vname,x)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
413 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
414 _out += "%s(%d,%d)" % (vname,x,y)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
415
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
416 print(_out)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
417 elif op == 'DATA':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
418 _out = "%s DATA " % line
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
419 first = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
420 for v in instr[1]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
421 if not first: _out += ","
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
422 first = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
423 _out += v
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
424 print(_out)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
425
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
426 # Erase the current program
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
427 def new(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
428 self.prog = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
429
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
430 # Insert statements
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
431 def add_statements(self,prog):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
432 for line,stat in prog.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
433 self.prog[line] = stat
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
434
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
435 # Delete a statement
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
436 def del_line(self,lineno):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
437 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
438 del self.prog[lineno]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
439 except KeyError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
440 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
441