pmacs3/mode/inform6.py

142 lines
5.5 KiB
Python
Raw Permalink Normal View History

from mode import Fundamental
from lex import Grammar, PatternRule, RegionRule, NocaseKeywordRule
from tab import StackTabber
import regex
directives = '''abbreviate array attribute btrace class constant default
dictionary end endif etrace extend fake_action global ifdef ifndef iftrue
iffalse ifv3 ifv5 import include link listsymbols listdict listverbs lowstring
ltrace message nearby nobtrace noetrace noltrace notrace object property
release replace serial statusline stub switches system_file trace verb
zcharacter'''.split()
defines = '''array attribute class constant fake_action global lowstring nearby
object property'''.split()
attributes = '''absent animate clothing concealed container door edible
enterable female general light lockable locked male moved neuter on open
openable pluralname proper scenery scored static supporter switchable talkable
transparent visited workflag worn'''.split()
properties = '''n_to s_to e_to w_to ne_to se_to nw_to sw_to u_to d_to in_to
out_to add_to_scope after article articles before cant_go capacity daemon
describe description door_dir door_to each_turn found_in grammar initial
inside_description invent life list_together name number orders parse_name
plural react_after react_before short_name time_left time_out when_closed
when_open when_on when_off with_key'''.split()
keywords = '''box break class continue do else font off font on for give has
hasnt if inversion jump move new_line notin objectloop ofclass print print_ret
private quit read remove restore return rfalse rtrue save spaces string style
bold style fixed style reverse style roman style underline switch to until
while with'''.split()
class StringGrammar(Grammar):
rules = [
PatternRule('escaped', r'\\.'),
PatternRule('data', r'[^\\"]+'),
]
class NameGrammar(Grammar):
rules = [
PatternRule('escaped', r'\\.'),
PatternRule('data', r"[^\\']+"),
]
class Inform6Grammar(Grammar):
rules = [
PatternRule('comment', '!.*$'),
PatternRule('inform6.char', "'.(?://.+)'"),
RegionRule('inform6.name', "'", NameGrammar, "'"),
RegionRule('inform6.string', '"', StringGrammar, '"'),
NocaseKeywordRule('inform6.directive', directives),
NocaseKeywordRule('inform6.define', defines),
NocaseKeywordRule('inform6.attribute', attributes),
NocaseKeywordRule('inform6.property', properties),
NocaseKeywordRule('inform6.keyword', keywords),
PatternRule('inform6.number', '\$\$[01]+'),
PatternRule('inform6.number', '\$[0-9a-fA-F]+'),
PatternRule('inform6.number', '[0-9]+'),
PatternRule('inform6.label', '\.[a-zA-Z_][a-zA-Z0-9_]*'),
PatternRule('inform6.identifier', '[a-zA-Z_][a-zA-Z0-9_]*'),
PatternRule('inform6.word', '[a-zA-Z_]+'),
PatternRule('delimiter', r'[\(\)\{\}\[\];]'),
PatternRule('spaces', ' +'),
PatternRule('eol', '\n'),
PatternRule('continuation', r'\\\n$'),
]
class Inform6Tabber(StackTabber):
def is_base(self, y):
if y == 0:
return True
h = self.mode.window.buffer.highlights[self.mode.name]
if not h.tokens[y]:
return False
t = h.tokens[y][0]
if t.name != 'inform6.directive':
return False
return t.string.lower() in ('constant', 'include', 'object')
def _handle_open_token(self, currlvl, y, i):
t = self.get_token(y, i)
l = self.get_curr_level() + self.mode.tabwidth
self._append(t.string, l, y)
return currlvl
def _handle_other_token(self, currlvl, y, i):
w = self.mode.tabwidth
t = self.get_token(y, i)
s = t.string.lower()
n = t.fqname()
if n == 'inform6.directive':
if s == 'object':
self._append('object', currlvl + w, y)
if n == 'inform6.keyword':
if s in ('with', 'has'):
if self._peek_name() == 'keyword':
self._pop()
currlvl -= w
self._append('keyword', currlvl + w, y)
elif n == 'delimiter':
self._opt_pop('keyword')
self._opt_pop('object')
return currlvl
class Inform6(Fundamental):
name = 'inform6'
extensions = ['.inf']
tabbercls = Inform6Tabber
grammar = Inform6Grammar
commentc = '!'
opentokens = ('delimiter',)
opentags = {'(': ')', '[': ']', '{': '}'}
closetokens = ('delimiter',)
closetags = {')': '(', ']': '[', '}': '{'}
colors = {
'inform6.label': ('magenta', 'default', 'bold'),
'inform6.define': ('magenta', 'default', 'bold'),
'inform6.directive': ('blue', 'default', 'bold'),
'inform6.keyword': ('blue', 'default', 'bold'),
'inform6.attribute': ('cyan', 'default', 'bold'),
'inform6.property': ('cyan', 'default', 'bold'),
'inform6.string.start': ('green', 'default', 'bold'),
'inform6.string.escaped': ('magenta', 'default', 'bold'),
'inform6.string.data': ('green', 'default', 'bold'),
'inform6.string.end': ('green', 'default', 'bold'),
'inform6.name.start': ('green', 'default', 'bold'),
'inform6.name.escaped': ('magenta', 'default', 'bold'),
'inform6.name.data': ('green', 'default', 'bold'),
'inform6.name.end': ('green', 'default', 'bold'),
}
_bindings = {
'close-paren': (')',),
'close-brace': ('}',),
'close-bracket': (']',),
}
install = Inform6.install