""" Gradio Blocks layout for the CL compiler. Single-column stacked layout: header → input → compile button → status, then three phase sections (Tokens, AST, Semantic). """ from pathlib import Path import gradio as gr from .pipeline import badge, compile_all, load_samples SAMPLES = load_samples() DEFAULT_SAMPLE = "hello" if "hello" in SAMPLES else next(iter(SAMPLES), "") DEFAULT_CODE = SAMPLES.get(DEFAULT_SAMPLE, "int x;\nx = 5;\nx = x + 2;\n") # Loads mermaid.js once and renders any
 that appears
# in the DOM (including blocks that Gradio injects after a Compile click).
_MERMAID_HEAD = """


"""


def load_css() -> str:
    return (Path(__file__).parent / "styles.css").read_text(encoding="utf-8")


def _load_sample(name: str) -> str:
    return SAMPLES.get(name, "")


def build_demo() -> gr.Blocks:
    with gr.Blocks(title="CL Compiler — Visualizer", head=_MERMAID_HEAD) as demo:
        # --- Header --------------------------------------------------------
        gr.Markdown("# CL Compiler", elem_classes="app-header")
        gr.Markdown(
            "A visual pipeline for the CL language — watch source code flow through "
            "**Lexer → Parser → Semantic Analyzer**.",
            elem_classes="app-subtitle",
        )
        gr.Markdown(
            "Kacem Mathlouthi · Mohamed Amine Haouas · Alaeddine Zaouali · Rami Kaabi · Oussama Kraiem",
            elem_classes="app-authors",
        )

        # --- Input ---------------------------------------------------------
        sample_dropdown = gr.Dropdown(
            choices=list(SAMPLES.keys()),
            value=DEFAULT_SAMPLE,
            label="Sample",
            interactive=True,
        )
        code_input = gr.Code(
            value=DEFAULT_CODE,
            label="Source",
            lines=14,
            interactive=True,
        )
        compile_btn = gr.Button("Compile", variant="primary", size="lg")
        status = gr.Markdown(
            badge("skip", "Idle — click Compile to run."),
            elem_classes="status-row",
        )

        # --- Phase 1: Tokens ----------------------------------------------
        with gr.Column(elem_classes="phase-section"):
            gr.Markdown("Phase 1", elem_classes="phase-marker")
            gr.Markdown("## Tokens", elem_classes="phase-title")
            gr.Markdown(
                "Source text is scanned left-to-right and emitted as a flat token "
                "stream. Whitespace and `//` comments are skipped.",
                elem_classes="phase-desc",
            )
            tokens_table = gr.Dataframe(
                headers=["#", "Type", "Value", "Line", "Col"],
                datatype=["number", "str", "str", "number", "number"],
                interactive=False,
                wrap=True,
                show_label=False,
            )

        # --- Phase 2: AST -------------------------------------------------
        with gr.Column(elem_classes="phase-section"):
            gr.Markdown("Phase 2", elem_classes="phase-marker")
            gr.Markdown("## Abstract Syntax Tree", elem_classes="phase-title")
            gr.Markdown(
                "Tokens are consumed by a recursive-descent parser that builds a "
                "tree of nodes. Indentation reflects parent → child relationships.",
                elem_classes="phase-desc",
            )
            ast_view = gr.HTML(
                value='
Click Compile to see the syntax tree.
', elem_classes="ast-view", ) # --- Phase 3: Semantic -------------------------------------------- with gr.Column(elem_classes="phase-section"): gr.Markdown("Phase 3", elem_classes="phase-marker") gr.Markdown("## Semantic Analysis", elem_classes="phase-title") gr.Markdown( "The AST is walked with a scoped symbol table. Variables must be " "declared before use; assignment and operator types must agree.", elem_classes="phase-desc", ) semantic_status = gr.Markdown(elem_classes="status-row") symbol_table = gr.Dataframe( headers=["Name", "Type"], datatype=["str", "str"], label="Symbol Table (global scope)", interactive=False, ) gr.Markdown( "Try the `errors` sample to see how type and scope errors are reported.", elem_classes="footer-note", ) # --- Wiring -------------------------------------------------------- sample_dropdown.change(_load_sample, inputs=sample_dropdown, outputs=code_input) compile_btn.click( compile_all, inputs=code_input, outputs=[status, tokens_table, ast_view, semantic_status, symbol_table], ) return demo