#!/usr/bin/env python3
"""
opsymbols.py
Andy Hammerlindl 2010/06/01

Extract mapping such as '+' --> SYM_PLUS from camp.l
"""

import argparse
import re
import textwrap

# Parse command-line arguments
parser = argparse.ArgumentParser(description="Extract operator symbols.")
parser.add_argument("--campfile", required=True, help="Input lex file (camp.l)")
parser.add_argument("--output", required=True, help="Output header file")
args = parser.parse_args()

# Open output file and write header
with open(args.output, "w", encoding="utf-8") as header:
    header.write(
        # pylint: disable=line-too-long
        textwrap.dedent(
            """\
            /*****
             * This file is automatically generated by opsymbols.py
             * Changes will be overwritten.
             *****/

            // If the OPSYMBOL macro is not defined for a specific purpose, define it with
            // the default purpose of using SYM_PLUS etc. as external pre-translated
            // symbols.

            #ifndef OPSYMBOL
            #define OPSYMBOL(str, name) extern sym::symbol name
            #endif

            """
        )
    )

    # Define add function
    def add(symbol, name):
        header.write(f'OPSYMBOL("{symbol}", {name});\n')

    # Open and process campfile
    with open(args.campfile, "r", encoding="utf-8") as lexer:
        for line in lexer:
            match = re.search(r'^"(\S+)"\s*{\s*DEFSYMBOL\((\w+)\);', line)
            if match:
                add(match.group(1), match.group(2))
                continue
            match = re.search(r"^(\w+)\s*{\s*DEFSYMBOL\((\w+)\);", line)
            if match:
                add(match.group(1), match.group(2))
                continue
            match = re.search(r"^\s*EXTRASYMBOL\(\s*(\w+)\s*,\s*(\w+)\s*\)", line)
            if match:
                add(match.group(1), match.group(2))
                continue

    # Write closing comments
    header.write("\n/* This file is automatically generated. */\n")
