// Dos formas de leer una cadena de restas, sin construir un árbol: se calcula al vuelo.
//
//   por la derecha:  chain → NUMBER [ "-" chain ]
//   con un ciclo:    chain → NUMBER ("-" NUMBER)*
#include <stdio.h>

#include "lexer.h"

typedef struct {
    Lexer *lexer;
    Token current;
    int failed;
} Parser;

static void advance(Parser *p) {
    p->current = lexer_next(p->lexer);
}

static double read_number(Parser *p) {
    if (p->current.kind != TOKEN_NUMBER) {
        p->failed = 1;
        return 0.0;
    }
    double value = p->current.number;
    advance(p);
    return value;
}

static double chain_right(Parser *p) {
    double value = read_number(p);
    if (p->current.kind == TOKEN_MINUS) {
        advance(p);
        return value - chain_right(p);
    }
    return value;
}

static double chain_loop(Parser *p) {
    double value = read_number(p);
    while (p->current.kind == TOKEN_MINUS) {
        advance(p);
        value = value - read_number(p);
    }
    return value;
}

// Corre una de las dos funciones sobre el texto. Devuelve 1 si lo pudo leer completo.
static int run_chain(const char *source, double (*chain)(Parser *), double *value) {
    Parser parser = {.lexer = lexer_new(source), .failed = 0};
    if (parser.lexer == NULL) {
        return 0;
    }
    advance(&parser);
    *value = chain(&parser);
    int ok = !parser.failed && parser.current.kind == TOKEN_END;
    lexer_free(parser.lexer);
    return ok;
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "uso: %s 'a - b - c'\n", argv[0]);
        return 1;
    }
    double right;
    double loop;
    if (!run_chain(argv[1], chain_right, &right) || !run_chain(argv[1], chain_loop, &loop)) {
        printf("solo entiendo números separados por -\n");
        return 1;
    }
    printf("recursión por la derecha: %g\n", right);
    printf("con un ciclo:             %g\n", loop);
    return 0;
}
