""" This file is part of pilang. pilang is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. pilang is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with pilang. If not, see . """ import sys import errors import rtypes class builtin: def __init__(self, environ): self.commands = { "ret": self.cmd_ret, "get": self.cmd_get, "len": self.cmd_len, "catch": self.cmd_catch, "exit": self.cmd_exit, "marker": self.cmd_marker, "printnnl": self.cmd_printnnl, "print": self.cmd_print, "input": self.cmd_input, "set": self.cmd_set, "inc": self.cmd_inc, "dec": self.cmd_dec, "del": self.cmd_del, "eval": self.cmd_eval, "cmp": self.cmd_cmp, "lower": self.cmd_lower } self.environ = environ def processor(self, command, args): try: return self.commands[command](args) except KeyError: return errors.nochsuchcmd def cmd_ret(self, args): return " ".join(args) def cmd_get(self, args): if len(args) != 2: return errors.badarguments try: return args[0][int(round(float(args[1])))] except: return errors.badarguments def cmd_len(self, args): result = 0 for arg in args: result += len(arg) return str(result) def cmd_catch(self, args): if args == []: self.environ.catch = not self.environ.catch else: if args[0].lower() == "true": self.environ.catch = True elif args[0].lower() == "false": self.environ.catch = False else: return errors.badarguments def cmd_exit(self, args): try: sys.exit(int(args[0])) except ValueError: return errors.badarguments except IndexError: return errors.badarguments def cmd_marker(self, args): if len(args) != 2: return errors.badarguments if args[0] == "set": raise rtypes.goto(marker=str(args[1]), define=True) elif args[0] == "goto": raise rtypes.goto(marker=str(args[1]), define=False) else: return errors.badarguments def cmd_printnnl(self, args): return self.cmd_print(args, nonline=True) def cmd_print(self, args, nonline=False): for arg in args: print(arg, end="", flush=nonline) if not nonline: print() return rtypes.success def cmd_input(self, args): self.cmd_print(args, nonline=True) try: return input() except EOFError: print() return errors.inputeof def cmd_set(self, args): if len(args) != 2: return errors.badarguments self.environ.variables[args[0]] = args[1] return rtypes.success def cmd_inc(self, args): if len(args) == 1: args.append(1) if not len(args) == 2: return errors.badarguments try: self.environ.variables[args[0]] = str(float(self.environ.variables[args[0]]) + float(args[1])) except KeyError: return errors.badarguments return rtypes.success def cmd_dec(self, args): if len(args) < 2: args.append(1) return self.cmd_inc(args[0], -args[1]) def cmd_del(self, args): # Check if variable exists for arg in args: if not arg in self.environ.variables.keys(): return errors.nosuchvariable # Actually do that stuff for arg in args: del self.environ.variables[arg] return rtypes.success def cmd_lower(self, args): return str(args[0].lower()) def cmd_cmp(self, args): # Check try: action, var1, var2, *commands = args if action == "equal": matches = str(var1) == str(var2) elif action == "nonequal": matches = str(var1) != str(var2) elif action == "bigger": matches = float(var1) > float(var2) elif action == "smaller": matches = float(var1) < float(var2) elif action in ["isnum", "isnotnum"]: try: float(var1) float(var2) matches = True except ValueError: matches = False if action == "isnotnum": matches = not matches else: return errors.badarguments if commands == []: return matches except ValueError: return errors.badarguments # Evaluate list of commands if comparisation matches if matches: return self.cmd_eval(commands) else: return rtypes.fail def cmd_eval(self, args): for command in args: lastres = self.environ.evaluate(command) return lastres def adder(registerer): registerer(builtin)