-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
208 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
import sublime | ||
import sublime_plugin | ||
import os | ||
import re | ||
import sys | ||
import time | ||
|
||
class MerlinMacGen(sublime_plugin.TextCommand): | ||
|
||
opcodes = { | ||
'BRL', 'COP', 'JML', 'JMPL', 'JSL', 'MVN', 'MVP', 'MX', 'PEA', | ||
'PEI', 'PER', 'REP', 'SEP', 'WDM', 'XCE', 'ADR', 'ADRL', 'ASC', | ||
'AST', 'BRK', 'CHK', 'CYC', 'DA', 'DAT', 'DB', 'DCI', 'DDB', 'DEND', | ||
'DFB', 'DL', 'DS', 'DSK', 'DUM', 'DW', 'END', 'ENT', 'EQU', 'ERR', 'EXP', | ||
'EXT', 'FLS', 'HEX', 'INV', 'KBD', 'LST', 'LSTL', 'LUP', 'OBJ', | ||
'ORG', 'PAG', 'PAU', 'PMC', 'PUT', 'REL', 'REV', 'SAV', 'SKP', | ||
'STR', 'TR', 'TTL', 'TYP', 'USE', 'USR', 'VAR', 'XC', 'XREF','=', | ||
'>>>', 'DO', 'ELS', 'EOM', 'FIN', 'IF', 'MAC', '--^', '<<<', | ||
'CLC', 'CLD', 'CLI', 'CLV', 'DEX', 'DEY', 'INX', 'INY', 'NOP', | ||
'PHA', 'PHB', 'PHD', 'PHK', 'PHX', 'PHY', 'PLA', 'PLB', 'PLD', | ||
'PLP', 'PLX', 'PLY', 'RTI', 'RTL', 'RTS', 'SEC', 'SED', 'SEI', | ||
'STP', 'SWA', 'TAD', 'TAS', 'TAX', 'TAY', 'TCD', 'TCS', 'TDA', | ||
'TDC', 'TSA', 'TSC', 'TSX', 'TXA', 'TXS', 'TXY', 'TYA', 'TYX', | ||
'WAI', 'XBA', 'BCC', 'BCS', 'BEQ', 'BGE', 'BLT', 'BMI', 'BNE', | ||
'BPL', 'BRA', 'BVC', 'BVS', 'ADCL', 'ANDL', 'CMPL', 'EORL', | ||
'LDAL', 'ORAL', 'SBCL', 'STAL', 'ADC', 'AND', 'ASL', 'BIT', | ||
'CMP', 'CPX', 'CPY', 'DEC', 'EOR', 'INC', 'JMP', 'JSR', 'LDA', | ||
'LDX', 'LDY', 'LSR', 'ORA', 'ROL', 'ROR', 'SBC', 'STA', 'STX', | ||
'STY', 'STZ', 'TRB', 'TSB', 'PHP', 'STRL', 'FLO', 'EXD', 'CAS', | ||
'' | ||
} | ||
re_pmc = re.compile('^[^.,/\\- ]*') | ||
re_dot_s = re.compile('\\.S$', re.IGNORECASE) | ||
re_ws = re.compile('[\t ]+') | ||
re_comment = re.compile('^[\t ]*[;*]') | ||
|
||
def front_matter(self): | ||
buffer = "" | ||
name = self.view.file_name() | ||
if name: | ||
buffer += "* Generated from " + os.path.basename(name) + " on " + time.asctime() + "\n" | ||
else: | ||
buffer += "* Generated on " + time.asctime() + "\n" | ||
buffer += "\n" | ||
return buffer | ||
|
||
def missing_matter(self, missing): | ||
buffer = "" | ||
if len(missing) == 0: | ||
return "" | ||
|
||
buffer = "* Missing Macros\n" | ||
|
||
missing = list(missing) | ||
missing.sort | ||
for macro in missing: | ||
buffer += "* " + macro + "\n" | ||
|
||
buffer += "\n" | ||
return buffer | ||
|
||
|
||
def run(self, edit): | ||
|
||
|
||
missing = set() | ||
known = set() | ||
|
||
view = self.view | ||
all = sublime.Region(0, view.size()) | ||
for r in view.lines(all): | ||
text = view.substr(r).rstrip() | ||
|
||
if text == "" or self.re_comment.match(text): | ||
continue | ||
|
||
line = re.split(self.re_ws, text, maxsplit=2) | ||
if len(line) < 2: | ||
continue | ||
|
||
# _macro args | ||
# PMC _macro,args << . / , - ( Space are separtors. | ||
# >>> _macro | ||
|
||
label = line[0].upper() | ||
opcode = line[1].upper() | ||
|
||
if opcode == "" or opcode[0] == ";": | ||
continue | ||
|
||
if opcode == 'MAC': | ||
# label MAC | ||
if label != "": | ||
known.add(label) | ||
continue | ||
|
||
if opcode in {'PMC', '>>>'} and len(line) > 2: | ||
tmp = line[2].upper() | ||
opcode = self.re_pmc.match(tmp).group(0) | ||
if opcode == "": | ||
continue | ||
|
||
|
||
if opcode in self.opcodes: | ||
continue | ||
if opcode in known: | ||
continue | ||
missing.add(opcode) | ||
|
||
|
||
if len(missing) == 0: | ||
return | ||
|
||
# | ||
buffer = "" | ||
root = "/tmp/supermacs" | ||
for e in os.listdir(root): | ||
|
||
if not self.re_dot_s.search(e): | ||
continue | ||
|
||
path = os.path.join(root, e) | ||
if not os.path.isfile(path): | ||
continue | ||
with open(path,'r') as file: | ||
# print(e + "\n",file=sys.stderr) | ||
buffer += self.one_macro_file(file, known, missing) | ||
|
||
if len(missing) == 0: | ||
break | ||
|
||
buffer = self.front_matter() + self.missing_matter(missing) + buffer | ||
|
||
|
||
view = view.window().new_file() | ||
view.insert(edit, 0, buffer) | ||
# p = 0 | ||
# for m in missing: | ||
# p = p + view.insert(edit, p, str(m) + "\n") | ||
|
||
|
||
def one_macro_file(self, file, known, missing): | ||
inmac = False | ||
buffer = "" | ||
|
||
while True: | ||
text = file.readline() | ||
if not text: | ||
return buffer | ||
|
||
text = text.rstrip() | ||
|
||
if inmac: | ||
buffer += text + "\n" | ||
|
||
if text == "" or self.re_comment.match(text): | ||
continue | ||
|
||
line = re.split(self.re_ws, text, maxsplit=2) | ||
|
||
|
||
if len(line) < 2: | ||
continue | ||
|
||
# if line[0] == "_MMStartUp": | ||
# print(line, file=sys.stderr) | ||
|
||
label = line[0].upper() | ||
opcode = line[1].upper() | ||
|
||
|
||
|
||
if opcode == "" or opcode[0] == ";": | ||
continue | ||
|
||
if opcode == "MAC" and label != "": | ||
# print(label,file=sys.stderr) | ||
# print(label in missing, file=sys.stderr) | ||
|
||
if inmac: | ||
known.add(label) | ||
missing.discard(label) | ||
elif label in missing: | ||
inmac = True | ||
known.add(label) | ||
missing.discard(label) | ||
buffer += text + "\n" | ||
continue | ||
|
||
if opcode in { '<<<', 'EOM' }: | ||
inmac = False | ||
continue | ||
|
||
if not inmac: | ||
continue | ||
|
||
if opcode in {'PMC', '>>>'} and len(line) > 2: | ||
tmp = line[2].upper() | ||
opcode = self.re_pmc.match(tmp).group(0) | ||
if opcode == "": | ||
continue | ||
|
||
if opcode in self.opcodes: | ||
continue | ||
if opcode in known: | ||
continue | ||
missing.add(opcode) | ||
|