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