//! El árbol del programa. use std::rc::Rc; use crate::regex::Regex; #[derive(Debug, Clone, Copy, PartialEq)] pub enum BinOp { Suma, Resta, Mult, Div, Modulo, Potencia } #[derive(Debug, Clone, Copy, PartialEq)] pub enum CmpOp { Lt, Le, Gt, Ge, Eq, Ne } #[derive(Clone)] pub enum Expr { Num(f64), Cad(String), /// Una ERE suelta: como expresión vale `$0 ~ /re/`. Ere(Rc), Var(String), Campo(Box), /// `a[i]`, `a[i,j]` (los índices se unen con SUBSEP). Indice(String, Vec), Asigna(Box, Box), /// `+=`, `-=`, … con su operador. AsignaOp(Box, BinOp, Box), Bin(BinOp, Box, Box), Cmp(CmpOp, Box, Box), /// `~` y `!~`. El segundo `bool` dice si está negado. Coincide(Box, Box, bool), Y(Box, Box), O(Box, Box), No(Box), Neg(Box), Pos(Box), Ternario(Box, Box, Box), /// Concatenación por yuxtaposición: `a b`. Concat(Box, Box), /// `++x` / `x++` (y `--`). `previo` = es prefijo. Incr(Box, bool, f64), /// `(i, j) in a` y `i in a`. En(Vec, String), Llamada(String, Vec), Builtin(String, Vec), /// `getline` en sus cuatro formas. Getline(Getline), /// `(expr)` agrupada: hay que recordarlo para distinguir `(a,b) in arr` de una lista. Grupo(Box), } #[derive(Clone)] pub enum Getline { /// `getline [lugar]` — de la entrada normal. Simple(Option>), /// `getline [lugar] < "fichero"`. DeFichero(Option>, Box), /// `"cmd" | getline [lugar]`. DeTuberia(Box, Option>), } /// Algo a lo que se puede asignar. #[derive(Clone)] pub enum Lugar { Var(String), Campo(Box), Indice(String, Vec), } #[derive(Clone)] pub enum Redir { /// `> f` Fichero(Box), /// `>> f` Anexa(Box), /// `| "cmd"` Tuberia(Box), } #[derive(Clone)] pub enum Sent { Expr(Expr), Print(Vec, Option), Printf(Vec, Option), Bloque(Vec), Si(Expr, Box, Option>), Mientras(Expr, Box), HazMientras(Box, Expr), /// `for (init; cond; paso) cuerpo` Para(Option>, Option, Option>, Box), /// `for (k in a) cuerpo` ParaEn(String, String, Box), Corta, Sigue, Siguiente, SiguienteFichero, Sale(Option), Retorna(Option), Borra(String, Vec), /// `delete a` entero. BorraTodo(String), Nada, } #[derive(Clone)] pub enum Patron { Begin, End, /// Sin patrón: la acción corre para cada registro. Siempre, Expr(Expr), /// `expr1, expr2` — rango. El `bool` es el estado (dentro/fuera), que vive en el intérprete. Rango(Expr, Expr), } #[derive(Clone)] pub struct Regla { pub patron: Patron, pub accion: Option>, /// Índice del estado de rango, para las reglas `expr1, expr2`. pub rango_id: usize, } #[derive(Clone)] pub struct Funcion { pub nombre: String, pub params: Vec, pub cuerpo: Vec, } #[derive(Clone, Default)] pub struct Programa { pub reglas: Vec, pub funciones: Vec, pub rangos: usize, }