~divmod-dev/divmod.org/no-addperson-2190

« back to all changes in this revision

Viewing changes to Imaginary/pottery/commands.py

  • Committer: exarkun
  • Date: 2006-02-26 02:37:39 UTC
  • Revision ID: svn-v4:866e43f7-fbfc-0310-8f2a-ec88d1da2979:trunk:4991
Merge move-pottery-to-trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
import os, sys, string, random
 
3
 
 
4
import pyparsing
 
5
 
 
6
from twisted.internet import defer
 
7
from twisted.python import reflect, rebuild, util
 
8
 
 
9
import pottery
 
10
from pottery import text as T, epottery, iterutils
 
11
from pottery.predicates import atLeastOne, isNot, And
 
12
 
 
13
OPPOSITE_DIRECTIONS = {
 
14
    "north": "south",
 
15
    "south": "north",
 
16
    "west": "east",
 
17
    "east": "west"}
 
18
 
 
19
def stripper(s, loc, toks):
 
20
    toks = toks.asList()
 
21
    toks[0] = toks[0][1:-1]
 
22
    return toks
 
23
 
 
24
def targetString(name):
 
25
    qstr = pyparsing.quotedString.setParseAction(stripper)
 
26
    return (
 
27
        pyparsing.Word(pyparsing.alphanums) ^
 
28
        qstr).setResultsName(name)
 
29
 
 
30
class CommandType(type):
 
31
    commands = {}
 
32
    def __new__(cls, name, bases, attrs):
 
33
        infrastructure = attrs.pop('infrastructure', False)
 
34
        t = super(CommandType, cls).__new__(cls, name, bases, attrs)
 
35
        if not infrastructure:
 
36
            cls.commands[reflect.qual(t)] = t
 
37
        return t
 
38
 
 
39
    def parse(self, player, line):
 
40
        for cls in self.commands.values():
 
41
            try:
 
42
                match = cls.match(player, line)
 
43
            except pyparsing.ParseException:
 
44
                pass
 
45
            else:
 
46
                if match is not None:
 
47
                    match = dict(match)
 
48
                    for k,v in match.items():
 
49
                        if isinstance(v, pyparsing.ParseResults):
 
50
                            match[k] = v[0]
 
51
                    return cls().run(player, line, **match)
 
52
        return defer.fail(epottery.NoSuchCommand(line))
 
53
 
 
54
class Command(object):
 
55
    __metaclass__ = CommandType
 
56
    infrastructure = True
 
57
 
 
58
    def match(cls, player, line):
 
59
        return cls.expr.parseString(line)
 
60
    match = classmethod(match)
 
61