# Path: h800/symbol_table.py
# def buildSymbolTable(filename, symtab, verbose=False):
#     """Build the symbol table."""
#     seg = filename.split('.')[0]  # Default: name of the first file.
#     subsegs = []        # List of subsegments.
#     subseg = "1"        # Current subsegment, default is 1 (no starting SETLOC)
#     d = Deck(file=filename, verbose=verbose)
#     errcount = 0
#     for card in d.cards:
#         if card.column8 == "*":
#             continue
#         command = card.operation
#         if command and command.startswith("SETLOC"):
#             if ',' in command:
#                 subseg = command.split(',')[1].strip()
#             else:
#                 subseg = "0"
#             subsegs.append(subseg)
#             # print("Subsegment: %s" % subseg)
#         if card.label:
#             symtabEntry = {
#                 "file": card.filename,
#                 "line": card.linenum,
#                 "lognum": card.lognum,
#                 "tagtype": None,
#                 "card": card
#             }
#             strLabel = card.label.strip().replace(' ', '')
#             if strLabel.upper() != strLabel:
#                 print("*** ERROR: Symbol %s is ill-formed (case)!" % strLabel,
#                       file=sys.stderr)
#                 print("Current definition: %s" % symtabEntry, file=sys.stderr)
#                 errcount += 1
#                 continue
#             tagName = strLabel
#             symtabEntry["tagtype"] = ' '
#             if ',' in strLabel:
#                 if strLabel.count(',') > 1:
#                     print("*** ERROR: Symbol %s is illegal, too many commas!"
#                           % strLabel, file=sys.stderr)
#                     print("Current definition: %s" % symtabEntry,
#                           file=sys.stderr)
#                     errcount += 1
#                     continue
#                 tagPrefix = strLabel.split(',')[0]
#                 tagName = strLabel.split(',')[1]
#                 if tagPrefix not in TAG_PREFIXES:
#                     print("*** ERROR: Symbol %s is ill-formed (tag prefix)!"
#                           % strLabel, file=sys.stderr)
#                     print("Current definition: %s" % symtabEntry,
#                           file=sys.stderr)
#                     errcount += 1
#                     continue
#                 if tagPrefix in ('L', 'X'):
#                     print("*** ERROR: Symbol %s has unsupported tag prefix!"
#                           % strLabel, file=sys.stderr)
#                     print("Current definition: %s" % symtabEntry,
#                           file=sys.stderr)
#                     errcount += 1
#                     continue
#                 symtabEntry["tagtype"] = tagPrefix
#                 if tagPrefix == 'B':
#                     # Mask tag for BOTH field and shift instructions.
#                     pass
#                 elif tagPrefix == 'F':
#                     # Mask tag for field instructions only.
#                     pass
#                 elif tagPrefix == 'S':
#                     # Mask tag for shift instructions only.
#                     pass
#                 elif tagPrefix == 'Z':
#                     # Special register tag.
#                     # TODO: check register tag symbolic name is valid, or
#                     # absolute value is valid.
#                     pass
# 
#             # Check the command code field. Depending on the command code
#             # field operation, multiple declarations might be allowed,
#             # e.g. RESERVE, EQUALS, ALF, SPEC, CAC, etc., all reserve
#             # storage, but ASSIGN doesn't.
#             if command is None:
#                 print("*** ERROR: Symbol %s has no operation!" % strLabel,
#                       file=sys.stderr)
#                 print("Current definition: %s" % symtabEntry, file=sys.stderr)
#                 errcount += 1
#                 continue
#             if command == "ASSIGN":
#                 symtype = "complex"
#             else:
#                 symtype = "simple"
#             if tagName not in list(symtab.keys()):
#                 symtab[tagName] = {}
#                 symtab[tagName][seg] = {}
#                 symtab[tagName][seg][subseg] = {}
#                 symtab[tagName][seg][subseg][symtype] = symtabEntry
#             elif seg not in symtab[tagName].keys():
#                 symtab[tagName][seg] = {}
#                 symtab[tagName][seg][subseg] = {}
#                 symtab[tagName][seg][subseg][symtype] = symtabEntry
#             elif subseg not in symtab[tagName][seg].keys():
#                 symtab[tagName][seg][subseg] = {}
#                 symtab[tagName][seg][subseg][symtype] = symtabEntry
#             else:
#                 prevdef = symtab[tagName]
#                 if symtype not in prevdef.keys():
#                     symtab[tagName][seg][subseg][symtype] = symtabEntry
#                 else:
#                     if command == "EQUALS":
#                         prevcard = prevdef[symtype]["card"]
#                         if prevcard.operation == "EQUALS":
#                             if card.addressa == prevcard.addressa and \
#                                     card.addressb == prevcard.addressb \
#                                     and card.addressc == prevcard.addressc:
#                                 # Equivalent assignment, ignore.
#                                 continue
#                     print("*** ERROR: Symbol %s is multiply-defined!" %
#                           tagName, file=sys.stderr)
#                     print("Previous definitions: %s" %
#                           symtab[tagName][seg][subseg], file=sys.stderr)
#                     print("Current definition: %s" % symtabEntry,
#                           file=sys.stderr)
#                     print("command: %s" % command, file=sys.stderr)
#                     errcount += 1
#     return symtab, errcount


