aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/vim.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/api/vim.c')
-rw-r--r--src/nvim/api/vim.c714
1 files changed, 0 insertions, 714 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index cbaba72213..3ca6189ddd 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -60,84 +60,6 @@
# include "api/vim.c.generated.h"
#endif
-/// Executes Vimscript (multiline block of Ex-commands), like anonymous
-/// |:source|.
-///
-/// Unlike |nvim_command()| this function supports heredocs, script-scope (s:),
-/// etc.
-///
-/// On execution error: fails with VimL error, does not update v:errmsg.
-///
-/// @see |execute()|
-/// @see |nvim_command()|
-///
-/// @param src Vimscript code
-/// @param output Capture and return all (non-error, non-shell |:!|) output
-/// @param[out] err Error details (Vim error), if any
-/// @return Output (non-error, non-shell |:!|) if `output` is true,
-/// else empty string.
-String nvim_exec(String src, Boolean output, Error *err)
- FUNC_API_SINCE(7)
-{
- const int save_msg_silent = msg_silent;
- garray_T *const save_capture_ga = capture_ga;
- garray_T capture_local;
- if (output) {
- ga_init(&capture_local, 1, 80);
- capture_ga = &capture_local;
- }
-
- try_start();
- if (output) {
- msg_silent++;
- }
- do_source_str(src.data, "nvim_exec()");
- if (output) {
- capture_ga = save_capture_ga;
- msg_silent = save_msg_silent;
- }
- try_end(err);
-
- if (ERROR_SET(err)) {
- goto theend;
- }
-
- if (output && capture_local.ga_len > 1) {
- String s = (String){
- .data = capture_local.ga_data,
- .size = (size_t)capture_local.ga_len,
- };
- // redir usually (except :echon) prepends a newline.
- if (s.data[0] == '\n') {
- memmove(s.data, s.data + 1, s.size - 1);
- s.data[s.size - 1] = '\0';
- s.size = s.size - 1;
- }
- return s; // Caller will free the memory.
- }
-theend:
- if (output) {
- ga_clear(&capture_local);
- }
- return (String)STRING_INIT;
-}
-
-/// Executes an ex-command.
-///
-/// On execution error: fails with VimL error, does not update v:errmsg.
-///
-/// @see |nvim_exec()|
-///
-/// @param command Ex-command string
-/// @param[out] err Error details (Vim error), if any
-void nvim_command(String command, Error *err)
- FUNC_API_SINCE(1)
-{
- try_start();
- do_cmdline_cmd(command.data);
- try_end(err);
-}
-
/// Gets a highlight definition by name.
///
/// @param name Highlight group name
@@ -478,51 +400,6 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Bool
return cstr_as_string(ptr);
}
-/// Evaluates a VimL |expression|.
-/// Dictionaries and Lists are recursively expanded.
-///
-/// On execution error: fails with VimL error, does not update v:errmsg.
-///
-/// @param expr VimL expression string
-/// @param[out] err Error details, if any
-/// @return Evaluation result or expanded object
-Object nvim_eval(String expr, Error *err)
- FUNC_API_SINCE(1)
-{
- static int recursive = 0; // recursion depth
- Object rv = OBJECT_INIT;
-
- TRY_WRAP({
- // Initialize `force_abort` and `suppress_errthrow` at the top level.
- if (!recursive) {
- force_abort = false;
- suppress_errthrow = false;
- current_exception = NULL;
- // `did_emsg` is set by emsg(), which cancels execution.
- did_emsg = false;
- }
- recursive++;
- try_start();
-
- typval_T rettv;
- int ok = eval0((char_u *)expr.data, &rettv, NULL, true);
-
- if (!try_end(err)) {
- if (ok == FAIL) {
- // Should never happen, try_end() should get the error. #8371
- api_set_error(err, kErrorTypeException,
- "Failed to evaluate expression: '%.*s'", 256, expr.data);
- } else {
- rv = vim_to_object(&rettv);
- }
- }
-
- tv_clear(&rettv);
- recursive--;
- });
-
- return rv;
-}
/// Execute Lua code. Parameters (if any) are available as `...` inside the
/// chunk. The chunk can return a value.
@@ -563,164 +440,6 @@ Object nvim_notify(String msg, Integer log_level, Dictionary opts, Error *err)
return nlua_exec(STATIC_CSTR_AS_STRING("return vim.notify(...)"), args, err);
}
-/// Calls a VimL function.
-///
-/// @param fn Function name
-/// @param args Function arguments
-/// @param self `self` dict, or NULL for non-dict functions
-/// @param[out] err Error details, if any
-/// @return Result of the function call
-static Object _call_function(String fn, Array args, dict_T *self, Error *err)
-{
- static int recursive = 0; // recursion depth
- Object rv = OBJECT_INIT;
-
- if (args.size > MAX_FUNC_ARGS) {
- api_set_error(err, kErrorTypeValidation,
- "Function called with too many arguments");
- return rv;
- }
-
- // Convert the arguments in args from Object to typval_T values
- typval_T vim_args[MAX_FUNC_ARGS + 1];
- size_t i = 0; // also used for freeing the variables
- for (; i < args.size; i++) {
- if (!object_to_vim(args.items[i], &vim_args[i], err)) {
- goto free_vim_args;
- }
- }
-
- TRY_WRAP({
- // Initialize `force_abort` and `suppress_errthrow` at the top level.
- if (!recursive) {
- force_abort = false;
- suppress_errthrow = false;
- current_exception = NULL;
- // `did_emsg` is set by emsg(), which cancels execution.
- did_emsg = false;
- }
- recursive++;
- try_start();
- typval_T rettv;
- funcexe_T funcexe = FUNCEXE_INIT;
- funcexe.firstline = curwin->w_cursor.lnum;
- funcexe.lastline = curwin->w_cursor.lnum;
- funcexe.evaluate = true;
- funcexe.selfdict = self;
- // call_func() retval is deceptive, ignore it. Instead we set `msg_list`
- // (see above) to capture abort-causing non-exception errors.
- (void)call_func((char_u *)fn.data, (int)fn.size, &rettv, (int)args.size,
- vim_args, &funcexe);
- if (!try_end(err)) {
- rv = vim_to_object(&rettv);
- }
- tv_clear(&rettv);
- recursive--;
- });
-
-free_vim_args:
- while (i > 0) {
- tv_clear(&vim_args[--i]);
- }
-
- return rv;
-}
-
-/// Calls a VimL function with the given arguments.
-///
-/// On execution error: fails with VimL error, does not update v:errmsg.
-///
-/// @param fn Function to call
-/// @param args Function arguments packed in an Array
-/// @param[out] err Error details, if any
-/// @return Result of the function call
-Object nvim_call_function(String fn, Array args, Error *err)
- FUNC_API_SINCE(1)
-{
- return _call_function(fn, args, NULL, err);
-}
-
-/// Calls a VimL |Dictionary-function| with the given arguments.
-///
-/// On execution error: fails with VimL error, does not update v:errmsg.
-///
-/// @param dict Dictionary, or String evaluating to a VimL |self| dict
-/// @param fn Name of the function defined on the VimL dict
-/// @param args Function arguments packed in an Array
-/// @param[out] err Error details, if any
-/// @return Result of the function call
-Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err)
- FUNC_API_SINCE(4)
-{
- Object rv = OBJECT_INIT;
-
- typval_T rettv;
- bool mustfree = false;
- switch (dict.type) {
- case kObjectTypeString:
- try_start();
- if (eval0((char_u *)dict.data.string.data, &rettv, NULL, true) == FAIL) {
- api_set_error(err, kErrorTypeException,
- "Failed to evaluate dict expression");
- }
- if (try_end(err)) {
- return rv;
- }
- // Evaluation of the string arg created a new dict or increased the
- // refcount of a dict. Not necessary for a RPC dict.
- mustfree = true;
- break;
- case kObjectTypeDictionary:
- if (!object_to_vim(dict, &rettv, err)) {
- goto end;
- }
- break;
- default:
- api_set_error(err, kErrorTypeValidation,
- "dict argument type must be String or Dictionary");
- return rv;
- }
- dict_T *self_dict = rettv.vval.v_dict;
- if (rettv.v_type != VAR_DICT || !self_dict) {
- api_set_error(err, kErrorTypeValidation, "dict not found");
- goto end;
- }
-
- if (fn.data && fn.size > 0 && dict.type != kObjectTypeDictionary) {
- dictitem_T *const di = tv_dict_find(self_dict, fn.data, (ptrdiff_t)fn.size);
- if (di == NULL) {
- api_set_error(err, kErrorTypeValidation, "Not found: %s", fn.data);
- goto end;
- }
- if (di->di_tv.v_type == VAR_PARTIAL) {
- api_set_error(err, kErrorTypeValidation,
- "partial function not supported");
- goto end;
- }
- if (di->di_tv.v_type != VAR_FUNC) {
- api_set_error(err, kErrorTypeValidation, "Not a function: %s", fn.data);
- goto end;
- }
- fn = (String) {
- .data = (char *)di->di_tv.vval.v_string,
- .size = STRLEN(di->di_tv.vval.v_string),
- };
- }
-
- if (!fn.data || fn.size < 1) {
- api_set_error(err, kErrorTypeValidation, "Invalid (empty) function name");
- goto end;
- }
-
- rv = _call_function(fn, args, self_dict, err);
-end:
- if (mustfree) {
- tv_clear(&rettv);
- }
-
- return rv;
-}
-
/// Calculates the number of display cells occupied by `text`.
/// <Tab> counts as one cell.
///
@@ -1991,439 +1710,6 @@ theend:
return rv;
}
-typedef struct {
- ExprASTNode **node_p;
- Object *ret_node_p;
-} ExprASTConvStackItem;
-
-/// @cond DOXYGEN_NOT_A_FUNCTION
-typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack;
-/// @endcond
-
-/// Parse a VimL expression.
-///
-/// @param[in] expr Expression to parse. Always treated as a single line.
-/// @param[in] flags Flags:
-/// - "m" if multiple expressions in a row are allowed (only
-/// the first one will be parsed),
-/// - "E" if EOC tokens are not allowed (determines whether
-/// they will stop parsing process or be recognized as an
-/// operator/space, though also yielding an error).
-/// - "l" when needing to start parsing with lvalues for
-/// ":let" or ":for".
-/// Common flag sets:
-/// - "m" to parse like for ":echo".
-/// - "E" to parse like for "<C-r>=".
-/// - empty string for ":call".
-/// - "lm" to parse for ":let".
-/// @param[in] highlight If true, return value will also include "highlight"
-/// key containing array of 4-tuples (arrays) (Integer,
-/// Integer, Integer, String), where first three numbers
-/// define the highlighted region and represent line,
-/// starting column and ending column (latter exclusive:
-/// one should highlight region [start_col, end_col)).
-///
-/// @return
-/// - AST: top-level dictionary with these keys:
-/// - "error": Dictionary with error, present only if parser saw some
-/// error. Contains the following keys:
-/// - "message": String, error message in printf format, translated.
-/// Must contain exactly one "%.*s".
-/// - "arg": String, error message argument.
-/// - "len": Amount of bytes successfully parsed. With flags equal to ""
-/// that should be equal to the length of expr string.
-/// (“Successfully parsed” here means “participated in AST
-/// creation”, not “till the first error”.)
-/// - "ast": AST, either nil or a dictionary with these keys:
-/// - "type": node type, one of the value names from ExprASTNodeType
-/// stringified without "kExprNode" prefix.
-/// - "start": a pair [line, column] describing where node is "started"
-/// where "line" is always 0 (will not be 0 if you will be
-/// using nvim_parse_viml() on e.g. ":let", but that is not
-/// present yet). Both elements are Integers.
-/// - "len": “length” of the node. This and "start" are there for
-/// debugging purposes primary (debugging parser and providing
-/// debug information).
-/// - "children": a list of nodes described in top/"ast". There always
-/// is zero, one or two children, key will not be present
-/// if node has no children. Maximum number of children
-/// may be found in node_maxchildren array.
-/// - Local values (present only for certain nodes):
-/// - "scope": a single Integer, specifies scope for "Option" and
-/// "PlainIdentifier" nodes. For "Option" it is one of
-/// ExprOptScope values, for "PlainIdentifier" it is one of
-/// ExprVarScope values.
-/// - "ident": identifier (without scope, if any), present for "Option",
-/// "PlainIdentifier", "PlainKey" and "Environment" nodes.
-/// - "name": Integer, register name (one character) or -1. Only present
-/// for "Register" nodes.
-/// - "cmp_type": String, comparison type, one of the value names from
-/// ExprComparisonType, stringified without "kExprCmp"
-/// prefix. Only present for "Comparison" nodes.
-/// - "ccs_strategy": String, case comparison strategy, one of the
-/// value names from ExprCaseCompareStrategy,
-/// stringified without "kCCStrategy" prefix. Only
-/// present for "Comparison" nodes.
-/// - "augmentation": String, augmentation type for "Assignment" nodes.
-/// Is either an empty string, "Add", "Subtract" or
-/// "Concat" for "=", "+=", "-=" or ".=" respectively.
-/// - "invert": Boolean, true if result of comparison needs to be
-/// inverted. Only present for "Comparison" nodes.
-/// - "ivalue": Integer, integer value for "Integer" nodes.
-/// - "fvalue": Float, floating-point value for "Float" nodes.
-/// - "svalue": String, value for "SingleQuotedString" and
-/// "DoubleQuotedString" nodes.
-/// @param[out] err Error details, if any
-Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, Error *err)
- FUNC_API_SINCE(4) FUNC_API_FAST
-{
- int pflags = 0;
- for (size_t i = 0 ; i < flags.size ; i++) {
- switch (flags.data[i]) {
- case 'm':
- pflags |= kExprFlagsMulti; break;
- case 'E':
- pflags |= kExprFlagsDisallowEOC; break;
- case 'l':
- pflags |= kExprFlagsParseLet; break;
- case NUL:
- api_set_error(err, kErrorTypeValidation, "Invalid flag: '\\0' (%u)",
- (unsigned)flags.data[i]);
- return (Dictionary)ARRAY_DICT_INIT;
- default:
- api_set_error(err, kErrorTypeValidation, "Invalid flag: '%c' (%u)",
- flags.data[i], (unsigned)flags.data[i]);
- return (Dictionary)ARRAY_DICT_INIT;
- }
- }
- ParserLine parser_lines[] = {
- {
- .data = expr.data,
- .size = expr.size,
- .allocated = false,
- },
- { NULL, 0, false },
- };
- ParserLine *plines_p = parser_lines;
- ParserHighlight colors;
- kvi_init(colors);
- ParserHighlight *const colors_p = (highlight ? &colors : NULL);
- ParserState pstate;
- viml_parser_init(&pstate, parser_simple_get_line, &plines_p, colors_p);
- ExprAST east = viml_pexpr_parse(&pstate, pflags);
-
- const size_t ret_size = (
- 2 // "ast", "len"
- + (size_t)(east.err.msg != NULL) // "error"
- + (size_t)highlight // "highlight"
- + 0);
- Dictionary ret = {
- .items = xmalloc(ret_size * sizeof(ret.items[0])),
- .size = 0,
- .capacity = ret_size,
- };
- ret.items[ret.size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ast"),
- .value = NIL,
- };
- ret.items[ret.size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("len"),
- .value = INTEGER_OBJ((Integer)(pstate.pos.line == 1
- ? parser_lines[0].size
- : pstate.pos.col)),
- };
- if (east.err.msg != NULL) {
- Dictionary err_dict = {
- .items = xmalloc(2 * sizeof(err_dict.items[0])),
- .size = 2,
- .capacity = 2,
- };
- err_dict.items[0] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("message"),
- .value = STRING_OBJ(cstr_to_string(east.err.msg)),
- };
- if (east.err.arg == NULL) {
- err_dict.items[1] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("arg"),
- .value = STRING_OBJ(STRING_INIT),
- };
- } else {
- err_dict.items[1] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("arg"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(east.err.arg, (size_t)east.err.arg_len),
- .size = (size_t)east.err.arg_len,
- })),
- };
- }
- ret.items[ret.size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("error"),
- .value = DICTIONARY_OBJ(err_dict),
- };
- }
- if (highlight) {
- Array hl = (Array) {
- .items = xmalloc(kv_size(colors) * sizeof(hl.items[0])),
- .capacity = kv_size(colors),
- .size = kv_size(colors),
- };
- for (size_t i = 0 ; i < kv_size(colors) ; i++) {
- const ParserHighlightChunk chunk = kv_A(colors, i);
- Array chunk_arr = (Array) {
- .items = xmalloc(4 * sizeof(chunk_arr.items[0])),
- .capacity = 4,
- .size = 4,
- };
- chunk_arr.items[0] = INTEGER_OBJ((Integer)chunk.start.line);
- chunk_arr.items[1] = INTEGER_OBJ((Integer)chunk.start.col);
- chunk_arr.items[2] = INTEGER_OBJ((Integer)chunk.end_col);
- chunk_arr.items[3] = STRING_OBJ(cstr_to_string(chunk.group));
- hl.items[i] = ARRAY_OBJ(chunk_arr);
- }
- ret.items[ret.size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("highlight"),
- .value = ARRAY_OBJ(hl),
- };
- }
- kvi_destroy(colors);
-
- // Walk over the AST, freeing nodes in process.
- ExprASTConvStack ast_conv_stack;
- kvi_init(ast_conv_stack);
- kvi_push(ast_conv_stack, ((ExprASTConvStackItem) {
- .node_p = &east.root,
- .ret_node_p = &ret.items[0].value,
- }));
- while (kv_size(ast_conv_stack)) {
- ExprASTConvStackItem cur_item = kv_last(ast_conv_stack);
- ExprASTNode *const node = *cur_item.node_p;
- if (node == NULL) {
- assert(kv_size(ast_conv_stack) == 1);
- kv_drop(ast_conv_stack, 1);
- } else {
- if (cur_item.ret_node_p->type == kObjectTypeNil) {
- const size_t ret_node_items_size = (size_t)(
- 3 // "type", "start" and "len"
- + (node->children != NULL) // "children"
- + (node->type == kExprNodeOption
- || node->type == kExprNodePlainIdentifier) // "scope"
- + (node->type == kExprNodeOption
- || node->type == kExprNodePlainIdentifier
- || node->type == kExprNodePlainKey
- || node->type == kExprNodeEnvironment) // "ident"
- + (node->type == kExprNodeRegister) // "name"
- + (3 // "cmp_type", "ccs_strategy", "invert"
- * (node->type == kExprNodeComparison))
- + (node->type == kExprNodeInteger) // "ivalue"
- + (node->type == kExprNodeFloat) // "fvalue"
- + (node->type == kExprNodeDoubleQuotedString
- || node->type == kExprNodeSingleQuotedString) // "svalue"
- + (node->type == kExprNodeAssignment) // "augmentation"
- + 0);
- Dictionary ret_node = {
- .items = xmalloc(ret_node_items_size * sizeof(ret_node.items[0])),
- .capacity = ret_node_items_size,
- .size = 0,
- };
- *cur_item.ret_node_p = DICTIONARY_OBJ(ret_node);
- }
- Dictionary *ret_node = &cur_item.ret_node_p->data.dictionary;
- if (node->children != NULL) {
- const size_t num_children = 1 + (node->children->next != NULL);
- Array children_array = {
- .items = xmalloc(num_children * sizeof(children_array.items[0])),
- .capacity = num_children,
- .size = num_children,
- };
- for (size_t i = 0; i < num_children; i++) {
- children_array.items[i] = NIL;
- }
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("children"),
- .value = ARRAY_OBJ(children_array),
- };
- kvi_push(ast_conv_stack, ((ExprASTConvStackItem) {
- .node_p = &node->children,
- .ret_node_p = &children_array.items[0],
- }));
- } else if (node->next != NULL) {
- kvi_push(ast_conv_stack, ((ExprASTConvStackItem) {
- .node_p = &node->next,
- .ret_node_p = cur_item.ret_node_p + 1,
- }));
- } else {
- kv_drop(ast_conv_stack, 1);
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("type"),
- .value = STRING_OBJ(cstr_to_string(east_node_type_tab[node->type])),
- };
- Array start_array = {
- .items = xmalloc(2 * sizeof(start_array.items[0])),
- .capacity = 2,
- .size = 2,
- };
- start_array.items[0] = INTEGER_OBJ((Integer)node->start.line);
- start_array.items[1] = INTEGER_OBJ((Integer)node->start.col);
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("start"),
- .value = ARRAY_OBJ(start_array),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("len"),
- .value = INTEGER_OBJ((Integer)node->len),
- };
- switch (node->type) {
- case kExprNodeDoubleQuotedString:
- case kExprNodeSingleQuotedString:
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("svalue"),
- .value = STRING_OBJ(((String) {
- .data = node->data.str.value,
- .size = node->data.str.size,
- })),
- };
- break;
- case kExprNodeOption:
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("scope"),
- .value = INTEGER_OBJ(node->data.opt.scope),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.opt.ident,
- node->data.opt.ident_len),
- .size = node->data.opt.ident_len,
- })),
- };
- break;
- case kExprNodePlainIdentifier:
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("scope"),
- .value = INTEGER_OBJ(node->data.var.scope),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.var.ident,
- node->data.var.ident_len),
- .size = node->data.var.ident_len,
- })),
- };
- break;
- case kExprNodePlainKey:
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.var.ident,
- node->data.var.ident_len),
- .size = node->data.var.ident_len,
- })),
- };
- break;
- case kExprNodeEnvironment:
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.env.ident,
- node->data.env.ident_len),
- .size = node->data.env.ident_len,
- })),
- };
- break;
- case kExprNodeRegister:
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("name"),
- .value = INTEGER_OBJ(node->data.reg.name),
- };
- break;
- case kExprNodeComparison:
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("cmp_type"),
- .value = STRING_OBJ(cstr_to_string(eltkn_cmp_type_tab[node->data.cmp.type])),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ccs_strategy"),
- .value = STRING_OBJ(cstr_to_string(ccs_tab[node->data.cmp.ccs])),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("invert"),
- .value = BOOLEAN_OBJ(node->data.cmp.inv),
- };
- break;
- case kExprNodeFloat:
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("fvalue"),
- .value = FLOAT_OBJ(node->data.flt.value),
- };
- break;
- case kExprNodeInteger:
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ivalue"),
- .value = INTEGER_OBJ((Integer)(
- node->data.num.value > API_INTEGER_MAX
- ? API_INTEGER_MAX
- : (Integer)node->data.num.value)),
- };
- break;
- case kExprNodeAssignment: {
- const ExprAssignmentType asgn_type = node->data.ass.type;
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("augmentation"),
- .value = STRING_OBJ(asgn_type == kExprAsgnPlain
- ? (String)STRING_INIT
- : cstr_to_string(expr_asgn_type_tab[asgn_type])),
- };
- break;
- }
- case kExprNodeMissing:
- case kExprNodeOpMissing:
- case kExprNodeTernary:
- case kExprNodeTernaryValue:
- case kExprNodeSubscript:
- case kExprNodeListLiteral:
- case kExprNodeUnaryPlus:
- case kExprNodeBinaryPlus:
- case kExprNodeNested:
- case kExprNodeCall:
- case kExprNodeComplexIdentifier:
- case kExprNodeUnknownFigure:
- case kExprNodeLambda:
- case kExprNodeDictLiteral:
- case kExprNodeCurlyBracesIdentifier:
- case kExprNodeComma:
- case kExprNodeColon:
- case kExprNodeArrow:
- case kExprNodeConcat:
- case kExprNodeConcatOrSubscript:
- case kExprNodeOr:
- case kExprNodeAnd:
- case kExprNodeUnaryMinus:
- case kExprNodeBinaryMinus:
- case kExprNodeNot:
- case kExprNodeMultiplication:
- case kExprNodeDivision:
- case kExprNodeMod:
- break;
- }
- assert(cur_item.ret_node_p->data.dictionary.size
- == cur_item.ret_node_p->data.dictionary.capacity);
- xfree(*cur_item.node_p);
- *cur_item.node_p = NULL;
- }
- }
- }
- kvi_destroy(ast_conv_stack);
-
- assert(ret.size == ret.capacity);
- // Should be a no-op actually, leaving it in case non-nodes will need to be
- // freed later.
- viml_pexpr_free_ast(east);
- viml_parser_destroy(&pstate);
- return ret;
-}
-
-
/// Writes a message to vim output or error buffer. The string is split
/// and flushed after each newline. Incomplete lines are kept for writing
/// later.