#!/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")