import sys
from optparse import OptionParser
from h800.symbol_table import buildSymbolTable



def main():
    parser = OptionParser("usage: %prog filename [filename]...")
    parser.add_option('-v', '--verbose',
                      dest='verbose',
                      action='store_true',
                      default=False,
                      help="Enable verbose output.")
    (opts, args) = parser.parse_args()
    if len(args) < 1:
        parser.error("usage: %prog filename")
        sys.exit(1)

    errors = 0

    symtab = {}
    for filename in args:
        symtab, file_errors = buildSymbolTable(filename, symtab,
                                               verbose=opts.verbose)
        errors += file_errors

    for sym in sorted(symtab.keys()):
        print(sym)
        for seg in sorted(symtab[sym].keys()):
            print("  Segment: %s" % seg)
            for subseg in sorted(symtab[sym][seg].keys()):
                print("    Subsegment: %s" % subseg)
                for symtype in sorted(symtab[sym][seg][subseg].keys()):

# Path: h800/symbol_table.py
# def buildSymbolTable(filename, symtab, verbose=False):
#     """Build the symbol table."""
#     seg = filename.split('.')[0]  # Default: name of the first file.
#     subsegs = []        # List of subsegments.
#     subseg = "1"        # Current subsegment, default is 1 (no starting SETLOC)
#     d = Deck(file=filename, verbose=verbose)
#     errcount = 0
#     for card in d.cards:
#         if card.column8 == "*":
#             continue
#         command = card.operation
#         if command and command.startswith("SETLOC"):
#             if ',' in command:
#                 subseg = command.split(',')[1].strip()
#             else:
#                 subseg = "0"
#             subsegs.append(subseg)
#             # print("Subsegment: %s" % subseg)
#         if card.label:
#             symtabEntry = {
#                 "file": card.filename,
#                 "line": card.linenum,
#                 "lognum": card.lognum,
#                 "tagtype": None,
#                 "card": card
#             }
#             strLabel = card.label.strip().replace(' ', '')
#             if strLabel.upper() != strLabel:
#                 print("*** ERROR: Symbol %s is ill-formed (case)!" % strLabel,
#                       file=sys.stderr)
#                 print("Current definition: %s" % symtabEntry, file=sys.stderr)
#                 errcount += 1
#                 continue
#             tagName = strLabel
#             symtabEntry["tagtype"] = ' '
#             if ',' in strLabel:
#                 if strLabel.count(',') > 1:
#                     print("*** ERROR: Symbol %s is illegal, too many commas!"
#                           % strLabel, file=sys.stderr)
#                     print("Current definition: %s" % symtabEntry,
#                           file=sys.stderr)
#                     errcount += 1
#                     continue
#                 tagPrefix = strLabel.split(',')[0]
#                 tagName = strLabel.split(',')[1]
#                 if tagPrefix not in TAG_PREFIXES:
#                     print("*** ERROR: Symbol %s is ill-formed (tag prefix)!"
#                           % strLabel, file=sys.stderr)
#                     print("Current definition: %s" % symtabEntry,
#                           file=sys.stderr)
#                     errcount += 1
#                     continue
#                 if tagPrefix in ('L', 'X'):
#                     print("*** ERROR: Symbol %s has unsupported tag prefix!"
#                           % strLabel, file=sys.stderr)
#                     print("Current definition: %s" % symtabEntry,
#                           file=sys.stderr)
#                     errcount += 1
#                     continue
#                 symtabEntry["tagtype"] = tagPrefix
#                 if tagPrefix == 'B':
#                     # Mask tag for BOTH field and shift instructions.
#                     pass
#                 elif tagPrefix == 'F':
#                     # Mask tag for field instructions only.
#                     pass
#                 elif tagPrefix == 'S':
#                     # Mask tag for shift instructions only.
#                     pass
#                 elif tagPrefix == 'Z':
#                     # Special register tag.
#                     # TODO: check register tag symbolic name is valid, or
#                     # absolute value is valid.
#                     pass
# 
#             # Check the command code field. Depending on the command code
#             # field operation, multiple declarations might be allowed,
#             # e.g. RESERVE, EQUALS, ALF, SPEC, CAC, etc., all reserve
#             # storage, but ASSIGN doesn't.
#             if command is None:
#                 print("*** ERROR: Symbol %s has no operation!" % strLabel,
#                       file=sys.stderr)
#                 print("Current definition: %s" % symtabEntry, file=sys.stderr)
#                 errcount += 1
#                 continue
#             if command == "ASSIGN":
#                 symtype = "complex"
#             else:
#                 symtype = "simple"
#             if tagName not in list(symtab.keys()):
#                 symtab[tagName] = {}
#                 symtab[tagName][seg] = {}
#                 symtab[tagName][seg][subseg] = {}
#                 symtab[tagName][seg][subseg][symtype] = symtabEntry
#             elif seg not in symtab[tagName].keys():
#                 symtab[tagName][seg] = {}
#                 symtab[tagName][seg][subseg] = {}
#                 symtab[tagName][seg][subseg][symtype] = symtabEntry
#             elif subseg not in symtab[tagName][seg].keys():
#                 symtab[tagName][seg][subseg] = {}
#                 symtab[tagName][seg][subseg][symtype] = symtabEntry
#             else:
#                 prevdef = symtab[tagName]
#                 if symtype not in prevdef.keys():
#                     symtab[tagName][seg][subseg][symtype] = symtabEntry
#                 else:
#                     if command == "EQUALS":
#                         prevcard = prevdef[symtype]["card"]
#                         if prevcard.operation == "EQUALS":
#                             if card.addressa == prevcard.addressa and \
#                                     card.addressb == prevcard.addressb \
#                                     and card.addressc == prevcard.addressc:
#                                 # Equivalent assignment, ignore.
#                                 continue
#                     print("*** ERROR: Symbol %s is multiply-defined!" %
#                           tagName, file=sys.stderr)
#                     print("Previous definitions: %s" %
#                           symtab[tagName][seg][subseg], file=sys.stderr)
#                     print("Current definition: %s" % symtabEntry,
#                           file=sys.stderr)
#                     print("command: %s" % command, file=sys.stderr)
#                     errcount += 1
#     return symtab, errcount


# Path: tools/list-symbols.py
import sys
from optparse import OptionParser
from h800.symbol_table import buildSymbolTable




def main():
    parser = OptionParser("usage: %prog filename [filename]...")
    parser.add_option('-v', '--verbose',
                      dest='verbose',
                      action='store_true',
                      default=False,
                      help="Enable verbose output.")
    (opts, args) = parser.parse_args()
    if len(args) < 1:
        parser.error("usage: %prog filename")
        sys.exit(1)

    errors = 0

    symtab = {}
    for filename in args:
        symtab, file_errors = buildSymbolTable(filename, symtab,
                                               verbose=opts.verbose)
        errors += file_errors

    for sym in sorted(symtab.keys()):
        print(sym)
        for seg in sorted(symtab[sym].keys()):
            print("  Segment: %s" % seg)
            for subseg in sorted(symtab[sym][seg].keys()):
                print("    Subsegment: %s" % subseg)
                for symtype in sorted(symtab[sym][seg][subseg].keys()):

                    symdata = symtab[sym][seg][subseg][symtype]