/*
 * SiPi Electron — motor en C para crear cosas electronicas con SiPi
 * (electronica, robots, electrodomesticos) de forma facil.
 *
 * Este header define los tipos compartidos entre el lexer, el parser
 * y el interprete: tokens, nodos de AST y valores en tiempo de ejecucion.
 */
#ifndef SIPI_ELECTRON_H
#define SIPI_ELECTRON_H

#include <stddef.h>

/* ---------- Tokens ---------- */

typedef enum {
    TOK_EOF, TOK_NEWLINE,
    TOK_NUMERO, TOK_TEXTO, TOK_IDENT,
    TOK_PROGRAMA, TOK_DECIR, TOK_VARIABLE, TOK_CONST,
    TOK_SI, TOK_SINO, TOK_FIN,
    TOK_MIENTRAS, TOK_REPETIR, TOK_VECES, TOK_ROMPER, TOK_CONTINUAR,
    TOK_FUNCION, TOK_DEVOLVER, TOK_LLAMAR, TOK_LLAMAR_VALOR,
    TOK_VERDADERO, TOK_FALSO,
    TOK_Y, TOK_O, TOK_NO,
    TOK_FLECHA,          /* -> */
    TOK_IGUAL, TOK_IGUAL_IGUAL, TOK_DISTINTO,
    TOK_MENOR, TOK_MAYOR, TOK_MENOR_IGUAL, TOK_MAYOR_IGUAL,
    TOK_MAS, TOK_MENOS, TOK_POR, TOK_DIV, TOK_MOD,
    TOK_PAREN_ABRE, TOK_PAREN_CIERRA, TOK_COMA, TOK_DOSPUNTOS,
    TOK_ERROR
} TipoToken;

typedef struct {
    TipoToken tipo;
    char texto[128];
    double numero;
    int linea;
} Token;

/* ---------- Nodos de AST ---------- */

typedef enum {
    N_PROGRAMA, N_BLOQUE,
    N_DECIR, N_VARIABLE, N_ASIGNAR, N_CONST,
    N_SI, N_MIENTRAS, N_REPETIR,
    N_FUNCION, N_DEVOLVER, N_LLAMAR, N_LLAMAR_VALOR,
    N_ROMPER, N_CONTINUAR,
    /* expresiones */
    N_NUMERO, N_TEXTO, N_BOOL, N_IDENT,
    N_BINARIA, N_UNARIA, N_LLAMADA_EXPR
} TipoNodo;

typedef struct Nodo {
    TipoNodo tipo;
    int linea;

    /* literales / identificadores */
    double numero;
    char texto[256];

    /* operador para N_BINARIA / N_UNARIA */
    TipoToken operador;

    /* hijos genericos (listas enlazadas simples) */
    struct Nodo *izq;      /* condicion / lhs / valor a devolver / callee */
    struct Nodo *der;      /* rhs */
    struct Nodo *cuerpo;   /* bloque principal (si, mientras, funcion...) */
    struct Nodo *cuerpo2;  /* bloque "sino" */
    struct Nodo *siguiente;/* siguiente sentencia en un bloque, o siguiente arg */
    struct Nodo *args;     /* lista de argumentos (llamadas y parametros) */
} Nodo;

/* ---------- Valores en tiempo de ejecucion ---------- */

typedef enum { V_NUMERO, V_TEXTO, V_BOOL, V_NULO } TipoValor;

typedef struct {
    TipoValor tipo;
    double numero;
    char texto[256];
} Valor;

/* ---------- Lexer ---------- */

typedef struct {
    const char *fuente;
    size_t pos;
    int linea;
} Lexer;

void lexer_iniciar(Lexer *lx, const char *fuente);
Token lexer_siguiente(Lexer *lx);

/* ---------- Parser ---------- */

Nodo *analizar_programa(const char *fuente_completa);

/* ---------- Interprete ---------- */

int interpretar_programa(Nodo *raiz);

/* ---------- Capa de hardware (HAL) ---------- */
/* hal_host.c la implementa en modo simulado (imprime lo que pasaria);
 * un futuro hal_avr.c / hal_esp32.c la implementaria contra pines reales. */

void hal_pin_modo(int pin, int modo);          /* 0=entrada, 1=salida */
void hal_pin_escribir(int pin, int valor);     /* 0 o 1 */
int  hal_pin_leer(int pin);
int  hal_analogico_leer(int pin);              /* 0-1023 simulado */
void hal_pwm_escribir(int pin, int valor);     /* 0-255 */
void hal_esperar_ms(int ms);

#endif
