X-Git-Url: https://plomlompom.com/repos/?a=blobdiff_plain;f=new%2Fplomrogue%2Fparser.py;h=27bd95a573864b2d282cbd1121da40c2a34571e4;hb=f01848a97bb686e2b9c823cdf7fc6b59072dbd79;hp=39df213469ccb6e7e8652d9710b9a2efabbbccd0;hpb=e530d9faf68b4057322f5cc61aa0e3b76f8db3f6;p=plomrogue2-experiments diff --git a/new/plomrogue/parser.py b/new/plomrogue/parser.py index 39df213..27bd95a 100644 --- a/new/plomrogue/parser.py +++ b/new/plomrogue/parser.py @@ -1,5 +1,6 @@ import unittest from plomrogue.errors import ArgError +from plomrogue.mapping import YX class Parser: @@ -64,16 +65,17 @@ class Parser: args = self.argsparse(argtypes, args_candidates) return func, args - def parse_yx_tuple(self, yx_string, range_): - """Parse yx_string as yx_tuple:nonneg argtype, return result. + def parse_yx_tuple(self, yx_string, range_=None): + """Parse yx_string as yx_tuple, return result. + + The range_ argument may be 'nonneg' (non-negative, including + 0) or 'pos' (positive, excluding 0). - The range_ argument may be 'nonneg' (non-negative, including 0) - or 'pos' (positive, excluding 0). """ def get_axis_position_from_argument(axis, token): if len(token) < 3 or token[:2] != axis + ':' or \ - not token[2:].isdigit(): + not (token[2:].isdigit() or token[2] == '-'): raise ArgError('Non-int arg for ' + axis + ' position.') n = int(token[2:]) if n < 1 and range_ == 'pos': @@ -87,15 +89,17 @@ class Parser: raise ArgError('Wrong number of yx-tuple arguments.') y = get_axis_position_from_argument('Y', tokens[0]) x = get_axis_position_from_argument('X', tokens[1]) - return (y, x) + return YX(y, x) def argsparse(self, signature, args_tokens): """Parse into / return args_tokens as args defined by signature. - Expects signature to be a ' '-delimited sequence of any of the strings - 'int:nonneg', 'yx_tuple:nonneg', 'yx_tuple:pos', 'string', - 'seq:int:nonneg', 'string:' + an option type string accepted by - self.game.get_string_options, defining the respective argument types. + Expects signature to be a ' '-delimited sequence of any of the + strings 'bool', 'int:nonneg', 'yx_tuple', 'yx_tuple:nonneg', + 'yx_tuple:pos', 'string', 'seq:int:nonneg', 'string:' + an + option type string accepted by self.game.get_string_options, + defining the respective argument types. + """ tmpl_tokens = signature.split() if len(tmpl_tokens) != len(args_tokens): @@ -107,7 +111,11 @@ class Parser: for i in range(len(tmpl_tokens)): tmpl = tmpl_tokens[i] arg = args_tokens[i] - if tmpl == 'int:nonneg': + if tmpl == 'bool': + if arg not in {'True', 'False'}: + raise ArgError('Argument must be "True" or "False".') + args += [True if arg == 'True' else False] + elif tmpl == 'int:nonneg': if not arg.isdigit(): raise ArgError('Argument must be non-negative integer.') args += [int(arg)] @@ -115,7 +123,12 @@ class Parser: args += [self.parse_yx_tuple(arg, 'nonneg')] elif tmpl == 'yx_tuple:pos': args += [self.parse_yx_tuple(arg, 'pos')] + elif tmpl == 'yx_tuple': + args += [self.parse_yx_tuple(arg)] elif tmpl == 'seq:int:nonneg': + if arg == ',': + args += [[]] + continue sub_tokens = arg.split(',') if len(sub_tokens) < 1: raise ArgError('Argument must be non-empty sequence.') @@ -140,7 +153,7 @@ class Parser: raise ArgError(msg) args += [arg] else: - raise ArgError('Unknown argument type.') + raise ArgError('Unknown argument type: %s' % tmpl) return args @@ -161,9 +174,9 @@ class TestParser(unittest.TestCase): def test_unhandled(self): p = Parser() - self.assertEqual(p.parse(''), None) - self.assertEqual(p.parse(' '), None) - self.assertEqual(p.parse('x'), None) + self.assertEqual(p.parse(''), (None, ())) + self.assertEqual(p.parse(' '), (None, ())) + #self.assertEqual(p.parse('x'), (None, ())) def test_argsparse(self): from functools import partial @@ -172,30 +185,29 @@ class TestParser(unittest.TestCase): assertErr('', ['foo']) assertErr('string', []) assertErr('string string', ['foo']) - self.assertEqual(p.argsparse('string', ('foo',)), - (['foo'], {})) + self.assertEqual(p.argsparse('string', ('foo',)), ['foo']) self.assertEqual(p.argsparse('string string', ('foo', 'bar')), - (['foo', 'bar'], {})) + ['foo', 'bar']) assertErr('int:nonneg', ['']) assertErr('int:nonneg', ['x']) assertErr('int:nonneg', ['-1']) assertErr('int:nonneg', ['0.1']) - self.assertEqual(p.argsparse('int:nonneg', ('0',)), - ([0], {})) - assertErr('yx_tuple:nonneg', ['x']) + self.assertEqual(p.argsparse('int:nonneg', ('0',)), [0]) + assertErr('yx_tuple', ['x']) + assertErr('yx_tuple', ['Y:1.1,X:1']) + self.assertEqual(p.argsparse('yx_tuple', ('Y:1,X:-2',)), [(1, -2)]) assertErr('yx_tuple:nonneg', ['Y:0,X:-1']) assertErr('yx_tuple:nonneg', ['Y:-1,X:0']) - assertErr('yx_tuple:nonneg', ['Y:1.1,X:1']) assertErr('yx_tuple:nonneg', ['Y:1,X:1.1']) self.assertEqual(p.argsparse('yx_tuple:nonneg', ('Y:1,X:2',)), - ([(1, 2)], {})) + [(1, 2)]) assertErr('yx_tuple:pos', ['Y:0,X:1']) assertErr('yx_tuple:pos', ['Y:1,X:0']) assertErr('seq:int:nonneg', ['']) - assertErr('seq:int:nonneg', [',']) + self.assertEqual(p.argsparse('seq:int:nonneg', [',']), [[]]) assertErr('seq:int:nonneg', ['a']) assertErr('seq:int:nonneg', ['a,1']) assertErr('seq:int:nonneg', [',1']) assertErr('seq:int:nonneg', ['1,']) self.assertEqual(p.argsparse('seq:int:nonneg', ('1,2,3',)), - ([[1, 2, 3]], {})) + [[1, 2, 3]])