gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 815Rust 56Shell 37Markdown 291229 Definitions

⎇ main crates/simi/src/ast.rs Rust · 129 lines · 3.7 KB History Who touched what raw

simi: el /bin/sh propio del producto — 4448 líneas, sólo libc, y CERO divergencias contra el ash 6809ef4be · Sergio ·

1//! El árbol. Nada de estado ni de ejecución acá: sólo la forma del lenguaje.
2
3/// Un trozo de palabra. La palabra se arma en el lexer y se expande en `expand`, en ese orden:
4/// tilde → parámetro/orden/aritmética → división en campos → rutas → quita de comillas.
5#[derive(Debug, Clone, PartialEq)]
6pub enum Seg {
7    /// Texto literal. `comillado` = vino de comillas ⇒ **no** se divide en campos ni se globea.
8    Lit { texto: String, comillado: bool },
9    /// `~` al principio de una palabra (o de un campo tras `:` en una asignación).
10    Tilde,
11    /// `$x`, `${x}`, `${x:-def}`, `${#x}`, `${x%%pat}`… `comillado` va aparte porque
12    /// `"$x"` no se divide y `$x` sí.
13    Param { nombre: String, op: ParamOp, arg: Vec<Seg>, comillado: bool },
14    /// `$( … )` y `` ` … ` ``. El cuerpo es shell otra vez y se parsea al expandir.
15    CmdSub { cuerpo: String, comillado: bool },
16    /// `$(( … ))`.
17    Arith { expr: String, comillado: bool },
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum ParamOp {
22    /// `$x` / `${x}`
23    Valor,
24    /// `${#x}`
25    Largo,
26    /// `${x:-p}` · `${x-p}` (sin dos puntos: sólo si NO está definida)
27    Defecto { dos_puntos: bool },
28    /// `${x:=p}` · `${x=p}`
29    Asigna { dos_puntos: bool },
30    /// `${x:?p}` · `${x?p}`
31    Error { dos_puntos: bool },
32    /// `${x:+p}` · `${x+p}`
33    Alterno { dos_puntos: bool },
34    /// `${x#p}` · `${x##p}`
35    QuitaPrefijo { largo: bool },
36    /// `${x%p}` · `${x%%p}`
37    QuitaSufijo { largo: bool },
38}
39
40pub type Palabra = Vec<Seg>;
41
42#[derive(Debug, Clone, PartialEq)]
43pub enum Redir {
44    /// `n> pal` (`trunca` falso ⇒ `>>`)
45    Salida { fd: i32, destino: Palabra, append: bool },
46    /// `n< pal`
47    Entrada { fd: i32, origen: Palabra },
48    /// `n<> pal`
49    LecturaEscritura { fd: i32, ruta: Palabra },
50    /// `n>&m`, `n<&m`, y los cierres `n>&-` / `n<&-`
51    Duplica { fd: i32, otro: DupDestino, escritura: bool },
52    /// `n<< DELIM` ya resuelto: el cuerpo viene del lexer. `expande` = el delimitador NO estaba
53    /// entrecomillado.
54    AquiDoc { fd: i32, cuerpo: Palabra, expande: bool },
55}
56
57#[derive(Debug, Clone, PartialEq)]
58pub enum DupDestino {
59    Fd(Palabra),
60    Cerrar,
61}
62
63#[derive(Debug, Clone, PartialEq)]
64pub struct Asignacion {
65    pub nombre: String,
66    pub valor: Palabra,
67}
68
69#[derive(Debug, Clone, PartialEq)]
70pub enum Orden {
71    Simple {
72        asignaciones: Vec<Asignacion>,
73        palabras: Vec<Palabra>,
74        redirs: Vec<Redir>,
75    },
76    /// `{ …; }`
77    Grupo { cuerpo: Lista, redirs: Vec<Redir> },
78    /// `( … )`
79    Subshell { cuerpo: Lista, redirs: Vec<Redir> },
80    Si {
81        ramas: Vec<(Lista, Lista)>, // (condición, cuerpo)
82        sino: Option<Lista>,
83        redirs: Vec<Redir>,
84    },
85    /// `while`/`until`
86    Bucle { hasta: bool, cond: Lista, cuerpo: Lista, redirs: Vec<Redir> },
87    Para {
88        var: String,
89        /// `None` = `for x; do` ⇒ itera sobre `"$@"`
90        palabras: Option<Vec<Palabra>>,
91        cuerpo: Lista,
92        redirs: Vec<Redir>,
93    },
94    Caso {
95        sujeto: Palabra,
96        ramas: Vec<(Vec<Palabra>, Lista)>,
97        redirs: Vec<Redir>,
98    },
99    Funcion { nombre: String, cuerpo: Box<Orden> },
100}
101
102#[derive(Debug, Clone, PartialEq)]
103pub struct Tuberia {
104    /// `! cmd | cmd`
105    pub negada: bool,
106    pub ordenes: Vec<Orden>,
107}
108
109#[derive(Debug, Clone, Copy, PartialEq, Eq)]
110pub enum Enlace {
111    Y,  // &&
112    O,  // ||
113}
114
115#[derive(Debug, Clone, PartialEq)]
116pub struct YO {
117    pub primera: Tuberia,
118    pub resto: Vec<(Enlace, Tuberia)>,
119}
120
121#[derive(Debug, Clone, Copy, PartialEq, Eq)]
122pub enum Fin {
123    /// `;` o fin de línea
124    Secuencial,
125    /// `&`
126    SegundoPlano,
127}
128
129pub type Lista = Vec<(YO, Fin)>;