|
| 1 | +/** |
| 2 | + * AWK Abstract Syntax Tree Types |
| 3 | + * |
| 4 | + * Follows the same discriminated union pattern as the main bash AST. |
| 5 | + */ |
| 6 | + |
| 7 | +// ─── Expressions ─────────────────────────────────────────── |
| 8 | + |
| 9 | +export type AwkExpr = |
| 10 | + | AwkNumberLiteral |
| 11 | + | AwkStringLiteral |
| 12 | + | AwkRegexLiteral |
| 13 | + | AwkFieldRef |
| 14 | + | AwkVariable |
| 15 | + | AwkArrayAccess |
| 16 | + | AwkBinaryOp |
| 17 | + | AwkUnaryOp |
| 18 | + | AwkTernaryOp |
| 19 | + | AwkFunctionCall |
| 20 | + | AwkAssignment |
| 21 | + | AwkPreIncrement |
| 22 | + | AwkPreDecrement |
| 23 | + | AwkPostIncrement |
| 24 | + | AwkPostDecrement |
| 25 | + | AwkGetline |
| 26 | + | AwkInExpr |
| 27 | + | AwkTuple; |
| 28 | + |
| 29 | +export interface AwkNumberLiteral { |
| 30 | + type: "number"; |
| 31 | + value: number; |
| 32 | +} |
| 33 | + |
| 34 | +export interface AwkStringLiteral { |
| 35 | + type: "string"; |
| 36 | + value: string; |
| 37 | +} |
| 38 | + |
| 39 | +export interface AwkRegexLiteral { |
| 40 | + type: "regex"; |
| 41 | + pattern: string; |
| 42 | +} |
| 43 | + |
| 44 | +export interface AwkFieldRef { |
| 45 | + type: "field"; |
| 46 | + index: AwkExpr; |
| 47 | +} |
| 48 | + |
| 49 | +export interface AwkVariable { |
| 50 | + type: "variable"; |
| 51 | + name: string; |
| 52 | +} |
| 53 | + |
| 54 | +export interface AwkArrayAccess { |
| 55 | + type: "array_access"; |
| 56 | + array: string; |
| 57 | + key: AwkExpr; |
| 58 | +} |
| 59 | + |
| 60 | +export interface AwkBinaryOp { |
| 61 | + type: "binary"; |
| 62 | + operator: |
| 63 | + | "+" |
| 64 | + | "-" |
| 65 | + | "*" |
| 66 | + | "/" |
| 67 | + | "%" |
| 68 | + | "^" |
| 69 | + | "==" |
| 70 | + | "!=" |
| 71 | + | "<" |
| 72 | + | ">" |
| 73 | + | "<=" |
| 74 | + | ">=" |
| 75 | + | "~" |
| 76 | + | "!~" |
| 77 | + | "&&" |
| 78 | + | "||" |
| 79 | + | " "; // concatenation |
| 80 | + left: AwkExpr; |
| 81 | + right: AwkExpr; |
| 82 | +} |
| 83 | + |
| 84 | +export interface AwkUnaryOp { |
| 85 | + type: "unary"; |
| 86 | + operator: "!" | "-" | "+"; |
| 87 | + operand: AwkExpr; |
| 88 | +} |
| 89 | + |
| 90 | +export interface AwkPreIncrement { |
| 91 | + type: "pre_increment"; |
| 92 | + operand: AwkVariable | AwkArrayAccess | AwkFieldRef; |
| 93 | +} |
| 94 | + |
| 95 | +export interface AwkPreDecrement { |
| 96 | + type: "pre_decrement"; |
| 97 | + operand: AwkVariable | AwkArrayAccess | AwkFieldRef; |
| 98 | +} |
| 99 | + |
| 100 | +export interface AwkPostIncrement { |
| 101 | + type: "post_increment"; |
| 102 | + operand: AwkVariable | AwkArrayAccess | AwkFieldRef; |
| 103 | +} |
| 104 | + |
| 105 | +export interface AwkPostDecrement { |
| 106 | + type: "post_decrement"; |
| 107 | + operand: AwkVariable | AwkArrayAccess | AwkFieldRef; |
| 108 | +} |
| 109 | + |
| 110 | +export interface AwkTernaryOp { |
| 111 | + type: "ternary"; |
| 112 | + condition: AwkExpr; |
| 113 | + consequent: AwkExpr; |
| 114 | + alternate: AwkExpr; |
| 115 | +} |
| 116 | + |
| 117 | +export interface AwkFunctionCall { |
| 118 | + type: "call"; |
| 119 | + name: string; |
| 120 | + args: AwkExpr[]; |
| 121 | +} |
| 122 | + |
| 123 | +export interface AwkAssignment { |
| 124 | + type: "assignment"; |
| 125 | + operator: "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "^="; |
| 126 | + target: AwkFieldRef | AwkVariable | AwkArrayAccess; |
| 127 | + value: AwkExpr; |
| 128 | +} |
| 129 | + |
| 130 | +export interface AwkInExpr { |
| 131 | + type: "in"; |
| 132 | + key: AwkExpr; |
| 133 | + array: string; |
| 134 | +} |
| 135 | + |
| 136 | +export interface AwkGetline { |
| 137 | + type: "getline"; |
| 138 | + variable?: string; |
| 139 | + file?: AwkExpr; |
| 140 | +} |
| 141 | + |
| 142 | +export interface AwkTuple { |
| 143 | + type: "tuple"; |
| 144 | + elements: AwkExpr[]; |
| 145 | +} |
| 146 | + |
| 147 | +// ─── Statements ──────────────────────────────────────────── |
| 148 | + |
| 149 | +export type AwkStmt = |
| 150 | + | AwkExpressionStmt |
| 151 | + | AwkPrintStmt |
| 152 | + | AwkPrintfStmt |
| 153 | + | AwkIfStmt |
| 154 | + | AwkWhileStmt |
| 155 | + | AwkDoWhileStmt |
| 156 | + | AwkForStmt |
| 157 | + | AwkForInStmt |
| 158 | + | AwkBreakStmt |
| 159 | + | AwkContinueStmt |
| 160 | + | AwkNextStmt |
| 161 | + | AwkNextFileStmt |
| 162 | + | AwkExitStmt |
| 163 | + | AwkReturnStmt |
| 164 | + | AwkDeleteStmt |
| 165 | + | AwkBlock; |
| 166 | + |
| 167 | +export interface AwkExpressionStmt { |
| 168 | + type: "expr_stmt"; |
| 169 | + expression: AwkExpr; |
| 170 | +} |
| 171 | + |
| 172 | +export interface AwkPrintStmt { |
| 173 | + type: "print"; |
| 174 | + args: AwkExpr[]; |
| 175 | + output?: { redirect: ">" | ">>"; file: AwkExpr }; |
| 176 | +} |
| 177 | + |
| 178 | +export interface AwkPrintfStmt { |
| 179 | + type: "printf"; |
| 180 | + format: AwkExpr; |
| 181 | + args: AwkExpr[]; |
| 182 | + output?: { redirect: ">" | ">>"; file: AwkExpr }; |
| 183 | +} |
| 184 | + |
| 185 | +export interface AwkIfStmt { |
| 186 | + type: "if"; |
| 187 | + condition: AwkExpr; |
| 188 | + consequent: AwkStmt; |
| 189 | + alternate?: AwkStmt; |
| 190 | +} |
| 191 | + |
| 192 | +export interface AwkWhileStmt { |
| 193 | + type: "while"; |
| 194 | + condition: AwkExpr; |
| 195 | + body: AwkStmt; |
| 196 | +} |
| 197 | + |
| 198 | +export interface AwkDoWhileStmt { |
| 199 | + type: "do_while"; |
| 200 | + body: AwkStmt; |
| 201 | + condition: AwkExpr; |
| 202 | +} |
| 203 | + |
| 204 | +export interface AwkForStmt { |
| 205 | + type: "for"; |
| 206 | + init?: AwkExpr; |
| 207 | + condition?: AwkExpr; |
| 208 | + update?: AwkExpr; |
| 209 | + body: AwkStmt; |
| 210 | +} |
| 211 | + |
| 212 | +export interface AwkForInStmt { |
| 213 | + type: "for_in"; |
| 214 | + variable: string; |
| 215 | + array: string; |
| 216 | + body: AwkStmt; |
| 217 | +} |
| 218 | + |
| 219 | +export interface AwkBlock { |
| 220 | + type: "block"; |
| 221 | + statements: AwkStmt[]; |
| 222 | +} |
| 223 | + |
| 224 | +export interface AwkBreakStmt { |
| 225 | + type: "break"; |
| 226 | +} |
| 227 | +export interface AwkContinueStmt { |
| 228 | + type: "continue"; |
| 229 | +} |
| 230 | +export interface AwkNextStmt { |
| 231 | + type: "next"; |
| 232 | +} |
| 233 | +export interface AwkNextFileStmt { |
| 234 | + type: "nextfile"; |
| 235 | +} |
| 236 | +export interface AwkExitStmt { |
| 237 | + type: "exit"; |
| 238 | + code?: AwkExpr; |
| 239 | +} |
| 240 | +export interface AwkReturnStmt { |
| 241 | + type: "return"; |
| 242 | + value?: AwkExpr; |
| 243 | +} |
| 244 | +export interface AwkDeleteStmt { |
| 245 | + type: "delete"; |
| 246 | + target: AwkArrayAccess | AwkVariable; |
| 247 | +} |
| 248 | + |
| 249 | +// ─── Program Structure ───────────────────────────────────── |
| 250 | + |
| 251 | +export type AwkPattern = |
| 252 | + | AwkBeginPattern |
| 253 | + | AwkEndPattern |
| 254 | + | AwkExprPattern |
| 255 | + | AwkRegexPattern |
| 256 | + | AwkRangePattern; |
| 257 | + |
| 258 | +export interface AwkBeginPattern { |
| 259 | + type: "begin"; |
| 260 | +} |
| 261 | +export interface AwkEndPattern { |
| 262 | + type: "end"; |
| 263 | +} |
| 264 | +export interface AwkExprPattern { |
| 265 | + type: "expr_pattern"; |
| 266 | + expression: AwkExpr; |
| 267 | +} |
| 268 | +export interface AwkRegexPattern { |
| 269 | + type: "regex_pattern"; |
| 270 | + pattern: string; |
| 271 | +} |
| 272 | +export interface AwkRangePattern { |
| 273 | + type: "range"; |
| 274 | + start: AwkPattern; |
| 275 | + end: AwkPattern; |
| 276 | +} |
| 277 | + |
| 278 | +export interface AwkRule { |
| 279 | + pattern?: AwkPattern; |
| 280 | + action: AwkBlock; |
| 281 | +} |
| 282 | + |
| 283 | +export interface AwkFunctionDef { |
| 284 | + name: string; |
| 285 | + params: string[]; |
| 286 | + body: AwkBlock; |
| 287 | +} |
| 288 | + |
| 289 | +export interface AwkProgram { |
| 290 | + functions: AwkFunctionDef[]; |
| 291 | + rules: AwkRule[]; |
| 292 | +} |
0 commit comments