From b5ab142a71b264ed1569cc56e6006288eea60f75 Mon Sep 17 00:00:00 2001 From: niansa Date: Fri, 10 Apr 2020 16:21:10 +0200 Subject: [PATCH] Added more functions (builtin.dec, builtin.inc, builtin.marker, time.sleep) --- cli.py | 36 +++++++++++++++++++++++--- errors.py | 1 + modules/builtin.py | 63 +++++++++++++++++++++++++++++++++++++++++----- modules/time.py | 45 +++++++++++++++++++++++++++++++++ rstrings.py | 3 ++- rtypes.py | 5 ++++ 6 files changed, 142 insertions(+), 11 deletions(-) create mode 100644 modules/time.py diff --git a/cli.py b/cli.py index 7515db2..5fa47a2 100755 --- a/cli.py +++ b/cli.py @@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License along with pilang. If not, see . """ import sys +from rtypes import goto from intern import main_class if len(sys.argv) == 1: # CLI loop @@ -37,19 +38,46 @@ if len(sys.argv) == 1: # CLI loop except KeyboardInterrupt: print() continue - res = main.get_rstring(main.run_command(commandstr), errorsonly=False) + try: + res = main.get_rstring(main.run_command(commandstr), errorsonly=False) + except goto: + res = "Goto is not possible in CLI mode" if res != None: print(res) else: # File execution loop + # Initialise interpreter main = main_class() + # Parse argv if sys.argv[1] == "-c": del sys.argv[1] if len(sys.argv[1]) == 1: sys.exit(1) + # Save file line-by-line into list with open(sys.argv[1], mode="r") as f: + lines = [] for line in f: if line[-1] == "\n": line = line[:-1] - cmdres = main.get_rstring(main.run_command(line), errorsonly=True) - if cmdres: - print(cmdres) + lines.append(line) + # Execute file + linenum = 0 + markers = {"start": 0} + while True: + try: + cmdres = main.get_rstring(main.run_command(lines[linenum]), errorsonly=True) + linenum += 1 + except goto as gotoinstr: + if gotoinstr.define: + markers[gotoinstr.marker] = linenum + 1 + linenum += 1 + continue + else: + try: + linenum = markers[gotoinstr.marker] + except KeyError: + print("Invalid goto instruction (critical)") + sys.exit(3) + except IndexError: + break + if cmdres: + print(cmdres) diff --git a/errors.py b/errors.py index 20086c1..27feedf 100644 --- a/errors.py +++ b/errors.py @@ -19,3 +19,4 @@ class nochsuchcmd: pass class badarguments: pass class nosuchmodule: pass class nosuchvariable: pass +class inputeof: pass diff --git a/modules/builtin.py b/modules/builtin.py index dedaa89..a863d5d 100644 --- a/modules/builtin.py +++ b/modules/builtin.py @@ -23,11 +23,17 @@ 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, @@ -44,6 +50,20 @@ class builtin: 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 @@ -63,16 +83,33 @@ class builtin: 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="") + print(arg, end="", flush=nonline) if not nonline: print() return rtypes.success def cmd_input(self, args): self.cmd_print(args, nonline=True) - return input() + try: + return input() + except EOFError: + print() + return errors.inputeof def cmd_set(self, args): if len(args) != 2: @@ -80,6 +117,22 @@ class builtin: 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: @@ -120,11 +173,9 @@ class builtin: return matches except ValueError: return errors.badarguments - # Evaluate list of commands + # Evaluate list of commands if comparisation matches if matches: - for command in commands: - lastres = self.environ.evaluate(command) - return lastres + return self.cmd_eval(commands) else: return rtypes.fail diff --git a/modules/time.py b/modules/time.py new file mode 100644 index 0000000..9b860f9 --- /dev/null +++ b/modules/time.py @@ -0,0 +1,45 @@ +""" +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 time as pytime +import rtypes + +class time: + def __init__(self, environ): + self.commands = { + "sleep": self.cmd_sleep + } + self.environ = environ + + + def processor(self, command, args): + try: + return self.commands[command](args) + except KeyError: + return errors.nochsuchcmd + + def cmd_sleep(self, args): + if len(args) != 1: + return errors.badarguments + try: + pytime.sleep(float(args[0])) + except ValueError: + return errors.badarguments + return rtypes.success + + +def adder(registerer): + registerer(time) diff --git a/rstrings.py b/rstrings.py index ea4ad8b..0e2a799 100644 --- a/rstrings.py +++ b/rstrings.py @@ -20,5 +20,6 @@ rstrings = { "nochsuchcmd": "No such command", "nosuchmodule": "No such module", "nosuchvariable": "No such variable", - "badarguments": "Bad arguments" + "badarguments": "Bad arguments", + "inputeof": "EOF in stdin", } diff --git a/rtypes.py b/rtypes.py index a5267c2..37cbb64 100644 --- a/rtypes.py +++ b/rtypes.py @@ -16,3 +16,8 @@ along with pilang. If not, see . """ class success: pass class fail: pass + +class goto(Exception): + def __init__(self, marker, define:bool=False): + self.define = define + self.marker = marker