pmacs3/mode/nasm.py

73 lines
3.6 KiB
Python

from mode import Fundamental
from lex import Grammar, PatternRule, RegionRule, PatternMatchRule
from mode.python import StringGrammar1, StringGrammar2, StringGrammar3, StringGrammar4
from method import Method, arg
from subprocess import Popen, PIPE, STDOUT
chr1 = '[a-zA-Z_.?]'
chr2 = '[a-zA-Z0-9_.?$#@~]'
word = chr1 + chr2 + '*'
class NasmGrammar(Grammar):
rules = [
# for use with ndisasm files
PatternRule('nasm.address', '^[0-9a-fA-F]+ +[0-9a-fA-F]+'),
PatternRule('spaces', ' +'),
PatternRule("nasm.integer", "(0[xX][0-9a-fA-F]+|0|[1-9][0-9]*|0[0-7]+)[lL]?"),
PatternRule('nasm.register', "(?:eax|ebx|ecx|edx|ax|ah|al|bx|bh|bl|bp|cx|ch|cl|cmpsb|dh|di|dl|ds|dx|esi|es|edi|esp|ebp|si|sp|stosd)(?!" + chr2 + ")"),
PatternRule('nasm.pseudo', "(?:a16|a32|byte|db|dd|do|dq|dt|dword|qword|tword|fs|gs|near|o16|o32|short)(?!" + chr2 + ")"),
PatternRule('nasm.instruction', "(?:jg|jeq|jecxz|jne|ja|jmp|push|pushad|pushfd|call|ret|sub|adc|add|popad|popaw|popa|popfd|pop|call|and|arpl|bound|cwd|cdq|clc|cld|cli|cmp|cmpxchg|cpuid|das|dec|divpd|div|enter|leave|fadd|fld|fmul|fsqrt|fsub|fs|hlt|imul|inc|insb|insd|insw|ins|int|int3|in|jcxz|jc|jna|jnc|jnz|jo|js|jz|lea|lldt|loadsb|lock|loopne|movzx|movd|mov|mul|neg|not|nop|or|outsb|outsd|outsw|repe|retf|rol|sal|sar|sbb|scasw|shl|shr|shld|shrd|sldt|syscall|sysenter|sysexit|test|xchg|xadd|xor)(?!" + chr2 + ")"),
PatternRule('nasm.macro', "%(?:define|undef|assign|strlen|macro|endmacro|if|elif|else|endif|ifdef|ifndef|include|push|pop|stacksize)(?!" + chr2 + ")"),
PatternRule('nasm.keyword', "(?:section|global|extern)(?!" + chr2 + ")"),
PatternRule('nasm.prefix', "(?:dword|word|lock)(?!" + chr2 + ")"),
PatternMatchRule('x', '(' + word + ')(:)', 'nasm.label', 'delimiter'),
PatternRule("nasm.identifier", r'\$?' + word),
PatternRule("nasm.float", r"[0-9]+\.[0-9]*|\.[0-9]+|([0-9]|[0-9]+\.[0-9]*|\.[0-9]+)[eE][\+-]?[0-9]+"),
PatternRule('delimiter', r'(?://|%%|<<|>>|[~!\.\*/%\-\+\(\)\[\],\|\^\&])'),
RegionRule('string', '"""', StringGrammar4, '"""'),
RegionRule('string', "'''", StringGrammar3, "'''"),
RegionRule('string', '"', StringGrammar2, '"'),
RegionRule('string', "'", StringGrammar1, "'"),
PatternRule('comment', ';.*$'),
PatternRule('eol', '\n'),
PatternRule('continuation', r'\\\n$'),
]
class NasmDisassembleFile(Method):
args = [arg("path", dt='path', p="Path: "),
arg('flags', p='Flags: ', dv=lambda w: '-b 16', ld=True)]
def _execute(self, w, **vargs):
p = Popen(['ndisasm', vargs['path']], stdout=PIPE, stderr=STDOUT)
output = p.stdout.read()
retval = p.wait()
modename = None
bufname = '*Disasm:%s*' % vargs['path']
w.application.data_buffer(bufname, output, switch_to=True,
modename=modename)
class Nasm(Fundamental):
name = 'nasm'
extensions = ['.s']
grammar = NasmGrammar
commentc = ';'
colors = {
'nasm.address': ('cyan', 'default'),
'nasm.pseudo': ('cyan', 'default'),
'nasm.keyword': ('cyan', 'default'),
'nasm.macro': ('blue', 'default'),
'nasm.register': ('yellow', 'default'),
'nasm.instruction': ('magenta', 'default'),
'nasm.label': ('blue', 'default'),
'nasm.integer': ('green', 'default'),
}
_bindings = {
'close-paren': (')',),
'close-brace': ('}',),
'close-bracket': (']',),
}
actions = [NasmDisassembleFile]
install = Nasm.install