diff options
Diffstat (limited to 'components/script/dom/bindings/codegen/ply/example/BASIC/basinterp.py')
-rw-r--r-- | components/script/dom/bindings/codegen/ply/example/BASIC/basinterp.py | 496 |
1 files changed, 0 insertions, 496 deletions
diff --git a/components/script/dom/bindings/codegen/ply/example/BASIC/basinterp.py b/components/script/dom/bindings/codegen/ply/example/BASIC/basinterp.py deleted file mode 100644 index 67762c797bf..00000000000 --- a/components/script/dom/bindings/codegen/ply/example/BASIC/basinterp.py +++ /dev/null @@ -1,496 +0,0 @@ -# This file provides the runtime support for running a basic program -# Assumes the program has been parsed using basparse.py - -import sys -import math -import random - - -class BasicInterpreter: - - # Initialize the interpreter. prog is a dictionary - # containing (line,statement) mappings - def __init__(self, prog): - self.prog = prog - - self.functions = { # Built-in function table - 'SIN': lambda z: math.sin(self.eval(z)), - 'COS': lambda z: math.cos(self.eval(z)), - 'TAN': lambda z: math.tan(self.eval(z)), - 'ATN': lambda z: math.atan(self.eval(z)), - 'EXP': lambda z: math.exp(self.eval(z)), - 'ABS': lambda z: abs(self.eval(z)), - 'LOG': lambda z: math.log(self.eval(z)), - 'SQR': lambda z: math.sqrt(self.eval(z)), - 'INT': lambda z: int(self.eval(z)), - 'RND': lambda z: random.random() - } - - # Collect all data statements - def collect_data(self): - self.data = [] - for lineno in self.stat: - if self.prog[lineno][0] == 'DATA': - self.data = self.data + self.prog[lineno][1] - self.dc = 0 # Initialize the data counter - - # Check for end statements - def check_end(self): - has_end = 0 - for lineno in self.stat: - if self.prog[lineno][0] == 'END' and not has_end: - has_end = lineno - if not has_end: - print("NO END INSTRUCTION") - self.error = 1 - return - if has_end != lineno: - print("END IS NOT LAST") - self.error = 1 - - # Check loops - def check_loops(self): - for pc in range(len(self.stat)): - lineno = self.stat[pc] - if self.prog[lineno][0] == 'FOR': - forinst = self.prog[lineno] - loopvar = forinst[1] - for i in range(pc + 1, len(self.stat)): - if self.prog[self.stat[i]][0] == 'NEXT': - nextvar = self.prog[self.stat[i]][1] - if nextvar != loopvar: - continue - self.loopend[pc] = i - break - else: - print("FOR WITHOUT NEXT AT LINE %s" % self.stat[pc]) - self.error = 1 - - # Evaluate an expression - def eval(self, expr): - etype = expr[0] - if etype == 'NUM': - return expr[1] - elif etype == 'GROUP': - return self.eval(expr[1]) - elif etype == 'UNARY': - if expr[1] == '-': - return -self.eval(expr[2]) - elif etype == 'BINOP': - if expr[1] == '+': - return self.eval(expr[2]) + self.eval(expr[3]) - elif expr[1] == '-': - return self.eval(expr[2]) - self.eval(expr[3]) - elif expr[1] == '*': - return self.eval(expr[2]) * self.eval(expr[3]) - elif expr[1] == '/': - return float(self.eval(expr[2])) / self.eval(expr[3]) - elif expr[1] == '^': - return abs(self.eval(expr[2]))**self.eval(expr[3]) - elif etype == 'VAR': - var, dim1, dim2 = expr[1] - if not dim1 and not dim2: - if var in self.vars: - return self.vars[var] - else: - print("UNDEFINED VARIABLE %s AT LINE %s" % - (var, self.stat[self.pc])) - raise RuntimeError - # May be a list lookup or a function evaluation - if dim1 and not dim2: - if var in self.functions: - # A function - return self.functions[var](dim1) - else: - # A list evaluation - if var in self.lists: - dim1val = self.eval(dim1) - if dim1val < 1 or dim1val > len(self.lists[var]): - print("LIST INDEX OUT OF BOUNDS AT LINE %s" % - self.stat[self.pc]) - raise RuntimeError - return self.lists[var][dim1val - 1] - if dim1 and dim2: - if var in self.tables: - dim1val = self.eval(dim1) - dim2val = self.eval(dim2) - if dim1val < 1 or dim1val > len(self.tables[var]) or dim2val < 1 or dim2val > len(self.tables[var][0]): - print("TABLE INDEX OUT OUT BOUNDS AT LINE %s" % - self.stat[self.pc]) - raise RuntimeError - return self.tables[var][dim1val - 1][dim2val - 1] - print("UNDEFINED VARIABLE %s AT LINE %s" % - (var, self.stat[self.pc])) - raise RuntimeError - - # Evaluate a relational expression - def releval(self, expr): - etype = expr[1] - lhs = self.eval(expr[2]) - rhs = self.eval(expr[3]) - if etype == '<': - if lhs < rhs: - return 1 - else: - return 0 - - elif etype == '<=': - if lhs <= rhs: - return 1 - else: - return 0 - - elif etype == '>': - if lhs > rhs: - return 1 - else: - return 0 - - elif etype == '>=': - if lhs >= rhs: - return 1 - else: - return 0 - - elif etype == '=': - if lhs == rhs: - return 1 - else: - return 0 - - elif etype == '<>': - if lhs != rhs: - return 1 - else: - return 0 - - # Assignment - def assign(self, target, value): - var, dim1, dim2 = target - if not dim1 and not dim2: - self.vars[var] = self.eval(value) - elif dim1 and not dim2: - # List assignment - dim1val = self.eval(dim1) - if not var in self.lists: - self.lists[var] = [0] * 10 - - if dim1val > len(self.lists[var]): - print ("DIMENSION TOO LARGE AT LINE %s" % self.stat[self.pc]) - raise RuntimeError - self.lists[var][dim1val - 1] = self.eval(value) - elif dim1 and dim2: - dim1val = self.eval(dim1) - dim2val = self.eval(dim2) - if not var in self.tables: - temp = [0] * 10 - v = [] - for i in range(10): - v.append(temp[:]) - self.tables[var] = v - # Variable already exists - if dim1val > len(self.tables[var]) or dim2val > len(self.tables[var][0]): - print("DIMENSION TOO LARGE AT LINE %s" % self.stat[self.pc]) - raise RuntimeError - self.tables[var][dim1val - 1][dim2val - 1] = self.eval(value) - - # Change the current line number - def goto(self, linenum): - if not linenum in self.prog: - print("UNDEFINED LINE NUMBER %d AT LINE %d" % - (linenum, self.stat[self.pc])) - raise RuntimeError - self.pc = self.stat.index(linenum) - - # Run it - def run(self): - self.vars = {} # All variables - self.lists = {} # List variables - self.tables = {} # Tables - self.loops = [] # Currently active loops - self.loopend = {} # Mapping saying where loops end - self.gosub = None # Gosub return point (if any) - self.error = 0 # Indicates program error - - self.stat = list(self.prog) # Ordered list of all line numbers - self.stat.sort() - self.pc = 0 # Current program counter - - # Processing prior to running - - self.collect_data() # Collect all of the data statements - self.check_end() - self.check_loops() - - if self.error: - raise RuntimeError - - while 1: - line = self.stat[self.pc] - instr = self.prog[line] - - op = instr[0] - - # END and STOP statements - if op == 'END' or op == 'STOP': - break # We're done - - # GOTO statement - elif op == 'GOTO': - newline = instr[1] - self.goto(newline) - continue - - # PRINT statement - elif op == 'PRINT': - plist = instr[1] - out = "" - for label, val in plist: - if out: - out += ' ' * (15 - (len(out) % 15)) - out += label - if val: - if label: - out += " " - eval = self.eval(val) - out += str(eval) - sys.stdout.write(out) - end = instr[2] - if not (end == ',' or end == ';'): - sys.stdout.write("\n") - if end == ',': - sys.stdout.write(" " * (15 - (len(out) % 15))) - if end == ';': - sys.stdout.write(" " * (3 - (len(out) % 3))) - - # LET statement - elif op == 'LET': - target = instr[1] - value = instr[2] - self.assign(target, value) - - # READ statement - elif op == 'READ': - for target in instr[1]: - if self.dc < len(self.data): - value = ('NUM', self.data[self.dc]) - self.assign(target, value) - self.dc += 1 - else: - # No more data. Program ends - return - elif op == 'IF': - relop = instr[1] - newline = instr[2] - if (self.releval(relop)): - self.goto(newline) - continue - - elif op == 'FOR': - loopvar = instr[1] - initval = instr[2] - finval = instr[3] - stepval = instr[4] - - # Check to see if this is a new loop - if not self.loops or self.loops[-1][0] != self.pc: - # Looks like a new loop. Make the initial assignment - newvalue = initval - self.assign((loopvar, None, None), initval) - if not stepval: - stepval = ('NUM', 1) - stepval = self.eval(stepval) # Evaluate step here - self.loops.append((self.pc, stepval)) - else: - # It's a repeat of the previous loop - # Update the value of the loop variable according to the - # step - stepval = ('NUM', self.loops[-1][1]) - newvalue = ( - 'BINOP', '+', ('VAR', (loopvar, None, None)), stepval) - - if self.loops[-1][1] < 0: - relop = '>=' - else: - relop = '<=' - if not self.releval(('RELOP', relop, newvalue, finval)): - # Loop is done. Jump to the NEXT - self.pc = self.loopend[self.pc] - self.loops.pop() - else: - self.assign((loopvar, None, None), newvalue) - - elif op == 'NEXT': - if not self.loops: - print("NEXT WITHOUT FOR AT LINE %s" % line) - return - - nextvar = instr[1] - self.pc = self.loops[-1][0] - loopinst = self.prog[self.stat[self.pc]] - forvar = loopinst[1] - if nextvar != forvar: - print("NEXT DOESN'T MATCH FOR AT LINE %s" % line) - return - continue - elif op == 'GOSUB': - newline = instr[1] - if self.gosub: - print("ALREADY IN A SUBROUTINE AT LINE %s" % line) - return - self.gosub = self.stat[self.pc] - self.goto(newline) - continue - - elif op == 'RETURN': - if not self.gosub: - print("RETURN WITHOUT A GOSUB AT LINE %s" % line) - return - self.goto(self.gosub) - self.gosub = None - - elif op == 'FUNC': - fname = instr[1] - pname = instr[2] - expr = instr[3] - - def eval_func(pvalue, name=pname, self=self, expr=expr): - self.assign((pname, None, None), pvalue) - return self.eval(expr) - self.functions[fname] = eval_func - - elif op == 'DIM': - for vname, x, y in instr[1]: - if y == 0: - # Single dimension variable - self.lists[vname] = [0] * x - else: - # Double dimension variable - temp = [0] * y - v = [] - for i in range(x): - v.append(temp[:]) - self.tables[vname] = v - - self.pc += 1 - - # Utility functions for program listing - def expr_str(self, expr): - etype = expr[0] - if etype == 'NUM': - return str(expr[1]) - elif etype == 'GROUP': - return "(%s)" % self.expr_str(expr[1]) - elif etype == 'UNARY': - if expr[1] == '-': - return "-" + str(expr[2]) - elif etype == 'BINOP': - return "%s %s %s" % (self.expr_str(expr[2]), expr[1], self.expr_str(expr[3])) - elif etype == 'VAR': - return self.var_str(expr[1]) - - def relexpr_str(self, expr): - return "%s %s %s" % (self.expr_str(expr[2]), expr[1], self.expr_str(expr[3])) - - def var_str(self, var): - varname, dim1, dim2 = var - if not dim1 and not dim2: - return varname - if dim1 and not dim2: - return "%s(%s)" % (varname, self.expr_str(dim1)) - return "%s(%s,%s)" % (varname, self.expr_str(dim1), self.expr_str(dim2)) - - # Create a program listing - def list(self): - stat = list(self.prog) # Ordered list of all line numbers - stat.sort() - for line in stat: - instr = self.prog[line] - op = instr[0] - if op in ['END', 'STOP', 'RETURN']: - print("%s %s" % (line, op)) - continue - elif op == 'REM': - print("%s %s" % (line, instr[1])) - elif op == 'PRINT': - _out = "%s %s " % (line, op) - first = 1 - for p in instr[1]: - if not first: - _out += ", " - if p[0] and p[1]: - _out += '"%s"%s' % (p[0], self.expr_str(p[1])) - elif p[1]: - _out += self.expr_str(p[1]) - else: - _out += '"%s"' % (p[0],) - first = 0 - if instr[2]: - _out += instr[2] - print(_out) - elif op == 'LET': - print("%s LET %s = %s" % - (line, self.var_str(instr[1]), self.expr_str(instr[2]))) - elif op == 'READ': - _out = "%s READ " % line - first = 1 - for r in instr[1]: - if not first: - _out += "," - _out += self.var_str(r) - first = 0 - print(_out) - elif op == 'IF': - print("%s IF %s THEN %d" % - (line, self.relexpr_str(instr[1]), instr[2])) - elif op == 'GOTO' or op == 'GOSUB': - print("%s %s %s" % (line, op, instr[1])) - elif op == 'FOR': - _out = "%s FOR %s = %s TO %s" % ( - line, instr[1], self.expr_str(instr[2]), self.expr_str(instr[3])) - if instr[4]: - _out += " STEP %s" % (self.expr_str(instr[4])) - print(_out) - elif op == 'NEXT': - print("%s NEXT %s" % (line, instr[1])) - elif op == 'FUNC': - print("%s DEF %s(%s) = %s" % - (line, instr[1], instr[2], self.expr_str(instr[3]))) - elif op == 'DIM': - _out = "%s DIM " % line - first = 1 - for vname, x, y in instr[1]: - if not first: - _out += "," - first = 0 - if y == 0: - _out += "%s(%d)" % (vname, x) - else: - _out += "%s(%d,%d)" % (vname, x, y) - - print(_out) - elif op == 'DATA': - _out = "%s DATA " % line - first = 1 - for v in instr[1]: - if not first: - _out += "," - first = 0 - _out += v - print(_out) - - # Erase the current program - def new(self): - self.prog = {} - - # Insert statements - def add_statements(self, prog): - for line, stat in prog.items(): - self.prog[line] = stat - - # Delete a statement - def del_line(self, lineno): - try: - del self.prog[lineno] - except KeyError: - pass |