Files
2026-06-18 17:21:58 +02:00

46 lines
1.5 KiB
Python

import logging
from collections import defaultdict
from tclint.syntax_tree import Command, CommandSub, Node, Script, Visitor
class SymbolTable:
"""Holds a symbol table (links symbols to nodes)."""
def __init__(self) -> None:
self.proc_def: defaultdict[str, list[Node]] = defaultdict(list)
def add_proc_definition(self, command: Command) -> None:
"""Add definition of procedure"""
# command holds the "proc" keyword, so the proc name is 1st argument
proc_name_node = command.args[0]
proc_name = proc_name_node.contents
if not proc_name:
return
logging.debug(
f"Definition of proc '{proc_name}' at {proc_name_node._pos_str()}"
)
self.proc_def[proc_name].append(proc_name_node)
def lookup_proc_definitions(self, symbol_text: str) -> list[Node]:
"""Lookup definitions of the procedure pointed at by node"""
if symbol_text is None or symbol_text not in self.proc_def:
return []
return self.proc_def[symbol_text]
class SymbolTableBuilder(Visitor):
"""Builds a symbol table."""
def __init__(self):
self.table = SymbolTable()
def build(self, tree: CommandSub | Script) -> SymbolTable:
"""Run the builder visitor through the syntax tree, building a table."""
tree.accept(self, recurse=True)
return self.table
def visit_command(self, command: Command) -> None:
if command.routine.contents == "proc":
self.table.add_proc_definition(command)