import turtle
from lark import Lark, Transformer, v_args

# =============================================================
# 1. A GRAMÁTICA DO ROBÔ (SINTAXE COMPLETA)
# =============================================================
gramatica_robo = """
    ?start: programa
    programa: comando+

    ?comando: mover_frente | mover_tras | girar_esq | girar_dir 
            | subir_caneta | descer_caneta | mudar_cor

    # Comandos de Movimento e Rotação
    mover_frente: "FORWARD" NUMBER ";"
    mover_tras:   "BACK" NUMBER ";"
    girar_esq:    "LEFT" NUMBER ";"
    girar_dir:    "RIGHT" NUMBER ";"
    
    # Comandos de Estado da Caneta
    subir_caneta:  "PENUP" ";"
    descer_caneta: "PENDOWN" ";"
    
    # Comando de Cor: aceita strings como "red", "blue", "green"
    mudar_cor:     "COLOR" STRING ";"

    # Definições de Terminais
    COMMENT: /#[^\\n]*/
    STRING: /"[^"]*"/
    
    %import common.NUMBER
    %import common.WS
    
    %ignore WS
    %ignore COMMENT
"""

# =============================================================
# 2. O SIMULADOR DINÂMICO (SEMÂNTICA)
# =============================================================
class SimuladorRobo(Transformer):
    def __init__(self):
        # Inicialização da interface gráfica Turtle
        self.screen = turtle.Screen()
        self.screen.title("Lab de Compiladores - Robô Industrial")
        self.screen.bgcolor("#fdfdfd")
        
        self.robo = turtle.Turtle()
        self.robo.shape("turtle")
        self.robo.color("black") # Cor inicial
        self.robo.pensize(5)
        self.robo.speed(1)
        
        # Posicionamento inicial para começar a escrever
        self.robo.penup()
        self.robo.goto(-300, 150)
        self.robo.pendown()

    @v_args(inline=True)
    def mover_frente(self, dist):
        self.robo.forward(float(dist))

    @v_args(inline=True)
    def mover_tras(self, dist):
        self.robo.backward(float(dist))

    @v_args(inline=True)
    def girar_esq(self, ang):
        self.robo.left(float(ang))

    @v_args(inline=True)
    def girar_dir(self, ang):
        self.robo.right(float(ang))

    def subir_caneta(self, _):
        self.robo.penup()

    def descer_caneta(self, _):
        self.robo.pendown()

    @v_args(inline=True)
    def mudar_cor(self, cor_string):
        # Remove as aspas da string (ex: '"red"' -> 'red')
        cor = str(cor_string).replace('"', '')
        print(f"🎨 Trocando cor para: {cor}")
        try:
            self.robo.color(cor)
        except turtle.TurtleGraphicsError:
            print(f"⚠️ Aviso: Cor '{cor}' não reconhecida pelo Simulador.")

    def programa(self, children):
        return "\n✨ Processamento Finalizado: O robô concluiu a sequência!"

# =============================================================
# 3. EXECUTOR DO LABORATÓRIO
# =============================================================
def executar():
    parser = Lark(gramatica_robo)
    simulador = SimuladorRobo()
    
    nome_arquivo = "comandos.txt"

    try:
        with open(nome_arquivo, "r", encoding="utf-8") as f:
            codigo = f.read()
        
        print(f"--- Compilando e Executando: {nome_arquivo} ---")
        
        # Análise Sintática
        arvore = parser.parse(codigo)
        print(arvore.pretty())
        
        # Execução Semântica
        status = simulador.transform(arvore)
        print(status)

    except FileNotFoundError:
        print(f"❌ Erro: Arquivo '{nome_arquivo}' não encontrado.")
    except Exception as e:
        print(f"❌ Erro de Sintaxe ou Execução:\n{e}")

    print("\nFeche a janela do robô para sair.")
    turtle.done()

if __name__ == "__main__":
    executar()