expressions.h (13801B)
1 #pragma once 2 3 #include <stdbool.h> 4 #include <stddef.h> 5 #include <stdint.h> 6 7 #include "nvim/eval/typval_defs.h" 8 #include "nvim/types_defs.h" 9 #include "nvim/viml/parser/parser_defs.h" 10 11 // Defines whether to ignore case: 12 // == kCCStrategyUseOption 13 // ==# kCCStrategyMatchCase 14 // ==? kCCStrategyIgnoreCase 15 typedef enum { 16 kCCStrategyUseOption = 0, // 0 for xcalloc 17 kCCStrategyMatchCase = '#', 18 kCCStrategyIgnoreCase = '?', 19 } ExprCaseCompareStrategy; 20 21 /// Lexer token type 22 typedef enum { 23 kExprLexInvalid = 0, ///< Invalid token, indicaten an error. 24 kExprLexMissing, ///< Missing token, for use in parser. 25 kExprLexSpacing, ///< Spaces, tabs, newlines, etc. 26 kExprLexEOC, ///< End of command character: NL, |, just end of stream. 27 28 kExprLexQuestion, ///< Question mark, for use in ternary. 29 kExprLexColon, ///< Colon, for use in ternary. 30 kExprLexOr, ///< Logical or operator. 31 kExprLexAnd, ///< Logical and operator. 32 kExprLexComparison, ///< One of the comparison operators. 33 kExprLexPlus, ///< Plus sign. 34 kExprLexMinus, ///< Minus sign. 35 kExprLexDot, ///< Dot: either concat or subscript, also part of the float. 36 kExprLexMultiplication, ///< Multiplication, division or modulo operator. 37 38 kExprLexNot, ///< Not: !. 39 40 kExprLexNumber, ///< Integer number literal, or part of a float. 41 kExprLexSingleQuotedString, ///< Single quoted string literal. 42 kExprLexDoubleQuotedString, ///< Double quoted string literal. 43 kExprLexOption, ///< &optionname option value. 44 kExprLexRegister, ///< @r register value. 45 kExprLexEnv, ///< Environment $variable value. 46 kExprLexPlainIdentifier, ///< Identifier without scope: `abc`, `foo#bar`. 47 48 kExprLexBracket, ///< Bracket, either opening or closing. 49 kExprLexFigureBrace, ///< Figure brace, either opening or closing. 50 kExprLexParenthesis, ///< Parenthesis, either opening or closing. 51 kExprLexComma, ///< Comma. 52 kExprLexArrow, ///< Arrow, like from lambda expressions. 53 kExprLexAssignment, ///< Assignment: `=` or `{op}=`. 54 // XXX When modifying this enum you need to also modify eltkn_type_tab in 55 // expressions.c and tests and, possibly, viml_pexpr_repr_token. 56 } LexExprTokenType; 57 58 typedef enum { 59 kExprCmpEqual, ///< Equality, inequality. 60 kExprCmpMatches, ///< Matches regex, not matches regex. 61 kExprCmpGreater, ///< `>` or `<=` 62 kExprCmpGreaterOrEqual, ///< `>=` or `<`. 63 kExprCmpIdentical, ///< `is` or `isnot` 64 } ExprComparisonType; 65 66 /// All possible option scopes 67 typedef enum { 68 kExprOptScopeUnspecified = 0, 69 kExprOptScopeGlobal = 'g', 70 kExprOptScopeLocal = 'l', 71 } ExprOptScope; 72 73 /// All possible assignment types: `=` and `{op}=`. 74 typedef enum { 75 kExprAsgnPlain = 0, ///< Plain assignment: `=`. 76 kExprAsgnAdd, ///< Assignment augmented with addition: `+=`. 77 kExprAsgnSubtract, ///< Assignment augmented with subtraction: `-=`. 78 kExprAsgnConcat, ///< Assignment augmented with concatenation: `.=`. 79 } ExprAssignmentType; 80 81 #define EXPR_OPT_SCOPE_LIST \ 82 ((char[]){ kExprOptScopeGlobal, kExprOptScopeLocal }) 83 84 /// All possible variable scopes 85 typedef enum { 86 kExprVarScopeMissing = 0, 87 kExprVarScopeScript = 's', 88 kExprVarScopeGlobal = 'g', 89 kExprVarScopeVim = 'v', 90 kExprVarScopeBuffer = 'b', 91 kExprVarScopeWindow = 'w', 92 kExprVarScopeTabpage = 't', 93 kExprVarScopeLocal = 'l', 94 kExprVarScopeArguments = 'a', 95 } ExprVarScope; 96 97 #define EXPR_VAR_SCOPE_LIST \ 98 ((char[]) { \ 99 kExprVarScopeScript, kExprVarScopeGlobal, kExprVarScopeVim, \ 100 kExprVarScopeBuffer, kExprVarScopeWindow, kExprVarScopeTabpage, \ 101 kExprVarScopeLocal, kExprVarScopeBuffer, kExprVarScopeArguments, \ 102 }) 103 104 /// Lexer token 105 typedef struct { 106 ParserPosition start; 107 size_t len; 108 LexExprTokenType type; 109 union { 110 struct { 111 ExprComparisonType type; ///< Comparison type. 112 ExprCaseCompareStrategy ccs; ///< Case comparison strategy. 113 bool inv; ///< True if comparison is to be inverted. 114 } cmp; ///< For kExprLexComparison. 115 116 struct { 117 enum { 118 kExprLexMulMul, ///< Real multiplication. 119 kExprLexMulDiv, ///< Division. 120 kExprLexMulMod, ///< Modulo. 121 } type; ///< Multiplication type. 122 } mul; ///< For kExprLexMultiplication. 123 124 struct { 125 bool closing; ///< True if bracket/etc is a closing one. 126 } brc; ///< For brackets/braces/parenthesis. 127 128 struct { 129 int name; ///< Register name, may be -1 if name not present. 130 } reg; ///< For kExprLexRegister. 131 132 struct { 133 bool closed; ///< True if quote was closed. 134 } str; ///< For kExprLexSingleQuotedString and kExprLexDoubleQuotedString. 135 136 struct { 137 const char *name; ///< Option name start. 138 size_t len; ///< Option name length. 139 ExprOptScope scope; ///< Option scope: &l:, &g: or not specified. 140 } opt; ///< Option properties. 141 142 struct { 143 ExprVarScope scope; ///< Scope character or 0 if not present. 144 bool autoload; ///< Has autoload characters. 145 } var; ///< For kExprLexPlainIdentifier 146 147 struct { 148 LexExprTokenType type; ///< Suggested type for parsing incorrect code. 149 const char *msg; ///< Error message. 150 } err; ///< For kExprLexInvalid 151 152 struct { 153 union { 154 float_T floating; 155 uvarnumber_T integer; 156 } val; ///< Number value. 157 uint8_t base; ///< Base: 2, 8, 10 or 16. 158 bool is_float; ///< True if number is a floating-point. 159 } num; ///< For kExprLexNumber 160 161 struct { 162 ExprAssignmentType type; 163 } ass; ///< For kExprLexAssignment 164 } data; ///< Additional data, if needed. 165 } LexExprToken; 166 167 typedef enum { 168 /// If set, “pointer” to the current byte in pstate will not be shifted 169 kELFlagPeek = (1 << 0), 170 /// Determines whether scope is allowed to come before the identifier 171 kELFlagForbidScope = (1 << 1), 172 /// Determines whether floating-point numbers are allowed 173 /// 174 /// I.e. whether dot is a decimal point separator or is not a part of 175 /// a number at all. 176 kELFlagAllowFloat = (1 << 2), 177 /// Determines whether `is` and `isnot` are seen as comparison operators 178 /// 179 /// If set they are supposed to be just regular identifiers. 180 kELFlagIsNotCmp = (1 << 3), 181 /// Determines whether EOC tokens are allowed 182 /// 183 /// If set then it will yield Invalid token with E15 in place of EOC one if 184 /// “EOC” is something like "|". It is fine with emitting EOC at the end of 185 /// string still, with or without this flag set. 186 kELFlagForbidEOC = (1 << 4), 187 // XXX Whenever you add a new flag, alter klee_assume() statement in 188 // viml_expressions_lexer.c. 189 } LexExprFlags; 190 191 /// Expression AST node type 192 typedef enum { 193 kExprNodeMissing = 0, 194 kExprNodeOpMissing, 195 kExprNodeTernary, ///< Ternary operator. 196 kExprNodeTernaryValue, ///< Ternary operator, colon. 197 kExprNodeRegister, ///< Register. 198 kExprNodeSubscript, ///< Subscript. 199 kExprNodeListLiteral, ///< List literal. 200 kExprNodeUnaryPlus, 201 kExprNodeBinaryPlus, 202 kExprNodeNested, ///< Nested parenthesised expression. 203 kExprNodeCall, ///< Function call. 204 /// Plain identifier: simple variable/function name 205 /// 206 /// Looks like "string", "g:Foo", etc: consists from a single 207 /// kExprLexPlainIdentifier token. 208 kExprNodePlainIdentifier, 209 /// Plain dictionary key, for use with kExprNodeConcatOrSubscript 210 kExprNodePlainKey, 211 /// Complex identifier: variable/function name with curly braces 212 kExprNodeComplexIdentifier, 213 /// Figure brace expression which is not yet known 214 /// 215 /// May resolve to any of kExprNodeDictLiteral, kExprNodeLambda or 216 /// kExprNodeCurlyBracesIdentifier. 217 kExprNodeUnknownFigure, 218 kExprNodeLambda, ///< Lambda. 219 kExprNodeDictLiteral, ///< Dict literal. 220 kExprNodeCurlyBracesIdentifier, ///< Part of the curly braces name. 221 kExprNodeComma, ///< Comma “operator”. 222 kExprNodeColon, ///< Colon “operator”. 223 kExprNodeArrow, ///< Arrow “operator”. 224 kExprNodeComparison, ///< Various comparison operators. 225 /// Concat operator 226 /// 227 /// To be only used in cases when it is known for sure it is not a subscript. 228 kExprNodeConcat, 229 /// Concat or subscript operator 230 /// 231 /// For cases when it is not obvious whether expression is a concat or 232 /// a subscript. May only have either number or plain identifier as the second 233 /// child. To make it easier to avoid curly braces in place of 234 /// kExprNodePlainIdentifier node kExprNodePlainKey is used. 235 kExprNodeConcatOrSubscript, 236 kExprNodeInteger, ///< Integral number. 237 kExprNodeFloat, ///< Floating-point number. 238 kExprNodeSingleQuotedString, 239 kExprNodeDoubleQuotedString, 240 kExprNodeOr, 241 kExprNodeAnd, 242 kExprNodeUnaryMinus, 243 kExprNodeBinaryMinus, 244 kExprNodeNot, 245 kExprNodeMultiplication, 246 kExprNodeDivision, 247 kExprNodeMod, 248 kExprNodeOption, 249 kExprNodeEnvironment, 250 kExprNodeAssignment, 251 // XXX When modifying this list also modify east_node_type_tab both in parser 252 // and in tests, and you most likely will also have to alter list of 253 // highlight groups stored in highlight_init_cmdline variable. 254 } ExprASTNodeType; 255 256 typedef struct expr_ast_node ExprASTNode; 257 258 /// Structure representing one AST node 259 struct expr_ast_node { 260 ExprASTNodeType type; ///< Node type. 261 /// Node children: e.g. for 1 + 2 nodes 1 and 2 will be children of +. 262 ExprASTNode *children; 263 /// Next node: e.g. for 1 + 2 child nodes 1 and 2 are put into a single-linked 264 /// list: `(+)->children` references only node 1, node 2 is in 265 /// `(+)->children->next`. 266 ExprASTNode *next; 267 ParserPosition start; 268 size_t len; 269 union { 270 struct { 271 int name; ///< Register name, may be -1 if name not present. 272 } reg; ///< For kExprNodeRegister. 273 struct { 274 /// Which nodes UnknownFigure can’t possibly represent. 275 struct { 276 /// True if UnknownFigure may actually represent dictionary literal. 277 bool allow_dict; 278 /// True if UnknownFigure may actually represent lambda. 279 bool allow_lambda; 280 /// True if UnknownFigure may actually be part of curly braces name. 281 bool allow_ident; 282 } type_guesses; 283 /// Highlight chunk index, used for rehighlighting if needed 284 size_t opening_hl_idx; 285 } fig; ///< For kExprNodeUnknownFigure. 286 struct { 287 ExprVarScope scope; ///< Scope character or 0 if not present. 288 /// Actual identifier without scope. 289 /// 290 /// Points to inside parser reader state. 291 const char *ident; 292 size_t ident_len; ///< Actual identifier length. 293 } var; ///< For kExprNodePlainIdentifier and kExprNodePlainKey. 294 struct { 295 bool got_colon; ///< True if colon was seen. 296 } ter; ///< For kExprNodeTernaryValue. 297 struct { 298 ExprComparisonType type; ///< Comparison type. 299 ExprCaseCompareStrategy ccs; ///< Case comparison strategy. 300 bool inv; ///< True if comparison is to be inverted. 301 } cmp; ///< For kExprNodeComparison. 302 struct { 303 uvarnumber_T value; 304 } num; ///< For kExprNodeInteger. 305 struct { 306 float_T value; 307 } flt; ///< For kExprNodeFloat. 308 struct { 309 char *value; 310 size_t size; 311 } str; ///< For kExprNodeSingleQuotedString and 312 ///< kExprNodeDoubleQuotedString. 313 struct { 314 const char *ident; ///< Option name start. 315 size_t ident_len; ///< Option name length. 316 ExprOptScope scope; ///< Option scope: &l:, &g: or not specified. 317 } opt; ///< For kExprNodeOption. 318 struct { 319 const char *ident; ///< Environment variable name start. 320 size_t ident_len; ///< Environment variable name length. 321 } env; ///< For kExprNodeEnvironment. 322 struct { 323 ExprAssignmentType type; 324 } ass; ///< For kExprNodeAssignment 325 } data; 326 }; 327 328 enum ExprParserFlags { 329 /// Allow multiple expressions in a row: e.g. for :echo 330 /// 331 /// Parser will still parse only one of them though. 332 kExprFlagsMulti = (1 << 0), 333 /// Allow NL, NUL and bar to be EOC 334 /// 335 /// When parsing expressions input by user bar is assumed to be a binary 336 /// operator and other two are spacings. 337 kExprFlagsDisallowEOC = (1 << 1), 338 /// Parse :let argument 339 /// 340 /// That mean that top level node must be an assignment and first nodes 341 /// belong to lvalues. 342 kExprFlagsParseLet = (1 << 2), 343 // XXX whenever you add a new flag, alter klee_assume() statement in 344 // viml_expressions_parser.c, nvim_parse_expression() flags parsing 345 // alongside with its documentation and flag sets in check_parsing() 346 // function in expressions parser functional and unit tests. 347 }; 348 349 /// AST error definition 350 typedef struct { 351 /// Error message. Must contain a single printf format atom: %.*s. 352 const char *msg; 353 /// Error message argument: points to the location of the error. 354 const char *arg; 355 /// Message argument length: length till the end of string. 356 int arg_len; 357 } ExprASTError; 358 359 /// Structure representing complete AST for one expression 360 typedef struct { 361 /// When AST is not correct this message will be printed. 362 /// 363 /// Uses `semsg(msg, arg_len, arg);`, `msg` is assumed to contain only `%.*s`. 364 ExprASTError err; 365 /// Root node of the AST. 366 ExprASTNode *root; 367 } ExprAST; 368 369 /// Array mapping ExprASTNodeType to maximum amount of children node may have 370 extern const uint8_t node_maxchildren[]; 371 372 /// Array mapping ExprASTNodeType values to their stringified versions 373 extern const char *const east_node_type_tab[]; 374 375 /// Array mapping ExprComparisonType values to their stringified versions 376 extern const char *const eltkn_cmp_type_tab[]; 377 378 /// Array mapping ExprCaseCompareStrategy values to their stringified versions 379 extern const char *const ccs_tab[]; 380 381 /// Array mapping ExprAssignmentType values to their stringified versions 382 extern const char *const expr_asgn_type_tab[]; 383 384 #include "viml/parser/expressions.h.generated.h"