Added ability to make batch functions in the shell, and did some reworking of the event system in gamebase to allow it
This commit is contained in:
parent
9055d8b257
commit
bc70bad1c7
3 changed files with 130 additions and 54 deletions
110
shell.py
110
shell.py
|
@ -20,22 +20,24 @@
|
|||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301, USA.
|
||||
#
|
||||
# Ver. 0.1.0029
|
||||
# Ver. 0.1.0032
|
||||
|
||||
|
||||
import types as _types
|
||||
import traceback as _tb
|
||||
import math as _math
|
||||
import re as _re
|
||||
|
||||
_CONV24TO8 = 6 / 256
|
||||
|
||||
class Shell(object):
|
||||
|
||||
def __init__(self):
|
||||
self.__commands = {'exit': self.exitShell}
|
||||
self.__commands = {'exit': self.exitShell, 'batch': self.batch, 'alias': self.makeAlias, 'def': self.defineBatch}
|
||||
self.__aliases = {}
|
||||
self.__batches = {}
|
||||
self.ps1 = '> '
|
||||
self.ps2 = '> '
|
||||
self.ps2 = '. '
|
||||
self.colorMode = 0 # bits of color depth. Supports: 0, 3, 4, 8, 24
|
||||
self.prevColor = '\x1b[0m'
|
||||
self.__exit = False
|
||||
|
@ -126,16 +128,7 @@ class Shell(object):
|
|||
print(self.ps1, end = '')
|
||||
command = self.scanInput()
|
||||
# we have to handle shell built-ins first (when we get some)
|
||||
if len(command) == 0:
|
||||
continue
|
||||
if command[0] in self.__commands:
|
||||
try:
|
||||
self.__commands[command[0]](command[1:])
|
||||
except Exception as e:
|
||||
_tb.print_exc()
|
||||
print(e)
|
||||
else:
|
||||
self.handleUnknownCommand(command)
|
||||
self.handleCommand(command)
|
||||
self.update()
|
||||
self.__exit = False
|
||||
|
||||
|
@ -152,20 +145,23 @@ conventionally called args or argv"""
|
|||
'a' must be one token, but original can be multiple."""
|
||||
self.__aliases[a] = original
|
||||
|
||||
def registerBatch(self, name: str, commands: list):
|
||||
self.__batches[name] = commands
|
||||
|
||||
def getAlias(self, a: str):
|
||||
if a in self.__aliases:
|
||||
return self.__aliases[a]
|
||||
else:
|
||||
return None
|
||||
|
||||
def getBatch(self, name: str):
|
||||
if name in self.__batches:
|
||||
return ['batch']
|
||||
else:
|
||||
return None
|
||||
|
||||
def exitShell(self, args):
|
||||
"""The default exit command."""
|
||||
self.__exit = True
|
||||
|
||||
# Beyond this point are functions that are called within the main loop.
|
||||
def scanInput(self):
|
||||
"""Parses input. Override this for custom input parsing, or input source."""
|
||||
instr = input()
|
||||
def scanLine(self, instr):
|
||||
"""Take a line of text and turn it into an argument list"""
|
||||
if instr == '':
|
||||
return []
|
||||
inQuotes = False
|
||||
|
@ -193,8 +189,78 @@ conventionally called args or argv"""
|
|||
ret.append(instr[argStart:c])
|
||||
a = self.getAlias(ret[0])
|
||||
if a:
|
||||
ret = a[:] + ret[1:]
|
||||
ret = a + ret[1:]
|
||||
b = self.getBatch(ret[0])
|
||||
if b:
|
||||
ret = b + ret
|
||||
return ret
|
||||
|
||||
# Default functions
|
||||
|
||||
def exitShell(self, args):
|
||||
"""The default exit command."""
|
||||
self.__exit = True
|
||||
|
||||
def makeAlias(self, args):
|
||||
"""Make an alias."""
|
||||
self.registerAlias(args[0], args[1:])
|
||||
|
||||
def defineBatch(self, args):
|
||||
"""Define a batch file."""
|
||||
if len(args) != 1:
|
||||
raise ValueError('def takes only one argument')
|
||||
ret = []
|
||||
command = input(self.ps2)
|
||||
while command != 'end':
|
||||
ret.append(command)
|
||||
command = input(self.ps2)
|
||||
self.registerBatch(args[0], ret)
|
||||
|
||||
def batch(self, args):
|
||||
"""Run commands in batch mode
|
||||
$0 is the name of the batch
|
||||
$1 - $n are individual arguments
|
||||
$* is all the arguments except 0
|
||||
$>0 - $>n is all arguments after the nth
|
||||
$>=0 - $>=n is the nth and later arguments"""
|
||||
script = self.__batches[args[0]]
|
||||
var = _re.compile(r'\$((?:[>][=]?)?[0-9]+)')
|
||||
u = False
|
||||
for line in script:
|
||||
if u:
|
||||
self.update()
|
||||
else:
|
||||
u = True
|
||||
newLine = line.replace(r'$*', ' '.join(args[1:]))
|
||||
matches = var.finditer(newLine)
|
||||
for m in matches:
|
||||
n = m.group(1)
|
||||
if n[0] == '>':
|
||||
if n[1] == '=':
|
||||
num = int(n[2:])
|
||||
else:
|
||||
num = int(n[1:])+1
|
||||
newLine = newLine.replace(m.group(), ' '.join(args[num:]))
|
||||
else:
|
||||
newLine = newLine.replace(m.group(), args[int(n)])
|
||||
self.handleCommand(self.scanLine(newLine))
|
||||
|
||||
# Beyond this point are functions that are called within the main loop.
|
||||
def scanInput(self):
|
||||
"""Parses input. Override this for custom input parsing, or input source."""
|
||||
return self.scanLine(input())
|
||||
|
||||
def handleCommand(self, command):
|
||||
if len(command) == 0:
|
||||
return
|
||||
if command[0] in self.__commands:
|
||||
try:
|
||||
self.__commands[command[0]](command[1:])
|
||||
except Exception as e:
|
||||
_tb.print_exc()
|
||||
print(e)
|
||||
else:
|
||||
self.handleUnknownCommand(command)
|
||||
|
||||
def handleUnknownCommand(self, command):
|
||||
"""Handle commands that aren't registered. Override this if you want to do
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue