// Las instrucciones de Mini. Un programa es una lista enlazada de Stmt, por el campo next.
//
// Ownership: cada instrucción es owner de sus cadenas y de sus árboles. Quien tiene la cabeza
// de la lista la libera con stmt_free.
#ifndef STMT_H
#define STMT_H

#include "expr.h"

typedef enum { STMT_LET, STMT_PRINT, STMT_DEF } StmtKind;

typedef struct stmt Stmt;

struct stmt {
    StmtKind kind;
    union {
        struct { char *name; Expr *value; } let;
        struct { Expr *value; } print;
        struct { char *name; char **params; int param_count; Expr *body; } def;     // params es NULL si son 0
    } as;
    Stmt *next;
};

// Devuelven una instrucción nueva con next en NULL. Se vuelven owners de value, params y body
// aunque fallen: en ese caso los liberan y devuelven NULL. Un value o un body NULL cuenta como falla.
Stmt *stmt_let(const char *name, Expr *value);
Stmt *stmt_print(Expr *value);
Stmt *stmt_def(const char *name, char **params, int param_count, Expr *body);

// Libera un arreglo de cadenas, como params. Acepta NULL.
void free_names(char **names, int count);

// Libera la lista completa. Acepta NULL.
void stmt_free(Stmt *program);

#endif
