aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/viml
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-04-11 01:09:36 +0300
committerZyX <kp-pav@yandex.ru>2017-04-11 01:09:36 +0300
commitf98a3d85ed2f34a62300097fd30b393a3b3be393 (patch)
tree41562adb208723f786454ae2ddfa0bb02521318d /src/nvim/viml
parent1751ec192d860f2591d18c4aad4248b5ab786cec (diff)
downloadrneovim-f98a3d85ed2f34a62300097fd30b393a3b3be393.tar.gz
rneovim-f98a3d85ed2f34a62300097fd30b393a3b3be393.tar.bz2
rneovim-f98a3d85ed2f34a62300097fd30b393a3b3be393.zip
lua: Move files from src/nvim/viml/executor to src/nvim/lua
Diffstat (limited to 'src/nvim/viml')
-rw-r--r--src/nvim/viml/executor/converter.c1194
-rw-r--r--src/nvim/viml/executor/converter.h15
-rw-r--r--src/nvim/viml/executor/executor.c576
-rw-r--r--src/nvim/viml/executor/executor.h25
-rw-r--r--src/nvim/viml/executor/vim.lua2
5 files changed, 0 insertions, 1812 deletions
diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c
deleted file mode 100644
index 425a38538d..0000000000
--- a/src/nvim/viml/executor/converter.c
+++ /dev/null
@@ -1,1194 +0,0 @@
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-#include <assert.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "nvim/api/private/defs.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/func_attr.h"
-#include "nvim/memory.h"
-#include "nvim/assert.h"
-// FIXME: vim.h is not actually needed, but otherwise it states MAXPATHL is
-// redefined
-#include "nvim/vim.h"
-#include "nvim/globals.h"
-#include "nvim/message.h"
-#include "nvim/eval/typval.h"
-#include "nvim/ascii.h"
-#include "nvim/macros.h"
-
-#include "nvim/lib/kvec.h"
-#include "nvim/eval/decode.h"
-
-#include "nvim/viml/executor/converter.h"
-#include "nvim/viml/executor/executor.h"
-
-/// Determine, which keys lua table contains
-typedef struct {
- size_t maxidx; ///< Maximum positive integral value found.
- size_t string_keys_num; ///< Number of string keys.
- bool has_string_with_nul; ///< True if there is string key with NUL byte.
- ObjectType type; ///< If has_type_key is true then attached value. Otherwise
- ///< either kObjectTypeNil, kObjectTypeDictionary or
- ///< kObjectTypeArray, depending on other properties.
- lua_Number val; ///< If has_val_key and val_type == LUA_TNUMBER: value.
- bool has_type_key; ///< True if type key is present.
-} LuaTableProps;
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "viml/executor/converter.c.generated.h"
-#endif
-
-#define TYPE_IDX_VALUE true
-#define VAL_IDX_VALUE false
-
-#define LUA_PUSH_STATIC_STRING(lstate, s) \
- lua_pushlstring(lstate, s, sizeof(s) - 1)
-
-static LuaTableProps nlua_traverse_table(lua_State *const lstate)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- size_t tsize = 0; // Total number of keys.
- int val_type = 0; // If has_val_key: lua type of the value.
- bool has_val_key = false; // True if val key was found,
- // @see nlua_push_val_idx().
- size_t other_keys_num = 0; // Number of keys that are not string, integral
- // or type keys.
- LuaTableProps ret;
- memset(&ret, 0, sizeof(ret));
- if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
- emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 2);
- ret.type = kObjectTypeNil;
- return ret;
- }
- lua_pushnil(lstate);
- while (lua_next(lstate, -2)) {
- switch (lua_type(lstate, -2)) {
- case LUA_TSTRING: {
- size_t len;
- const char *s = lua_tolstring(lstate, -2, &len);
- if (memchr(s, NUL, len) != NULL) {
- ret.has_string_with_nul = true;
- }
- ret.string_keys_num++;
- break;
- }
- case LUA_TNUMBER: {
- const lua_Number n = lua_tonumber(lstate, -2);
- if (n > (lua_Number)SIZE_MAX || n <= 0
- || ((lua_Number)((size_t)n)) != n) {
- other_keys_num++;
- } else {
- const size_t idx = (size_t)n;
- if (idx > ret.maxidx) {
- ret.maxidx = idx;
- }
- }
- break;
- }
- case LUA_TBOOLEAN: {
- const bool b = lua_toboolean(lstate, -2);
- if (b == TYPE_IDX_VALUE) {
- if (lua_type(lstate, -1) == LUA_TNUMBER) {
- lua_Number n = lua_tonumber(lstate, -1);
- if (n == (lua_Number)kObjectTypeFloat
- || n == (lua_Number)kObjectTypeArray
- || n == (lua_Number)kObjectTypeDictionary) {
- ret.has_type_key = true;
- ret.type = (ObjectType)n;
- } else {
- other_keys_num++;
- }
- } else {
- other_keys_num++;
- }
- } else {
- has_val_key = true;
- val_type = lua_type(lstate, -1);
- if (val_type == LUA_TNUMBER) {
- ret.val = lua_tonumber(lstate, -1);
- }
- }
- break;
- }
- default: {
- other_keys_num++;
- break;
- }
- }
- tsize++;
- lua_pop(lstate, 1);
- }
- if (ret.has_type_key) {
- if (ret.type == kObjectTypeFloat
- && (!has_val_key || val_type != LUA_TNUMBER)) {
- ret.type = kObjectTypeNil;
- } else if (ret.type == kObjectTypeArray) {
- // Determine what is the last number in a *sequence* of keys.
- // This condition makes sure that Neovim will not crash when it gets table
- // {[vim.type_idx]=vim.types.array, [SIZE_MAX]=1}: without it maxidx will
- // be SIZE_MAX, with this condition it should be zero and [SIZE_MAX] key
- // should be ignored.
- if (ret.maxidx != 0
- && ret.maxidx != (tsize
- - ret.has_type_key
- - other_keys_num
- - has_val_key
- - ret.string_keys_num)) {
- for (ret.maxidx = 0;; ret.maxidx++) {
- lua_rawgeti(lstate, -1, (int)ret.maxidx + 1);
- if (lua_isnil(lstate, -1)) {
- lua_pop(lstate, 1);
- break;
- }
- lua_pop(lstate, 1);
- }
- }
- }
- } else {
- if (tsize == 0
- || (tsize == ret.maxidx
- && other_keys_num == 0
- && ret.string_keys_num == 0)) {
- ret.type = kObjectTypeArray;
- } else if (ret.string_keys_num == tsize) {
- ret.type = kObjectTypeDictionary;
- } else {
- ret.type = kObjectTypeNil;
- }
- }
- return ret;
-}
-
-/// Helper structure for nlua_pop_typval
-typedef struct {
- typval_T *tv; ///< Location where conversion result is saved.
- bool container; ///< True if tv is a container.
- bool special; ///< If true then tv is a _VAL part of special dictionary
- ///< that represents mapping.
- int idx; ///< Container index (used to detect self-referencing structures).
-} TVPopStackItem;
-
-/// Convert lua object to VimL typval_T
-///
-/// Should pop exactly one value from lua stack.
-///
-/// @param lstate Lua state.
-/// @param[out] ret_tv Where to put the result.
-///
-/// @return `true` in case of success, `false` in case of failure. Error is
-/// reported automatically.
-bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
-{
- bool ret = true;
- const int initial_size = lua_gettop(lstate);
- kvec_t(TVPopStackItem) stack = KV_INITIAL_VALUE;
- kv_push(stack, ((TVPopStackItem) { ret_tv, false, false, 0 }));
- while (ret && kv_size(stack)) {
- if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
- emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 3);
- ret = false;
- break;
- }
- TVPopStackItem cur = kv_pop(stack);
- if (cur.container) {
- if (cur.special || cur.tv->v_type == VAR_DICT) {
- assert(cur.tv->v_type == (cur.special ? VAR_LIST : VAR_DICT));
- bool next_key_found = false;
- while (lua_next(lstate, -2)) {
- if (lua_type(lstate, -2) == LUA_TSTRING) {
- next_key_found = true;
- break;
- }
- lua_pop(lstate, 1);
- }
- if (next_key_found) {
- size_t len;
- const char *s = lua_tolstring(lstate, -2, &len);
- if (cur.special) {
- list_T *const kv_pair = tv_list_alloc();
- tv_list_append_list(cur.tv->vval.v_list, kv_pair);
- listitem_T *const key = tv_list_item_alloc();
- key->li_tv = decode_string(s, len, kTrue, false, false);
- tv_list_append(kv_pair, key);
- if (key->li_tv.v_type == VAR_UNKNOWN) {
- ret = false;
- tv_list_unref(kv_pair);
- continue;
- }
- listitem_T *const val = tv_list_item_alloc();
- tv_list_append(kv_pair, val);
- kv_push(stack, cur);
- cur = (TVPopStackItem) { &val->li_tv, false, false, 0 };
- } else {
- dictitem_T *const di = tv_dict_item_alloc_len(s, len);
- if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
- assert(false);
- }
- kv_push(stack, cur);
- cur = (TVPopStackItem) { &di->di_tv, false, false, 0 };
- }
- } else {
- lua_pop(lstate, 1);
- continue;
- }
- } else {
- assert(cur.tv->v_type == VAR_LIST);
- lua_rawgeti(lstate, -1, cur.tv->vval.v_list->lv_len + 1);
- if (lua_isnil(lstate, -1)) {
- lua_pop(lstate, 2);
- continue;
- }
- listitem_T *const li = tv_list_item_alloc();
- tv_list_append(cur.tv->vval.v_list, li);
- kv_push(stack, cur);
- cur = (TVPopStackItem) { &li->li_tv, false, false, 0 };
- }
- }
- assert(!cur.container);
- *cur.tv = (typval_T) {
- .v_type = VAR_NUMBER,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_number = 0 },
- };
- switch (lua_type(lstate, -1)) {
- case LUA_TNIL: {
- cur.tv->v_type = VAR_SPECIAL;
- cur.tv->vval.v_special = kSpecialVarNull;
- break;
- }
- case LUA_TBOOLEAN: {
- cur.tv->v_type = VAR_SPECIAL;
- cur.tv->vval.v_special = (lua_toboolean(lstate, -1)
- ? kSpecialVarTrue
- : kSpecialVarFalse);
- break;
- }
- case LUA_TSTRING: {
- size_t len;
- const char *s = lua_tolstring(lstate, -1, &len);
- *cur.tv = decode_string(s, len, kNone, true, false);
- if (cur.tv->v_type == VAR_UNKNOWN) {
- ret = false;
- }
- break;
- }
- case LUA_TNUMBER: {
- const lua_Number n = lua_tonumber(lstate, -1);
- if (n > (lua_Number)VARNUMBER_MAX || n < (lua_Number)VARNUMBER_MIN
- || ((lua_Number)((varnumber_T)n)) != n) {
- cur.tv->v_type = VAR_FLOAT;
- cur.tv->vval.v_float = (float_T)n;
- } else {
- cur.tv->v_type = VAR_NUMBER;
- cur.tv->vval.v_number = (varnumber_T)n;
- }
- break;
- }
- case LUA_TTABLE: {
- const LuaTableProps table_props = nlua_traverse_table(lstate);
-
- for (size_t i = 0; i < kv_size(stack); i++) {
- const TVPopStackItem item = kv_A(stack, i);
- if (item.container && lua_rawequal(lstate, -1, item.idx)) {
- tv_copy(item.tv, cur.tv);
- cur.container = false;
- goto nlua_pop_typval_table_processing_end;
- }
- }
-
- switch (table_props.type) {
- case kObjectTypeArray: {
- cur.tv->v_type = VAR_LIST;
- cur.tv->vval.v_list = tv_list_alloc();
- cur.tv->vval.v_list->lv_refcount++;
- if (table_props.maxidx != 0) {
- cur.container = true;
- cur.idx = lua_gettop(lstate);
- kv_push(stack, cur);
- }
- break;
- }
- case kObjectTypeDictionary: {
- if (table_props.string_keys_num == 0) {
- cur.tv->v_type = VAR_DICT;
- cur.tv->vval.v_dict = tv_dict_alloc();
- cur.tv->vval.v_dict->dv_refcount++;
- } else {
- cur.special = table_props.has_string_with_nul;
- if (table_props.has_string_with_nul) {
- decode_create_map_special_dict(cur.tv);
- assert(cur.tv->v_type = VAR_DICT);
- dictitem_T *const val_di = tv_dict_find(cur.tv->vval.v_dict,
- S_LEN("_VAL"));
- assert(val_di != NULL);
- cur.tv = &val_di->di_tv;
- assert(cur.tv->v_type == VAR_LIST);
- } else {
- cur.tv->v_type = VAR_DICT;
- cur.tv->vval.v_dict = tv_dict_alloc();
- cur.tv->vval.v_dict->dv_refcount++;
- }
- cur.container = true;
- cur.idx = lua_gettop(lstate);
- kv_push(stack, cur);
- lua_pushnil(lstate);
- }
- break;
- }
- case kObjectTypeFloat: {
- cur.tv->v_type = VAR_FLOAT;
- cur.tv->vval.v_float = (float_T)table_props.val;
- break;
- }
- case kObjectTypeNil: {
- EMSG(_("E5100: Cannot convert given lua table: table "
- "should either have a sequence of positive integer keys "
- "or contain only string keys"));
- ret = false;
- break;
- }
- default: {
- assert(false);
- }
- }
-nlua_pop_typval_table_processing_end:
- break;
- }
- default: {
- EMSG(_("E5101: Cannot convert given lua type"));
- ret = false;
- break;
- }
- }
- if (!cur.container) {
- lua_pop(lstate, 1);
- }
- }
- kv_destroy(stack);
- if (!ret) {
- tv_clear(ret_tv);
- *ret_tv = (typval_T) {
- .v_type = VAR_NUMBER,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_number = 0 },
- };
- lua_pop(lstate, lua_gettop(lstate) - initial_size + 1);
- }
- assert(lua_gettop(lstate) == initial_size - 1);
- return ret;
-}
-
-#define TYPVAL_ENCODE_ALLOW_SPECIALS true
-
-#define TYPVAL_ENCODE_CONV_NIL(tv) \
- lua_pushnil(lstate)
-
-#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- lua_pushboolean(lstate, (bool)(num))
-
-#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- lua_pushnumber(lstate, (lua_Number)(num))
-
-#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
-
-#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- TYPVAL_ENCODE_CONV_NUMBER(tv, flt)
-
-#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
- lua_pushlstring(lstate, (const char *)(str), (len))
-
-#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
-
-#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \
- TYPVAL_ENCODE_CONV_NIL()
-
-#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- do { \
- TYPVAL_ENCODE_CONV_NIL(tv); \
- goto typval_encode_stop_converting_one_item; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
-#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
-#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
-
-#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- lua_createtable(lstate, 0, 0)
-
-#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary)
-
-#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
- do { \
- if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
- emsgf(_("E5102: Lua failed to grow stack to %i"), \
- lua_gettop(lstate) + 3); \
- return false; \
- } \
- lua_createtable(lstate, (int)(len), 0); \
- lua_pushnumber(lstate, 1); \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
-
-#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
- do { \
- lua_Number idx = lua_tonumber(lstate, -2); \
- lua_rawset(lstate, -3); \
- lua_pushnumber(lstate, idx + 1); \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
- lua_rawset(lstate, -3)
-
-#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
- do { \
- if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
- emsgf(_("E5102: Lua failed to grow stack to %i"), \
- lua_gettop(lstate) + 3); \
- return false; \
- } \
- lua_createtable(lstate, 0, (int)(len)); \
- } while (0)
-
-#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, kv_pair)
-
-#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
-
-#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
-
-#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
- lua_rawset(lstate, -3)
-
-#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
- TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
-
-#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- do { \
- for (size_t backref = kv_size(*mpstack); backref; backref--) { \
- const MPConvStackVal mpval = kv_A(*mpstack, backref - 1); \
- if (mpval.type == conv_type) { \
- if (conv_type == kMPConvDict \
- ? (void *)mpval.data.d.dict == (void *)(val) \
- : (void *)mpval.data.l.list == (void *)(val)) { \
- lua_pushvalue(lstate, \
- -((int)((kv_size(*mpstack) - backref + 1) * 2))); \
- break; \
- } \
- } \
- } \
- } while (0)
-
-#define TYPVAL_ENCODE_SCOPE static
-#define TYPVAL_ENCODE_NAME lua
-#define TYPVAL_ENCODE_FIRST_ARG_TYPE lua_State *const
-#define TYPVAL_ENCODE_FIRST_ARG_NAME lstate
-#include "nvim/eval/typval_encode.c.h"
-#undef TYPVAL_ENCODE_SCOPE
-#undef TYPVAL_ENCODE_NAME
-#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
-#undef TYPVAL_ENCODE_FIRST_ARG_NAME
-
-#undef TYPVAL_ENCODE_CONV_STRING
-#undef TYPVAL_ENCODE_CONV_STR_STRING
-#undef TYPVAL_ENCODE_CONV_EXT_STRING
-#undef TYPVAL_ENCODE_CONV_NUMBER
-#undef TYPVAL_ENCODE_CONV_FLOAT
-#undef TYPVAL_ENCODE_CONV_FUNC_START
-#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
-#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
-#undef TYPVAL_ENCODE_CONV_FUNC_END
-#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
-#undef TYPVAL_ENCODE_CONV_LIST_START
-#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
-#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
-#undef TYPVAL_ENCODE_CONV_NIL
-#undef TYPVAL_ENCODE_CONV_BOOL
-#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
-#undef TYPVAL_ENCODE_CONV_DICT_START
-#undef TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START
-#undef TYPVAL_ENCODE_CONV_DICT_END
-#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
-#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
-#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
-#undef TYPVAL_ENCODE_CONV_LIST_END
-#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
-#undef TYPVAL_ENCODE_CONV_RECURSE
-#undef TYPVAL_ENCODE_ALLOW_SPECIALS
-
-/// Convert VimL typval_T to lua value
-///
-/// Should leave single value in lua stack. May only fail if lua failed to grow
-/// stack.
-///
-/// @param lstate Lua interpreter state.
-/// @param[in] tv typval_T to convert.
-///
-/// @return true in case of success, false otherwise.
-bool nlua_push_typval(lua_State *lstate, typval_T *const tv)
-{
- const int initial_size = lua_gettop(lstate);
- if (!lua_checkstack(lstate, initial_size + 2)) {
- emsgf(_("E1502: Lua failed to grow stack to %i"), initial_size + 4);
- return false;
- }
- if (encode_vim_to_lua(lstate, tv, "nlua_push_typval argument") == FAIL) {
- return false;
- }
- assert(lua_gettop(lstate) == initial_size + 1);
- return true;
-}
-
-#define NLUA_PUSH_HANDLE(lstate, type, idx) \
- do { \
- lua_pushnumber(lstate, (lua_Number)(idx)); \
- } while (0)
-
-#define NLUA_POP_HANDLE(lstate, type, stack_idx, idx) \
- do { \
- idx = (type)lua_tonumber(lstate, stack_idx); \
- } while (0)
-
-/// Push value which is a type index
-///
-/// Used for all “typed” tables: i.e. for all tables which represent VimL
-/// values.
-static inline void nlua_push_type_idx(lua_State *lstate)
- FUNC_ATTR_NONNULL_ALL
-{
- lua_pushboolean(lstate, TYPE_IDX_VALUE);
-}
-
-/// Push value which is a value index
-///
-/// Used for tables which represent scalar values, like float value.
-static inline void nlua_push_val_idx(lua_State *lstate)
- FUNC_ATTR_NONNULL_ALL
-{
- lua_pushboolean(lstate, VAL_IDX_VALUE);
-}
-
-/// Push type
-///
-/// Type is a value in vim.types table.
-///
-/// @param[out] lstate Lua state.
-/// @param[in] type Type to push.
-static inline void nlua_push_type(lua_State *lstate, ObjectType type)
- FUNC_ATTR_NONNULL_ALL
-{
- lua_pushnumber(lstate, (lua_Number)type);
-}
-
-/// Create lua table which has an entry that determines its VimL type
-///
-/// @param[out] lstate Lua state.
-/// @param[in] narr Number of “array” entries to be populated later.
-/// @param[in] nrec Number of “dictionary” entries to be populated later.
-/// @param[in] type Type of the table.
-static inline void nlua_create_typed_table(lua_State *lstate,
- const size_t narr,
- const size_t nrec,
- const ObjectType type)
- FUNC_ATTR_NONNULL_ALL
-{
- lua_createtable(lstate, (int)narr, (int)(1 + nrec));
- nlua_push_type_idx(lstate);
- nlua_push_type(lstate, type);
- lua_rawset(lstate, -3);
-}
-
-
-/// Convert given String to lua string
-///
-/// Leaves converted string on top of the stack.
-void nlua_push_String(lua_State *lstate, const String s)
- FUNC_ATTR_NONNULL_ALL
-{
- lua_pushlstring(lstate, s.data, s.size);
-}
-
-/// Convert given Integer to lua number
-///
-/// Leaves converted number on top of the stack.
-void nlua_push_Integer(lua_State *lstate, const Integer n)
- FUNC_ATTR_NONNULL_ALL
-{
- lua_pushnumber(lstate, (lua_Number)n);
-}
-
-/// Convert given Float to lua table
-///
-/// Leaves converted table on top of the stack.
-void nlua_push_Float(lua_State *lstate, const Float f)
- FUNC_ATTR_NONNULL_ALL
-{
- nlua_create_typed_table(lstate, 0, 1, kObjectTypeFloat);
- nlua_push_val_idx(lstate);
- lua_pushnumber(lstate, (lua_Number)f);
- lua_rawset(lstate, -3);
-}
-
-/// Convert given Float to lua boolean
-///
-/// Leaves converted value on top of the stack.
-void nlua_push_Boolean(lua_State *lstate, const Boolean b)
- FUNC_ATTR_NONNULL_ALL
-{
- lua_pushboolean(lstate, b);
-}
-
-/// Convert given Dictionary to lua table
-///
-/// Leaves converted table on top of the stack.
-void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict)
- FUNC_ATTR_NONNULL_ALL
-{
- if (dict.size == 0) {
- nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary);
- } else {
- lua_createtable(lstate, 0, (int)dict.size);
- }
- for (size_t i = 0; i < dict.size; i++) {
- nlua_push_String(lstate, dict.items[i].key);
- nlua_push_Object(lstate, dict.items[i].value);
- lua_rawset(lstate, -3);
- }
-}
-
-/// Convert given Array to lua table
-///
-/// Leaves converted table on top of the stack.
-void nlua_push_Array(lua_State *lstate, const Array array)
- FUNC_ATTR_NONNULL_ALL
-{
- lua_createtable(lstate, (int)array.size, 0);
- for (size_t i = 0; i < array.size; i++) {
- nlua_push_Object(lstate, array.items[i]);
- lua_rawseti(lstate, -2, (int)i + 1);
- }
-}
-
-#define GENERATE_INDEX_FUNCTION(type) \
-void nlua_push_##type(lua_State *lstate, const type item) \
- FUNC_ATTR_NONNULL_ALL \
-{ \
- NLUA_PUSH_HANDLE(lstate, type, item); \
-}
-
-GENERATE_INDEX_FUNCTION(Buffer)
-GENERATE_INDEX_FUNCTION(Window)
-GENERATE_INDEX_FUNCTION(Tabpage)
-
-#undef GENERATE_INDEX_FUNCTION
-
-/// Convert given Object to lua value
-///
-/// Leaves converted value on top of the stack.
-void nlua_push_Object(lua_State *lstate, const Object obj)
- FUNC_ATTR_NONNULL_ALL
-{
- switch (obj.type) {
- case kObjectTypeNil: {
- lua_pushnil(lstate);
- break;
- }
-#define ADD_TYPE(type, data_key) \
- case kObjectType##type: { \
- nlua_push_##type(lstate, obj.data.data_key); \
- break; \
- }
- ADD_TYPE(Boolean, boolean)
- ADD_TYPE(Integer, integer)
- ADD_TYPE(Float, floating)
- ADD_TYPE(String, string)
- ADD_TYPE(Array, array)
- ADD_TYPE(Dictionary, dictionary)
-#undef ADD_TYPE
-#define ADD_REMOTE_TYPE(type) \
- case kObjectType##type: { \
- nlua_push_##type(lstate, (type)obj.data.integer); \
- break; \
- }
- ADD_REMOTE_TYPE(Buffer)
- ADD_REMOTE_TYPE(Window)
- ADD_REMOTE_TYPE(Tabpage)
-#undef ADD_REMOTE_TYPE
- }
-}
-
-
-/// Convert lua value to string
-///
-/// Always pops one value from the stack.
-String nlua_pop_String(lua_State *lstate, Error *err)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (lua_type(lstate, -1) != LUA_TSTRING) {
- lua_pop(lstate, 1);
- api_set_error(err, Validation, "Expected lua string");
- return (String) { .size = 0, .data = NULL };
- }
- String ret;
-
- ret.data = (char *)lua_tolstring(lstate, -1, &(ret.size));
- assert(ret.data != NULL);
- ret.data = xmemdupz(ret.data, ret.size);
- lua_pop(lstate, 1);
-
- return ret;
-}
-
-/// Convert lua value to integer
-///
-/// Always pops one value from the stack.
-Integer nlua_pop_Integer(lua_State *lstate, Error *err)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (lua_type(lstate, -1) != LUA_TNUMBER) {
- lua_pop(lstate, 1);
- api_set_error(err, Validation, "Expected lua number");
- return 0;
- }
- const lua_Number n = lua_tonumber(lstate, -1);
- lua_pop(lstate, 1);
- if (n > (lua_Number)API_INTEGER_MAX || n < (lua_Number)API_INTEGER_MIN
- || ((lua_Number)((Integer)n)) != n) {
- api_set_error(err, Exception, "Number is not integral");
- return 0;
- }
- return (Integer)n;
-}
-
-/// Convert lua value to boolean
-///
-/// Always pops one value from the stack.
-Boolean nlua_pop_Boolean(lua_State *lstate, Error *err)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- const Boolean ret = lua_toboolean(lstate, -1);
- lua_pop(lstate, 1);
- return ret;
-}
-
-/// Check whether typed table on top of the stack has given type
-///
-/// @param[in] lstate Lua state.
-/// @param[out] err Location where error will be saved. May be NULL.
-/// @param[in] type Type to check.
-///
-/// @return @see nlua_traverse_table().
-static inline LuaTableProps nlua_check_type(lua_State *const lstate,
- Error *const err,
- const ObjectType type)
- FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (lua_type(lstate, -1) != LUA_TTABLE) {
- if (err) {
- api_set_error(err, Validation, "Expected lua table");
- }
- return (LuaTableProps) { .type = kObjectTypeNil };
- }
- LuaTableProps table_props = nlua_traverse_table(lstate);
-
- if (type == kObjectTypeDictionary && table_props.type == kObjectTypeArray
- && table_props.maxidx == 0 && !table_props.has_type_key) {
- table_props.type = kObjectTypeDictionary;
- }
-
- if (table_props.type != type) {
- if (err) {
- api_set_error(err, Validation, "Unexpected type");
- }
- }
-
- return table_props;
-}
-
-/// Convert lua table to float
-///
-/// Always pops one value from the stack.
-Float nlua_pop_Float(lua_State *lstate, Error *err)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (lua_type(lstate, -1) == LUA_TNUMBER) {
- const Float ret = (Float)lua_tonumber(lstate, -1);
- lua_pop(lstate, 1);
- return ret;
- }
-
- const LuaTableProps table_props = nlua_check_type(lstate, err,
- kObjectTypeFloat);
- lua_pop(lstate, 1);
- if (table_props.type != kObjectTypeFloat) {
- return 0;
- } else {
- return (Float)table_props.val;
- }
-}
-
-/// Convert lua table to array without determining whether it is array
-///
-/// @param lstate Lua state.
-/// @param[in] table_props nlua_traverse_table() output.
-/// @param[out] err Location where error will be saved.
-static Array nlua_pop_Array_unchecked(lua_State *const lstate,
- const LuaTableProps table_props,
- Error *const err)
-{
- Array ret = { .size = table_props.maxidx, .items = NULL };
-
- if (ret.size == 0) {
- lua_pop(lstate, 1);
- return ret;
- }
-
- ret.items = xcalloc(ret.size, sizeof(*ret.items));
- for (size_t i = 1; i <= ret.size; i++) {
- Object val;
-
- lua_rawgeti(lstate, -1, (int)i);
-
- val = nlua_pop_Object(lstate, err);
- if (err->set) {
- ret.size = i - 1;
- lua_pop(lstate, 1);
- api_free_array(ret);
- return (Array) { .size = 0, .items = NULL };
- }
- ret.items[i - 1] = val;
- }
- lua_pop(lstate, 1);
-
- return ret;
-}
-
-/// Convert lua table to array
-///
-/// Always pops one value from the stack.
-Array nlua_pop_Array(lua_State *lstate, Error *err)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- const LuaTableProps table_props = nlua_check_type(lstate, err,
- kObjectTypeArray);
- if (table_props.type != kObjectTypeArray) {
- return (Array) { .size = 0, .items = NULL };
- }
- return nlua_pop_Array_unchecked(lstate, table_props, err);
-}
-
-/// Convert lua table to dictionary
-///
-/// Always pops one value from the stack. Does not check whether whether topmost
-/// value on the stack is a table.
-///
-/// @param lstate Lua interpreter state.
-/// @param[in] table_props nlua_traverse_table() output.
-/// @param[out] err Location where error will be saved.
-static Dictionary nlua_pop_Dictionary_unchecked(lua_State *lstate,
- const LuaTableProps table_props,
- Error *err)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- Dictionary ret = { .size = table_props.string_keys_num, .items = NULL };
-
- if (ret.size == 0) {
- lua_pop(lstate, 1);
- return ret;
- }
- ret.items = xcalloc(ret.size, sizeof(*ret.items));
-
- lua_pushnil(lstate);
- for (size_t i = 0; lua_next(lstate, -2) && i < ret.size;) {
- // stack: dict, key, value
-
- if (lua_type(lstate, -2) == LUA_TSTRING) {
- lua_pushvalue(lstate, -2);
- // stack: dict, key, value, key
-
- ret.items[i].key = nlua_pop_String(lstate, err);
- // stack: dict, key, value
-
- if (!err->set) {
- ret.items[i].value = nlua_pop_Object(lstate, err);
- // stack: dict, key
- } else {
- lua_pop(lstate, 1);
- // stack: dict, key
- }
-
- if (err->set) {
- ret.size = i;
- api_free_dictionary(ret);
- lua_pop(lstate, 2);
- // stack:
- return (Dictionary) { .size = 0, .items = NULL };
- }
- i++;
- } else {
- lua_pop(lstate, 1);
- // stack: dict, key
- }
- }
- lua_pop(lstate, 1);
-
- return ret;
-}
-
-/// Convert lua table to dictionary
-///
-/// Always pops one value from the stack.
-Dictionary nlua_pop_Dictionary(lua_State *lstate, Error *err)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- const LuaTableProps table_props = nlua_check_type(lstate, err,
- kObjectTypeDictionary);
- if (table_props.type != kObjectTypeDictionary) {
- lua_pop(lstate, 1);
- return (Dictionary) { .size = 0, .items = NULL };
- }
-
- return nlua_pop_Dictionary_unchecked(lstate, table_props, err);
-}
-
-/// Helper structure for nlua_pop_Object
-typedef struct {
- Object *obj; ///< Location where conversion result is saved.
- bool container; ///< True if tv is a container.
-} ObjPopStackItem;
-
-/// Convert lua table to object
-///
-/// Always pops one value from the stack.
-Object nlua_pop_Object(lua_State *const lstate, Error *const err)
-{
- Object ret = NIL;
- const int initial_size = lua_gettop(lstate);
- kvec_t(ObjPopStackItem) stack = KV_INITIAL_VALUE;
- kv_push(stack, ((ObjPopStackItem) { &ret, false }));
- while (!err->set && kv_size(stack)) {
- if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
- api_set_error(err, Exception, "Lua failed to grow stack");
- break;
- }
- ObjPopStackItem cur = kv_pop(stack);
- if (cur.container) {
- if (cur.obj->type == kObjectTypeDictionary) {
- // stack: …, dict, key
- if (cur.obj->data.dictionary.size
- == cur.obj->data.dictionary.capacity) {
- lua_pop(lstate, 2);
- continue;
- }
- bool next_key_found = false;
- while (lua_next(lstate, -2)) {
- // stack: …, dict, new key, val
- if (lua_type(lstate, -2) == LUA_TSTRING) {
- next_key_found = true;
- break;
- }
- lua_pop(lstate, 1);
- // stack: …, dict, new key
- }
- if (next_key_found) {
- // stack: …, dict, new key, val
- size_t len;
- const char *s = lua_tolstring(lstate, -2, &len);
- const size_t idx = cur.obj->data.dictionary.size++;
- cur.obj->data.dictionary.items[idx].key = (String) {
- .data = xmemdupz(s, len),
- .size = len,
- };
- kv_push(stack, cur);
- cur = (ObjPopStackItem) {
- .obj = &cur.obj->data.dictionary.items[idx].value,
- .container = false,
- };
- } else {
- // stack: …, dict
- lua_pop(lstate, 1);
- // stack: …
- continue;
- }
- } else {
- if (cur.obj->data.array.size == cur.obj->data.array.capacity) {
- lua_pop(lstate, 1);
- continue;
- }
- const size_t idx = cur.obj->data.array.size++;
- lua_rawgeti(lstate, -1, (int)idx + 1);
- if (lua_isnil(lstate, -1)) {
- lua_pop(lstate, 2);
- continue;
- }
- kv_push(stack, cur);
- cur = (ObjPopStackItem) {
- .obj = &cur.obj->data.array.items[idx],
- .container = false,
- };
- }
- }
- assert(!cur.container);
- *cur.obj = NIL;
- switch (lua_type(lstate, -1)) {
- case LUA_TNIL: {
- break;
- }
- case LUA_TBOOLEAN: {
- *cur.obj = BOOLEAN_OBJ(lua_toboolean(lstate, -1));
- break;
- }
- case LUA_TSTRING: {
- size_t len;
- const char *s = lua_tolstring(lstate, -1, &len);
- *cur.obj = STRING_OBJ(((String) {
- .data = xmemdupz(s, len),
- .size = len,
- }));
- break;
- }
- case LUA_TNUMBER: {
- const lua_Number n = lua_tonumber(lstate, -1);
- if (n > (lua_Number)API_INTEGER_MAX || n < (lua_Number)API_INTEGER_MIN
- || ((lua_Number)((Integer)n)) != n) {
- *cur.obj = FLOAT_OBJ((Float)n);
- } else {
- *cur.obj = INTEGER_OBJ((Integer)n);
- }
- break;
- }
- case LUA_TTABLE: {
- const LuaTableProps table_props = nlua_traverse_table(lstate);
-
- switch (table_props.type) {
- case kObjectTypeArray: {
- *cur.obj = ARRAY_OBJ(((Array) {
- .items = NULL,
- .size = 0,
- .capacity = 0,
- }));
- if (table_props.maxidx != 0) {
- cur.obj->data.array.items =
- xcalloc(table_props.maxidx,
- sizeof(cur.obj->data.array.items[0]));
- cur.obj->data.array.capacity = table_props.maxidx;
- cur.container = true;
- kv_push(stack, cur);
- }
- break;
- }
- case kObjectTypeDictionary: {
- *cur.obj = DICTIONARY_OBJ(((Dictionary) {
- .items = NULL,
- .size = 0,
- .capacity = 0,
- }));
- if (table_props.string_keys_num != 0) {
- cur.obj->data.dictionary.items =
- xcalloc(table_props.string_keys_num,
- sizeof(cur.obj->data.dictionary.items[0]));
- cur.obj->data.dictionary.capacity = table_props.string_keys_num;
- cur.container = true;
- kv_push(stack, cur);
- lua_pushnil(lstate);
- }
- break;
- }
- case kObjectTypeFloat: {
- *cur.obj = FLOAT_OBJ((Float)table_props.val);
- break;
- }
- case kObjectTypeNil: {
- api_set_error(err, Validation, "Cannot convert given lua table");
- break;
- }
- default: {
- assert(false);
- }
- }
- break;
- }
- default: {
- api_set_error(err, Validation, "Cannot convert given lua type");
- break;
- }
- }
- if (!cur.container) {
- lua_pop(lstate, 1);
- }
- }
- kv_destroy(stack);
- if (err->set) {
- api_free_object(ret);
- ret = NIL;
- lua_pop(lstate, lua_gettop(lstate) - initial_size + 1);
- }
- assert(lua_gettop(lstate) == initial_size - 1);
- return ret;
-}
-
-#define GENERATE_INDEX_FUNCTION(type) \
-type nlua_pop_##type(lua_State *lstate, Error *err) \
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \
-{ \
- type ret; \
- NLUA_POP_HANDLE(lstate, type, -1, ret); \
- lua_pop(lstate, 1); \
- return ret; \
-}
-
-GENERATE_INDEX_FUNCTION(Buffer)
-GENERATE_INDEX_FUNCTION(Window)
-GENERATE_INDEX_FUNCTION(Tabpage)
-
-#undef GENERATE_INDEX_FUNCTION
-
-/// Record some auxilary values in vim module
-///
-/// Assumes that module table is on top of the stack.
-///
-/// Recorded values:
-///
-/// `vim.type_idx`: @see nlua_push_type_idx()
-/// `vim.val_idx`: @see nlua_push_val_idx()
-/// `vim.types`: table mapping possible values of `vim.type_idx` to string
-/// names (i.e. `array`, `float`, `dictionary`) and back.
-void nlua_init_types(lua_State *const lstate)
-{
- LUA_PUSH_STATIC_STRING(lstate, "type_idx");
- nlua_push_type_idx(lstate);
- lua_rawset(lstate, -3);
-
- LUA_PUSH_STATIC_STRING(lstate, "val_idx");
- nlua_push_val_idx(lstate);
- lua_rawset(lstate, -3);
-
- LUA_PUSH_STATIC_STRING(lstate, "types");
- lua_createtable(lstate, 0, 3);
-
- LUA_PUSH_STATIC_STRING(lstate, "float");
- lua_pushnumber(lstate, (lua_Number)kObjectTypeFloat);
- lua_rawset(lstate, -3);
- lua_pushnumber(lstate, (lua_Number)kObjectTypeFloat);
- LUA_PUSH_STATIC_STRING(lstate, "float");
- lua_rawset(lstate, -3);
-
- LUA_PUSH_STATIC_STRING(lstate, "array");
- lua_pushnumber(lstate, (lua_Number)kObjectTypeArray);
- lua_rawset(lstate, -3);
- lua_pushnumber(lstate, (lua_Number)kObjectTypeArray);
- LUA_PUSH_STATIC_STRING(lstate, "array");
- lua_rawset(lstate, -3);
-
- LUA_PUSH_STATIC_STRING(lstate, "dictionary");
- lua_pushnumber(lstate, (lua_Number)kObjectTypeDictionary);
- lua_rawset(lstate, -3);
- lua_pushnumber(lstate, (lua_Number)kObjectTypeDictionary);
- LUA_PUSH_STATIC_STRING(lstate, "dictionary");
- lua_rawset(lstate, -3);
-
- lua_rawset(lstate, -3);
-}
diff --git a/src/nvim/viml/executor/converter.h b/src/nvim/viml/executor/converter.h
deleted file mode 100644
index dbbaaebf6b..0000000000
--- a/src/nvim/viml/executor/converter.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef NVIM_VIML_EXECUTOR_CONVERTER_H
-#define NVIM_VIML_EXECUTOR_CONVERTER_H
-
-#include <lua.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "nvim/api/private/defs.h"
-#include "nvim/func_attr.h"
-#include "nvim/eval.h"
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "viml/executor/converter.h.generated.h"
-#endif
-#endif // NVIM_VIML_EXECUTOR_CONVERTER_H
diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c
deleted file mode 100644
index 826460772e..0000000000
--- a/src/nvim/viml/executor/executor.c
+++ /dev/null
@@ -1,576 +0,0 @@
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-
-#include "nvim/misc1.h"
-#include "nvim/getchar.h"
-#include "nvim/garray.h"
-#include "nvim/func_attr.h"
-#include "nvim/api/private/defs.h"
-#include "nvim/api/private/helpers.h"
-#include "nvim/api/vim.h"
-#include "nvim/vim.h"
-#include "nvim/ex_getln.h"
-#include "nvim/message.h"
-#include "nvim/memline.h"
-#include "nvim/buffer_defs.h"
-#include "nvim/macros.h"
-#include "nvim/screen.h"
-#include "nvim/cursor.h"
-#include "nvim/undo.h"
-#include "nvim/ascii.h"
-
-#include "nvim/viml/executor/executor.h"
-#include "nvim/viml/executor/converter.h"
-
-typedef struct {
- Error err;
- String lua_err_str;
-} LuaError;
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "viml/executor/vim_module.generated.h"
-# include "viml/executor/executor.c.generated.h"
-#endif
-
-/// Name of the run code for use in messages
-#define NLUA_EVAL_NAME "<VimL compiled string>"
-
-/// Call C function which does not expect any arguments
-///
-/// @param function Called function
-/// @param numret Number of returned arguments
-#define NLUA_CALL_C_FUNCTION_0(lstate, function, numret) \
- do { \
- lua_pushcfunction(lstate, &function); \
- lua_call(lstate, 0, numret); \
- } while (0)
-/// Call C function which expects one argument
-///
-/// @param function Called function
-/// @param numret Number of returned arguments
-/// @param a… Supplied argument (should be a void* pointer)
-#define NLUA_CALL_C_FUNCTION_1(lstate, function, numret, a1) \
- do { \
- lua_pushcfunction(lstate, &function); \
- lua_pushlightuserdata(lstate, a1); \
- lua_call(lstate, 1, numret); \
- } while (0)
-/// Call C function which expects two arguments
-///
-/// @param function Called function
-/// @param numret Number of returned arguments
-/// @param a… Supplied argument (should be a void* pointer)
-#define NLUA_CALL_C_FUNCTION_2(lstate, function, numret, a1, a2) \
- do { \
- lua_pushcfunction(lstate, &function); \
- lua_pushlightuserdata(lstate, a1); \
- lua_pushlightuserdata(lstate, a2); \
- lua_call(lstate, 2, numret); \
- } while (0)
-/// Call C function which expects three arguments
-///
-/// @param function Called function
-/// @param numret Number of returned arguments
-/// @param a… Supplied argument (should be a void* pointer)
-#define NLUA_CALL_C_FUNCTION_3(lstate, function, numret, a1, a2, a3) \
- do { \
- lua_pushcfunction(lstate, &function); \
- lua_pushlightuserdata(lstate, a1); \
- lua_pushlightuserdata(lstate, a2); \
- lua_pushlightuserdata(lstate, a3); \
- lua_call(lstate, 3, numret); \
- } while (0)
-/// Call C function which expects five arguments
-///
-/// @param function Called function
-/// @param numret Number of returned arguments
-/// @param a… Supplied argument (should be a void* pointer)
-#define NLUA_CALL_C_FUNCTION_4(lstate, function, numret, a1, a2, a3, a4) \
- do { \
- lua_pushcfunction(lstate, &function); \
- lua_pushlightuserdata(lstate, a1); \
- lua_pushlightuserdata(lstate, a2); \
- lua_pushlightuserdata(lstate, a3); \
- lua_pushlightuserdata(lstate, a4); \
- lua_call(lstate, 4, numret); \
- } while (0)
-
-/// Convert lua error into a Vim error message
-///
-/// @param lstate Lua interpreter state.
-/// @param[in] msg Message base, must contain one `%s`.
-static void nlua_error(lua_State *const lstate, const char *const msg)
- FUNC_ATTR_NONNULL_ALL
-{
- size_t len;
- const char *const str = lua_tolstring(lstate, -1, &len);
-
- emsgf(msg, (int)len, str);
-
- lua_pop(lstate, 1);
-}
-
-/// Compare two strings, ignoring case
-///
-/// Expects two values on the stack: compared strings. Returns one of the
-/// following numbers: 0, -1 or 1.
-///
-/// Does no error handling: never call it with non-string or with some arguments
-/// omitted.
-static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
-{
- const char *s1 = luaL_checklstring(lstate, 1, NULL);
- const char *s2 = luaL_checklstring(lstate, 2, NULL);
- const int ret = STRICMP(s1, s2);
- lua_pop(lstate, 2);
- lua_pushnumber(lstate, (lua_Number)((ret > 0) - (ret < 0)));
- return 1;
-}
-
-/// Evaluate lua string
-///
-/// Expects two values on the stack: string to evaluate, pointer to the
-/// location where result is saved. Always returns nothing (from the lua point
-/// of view).
-static int nlua_exec_lua_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
-{
- const String *const str = (const String *)lua_touserdata(lstate, 1);
- typval_T *const ret_tv = (typval_T *)lua_touserdata(lstate, 2);
- lua_pop(lstate, 2);
-
- if (luaL_loadbuffer(lstate, str->data, str->size, NLUA_EVAL_NAME)) {
- nlua_error(lstate, _("E5104: Error while creating lua chunk: %.*s"));
- return 0;
- }
- if (lua_pcall(lstate, 0, 1, 0)) {
- nlua_error(lstate, _("E5105: Error while calling lua chunk: %.*s"));
- return 0;
- }
- if (!nlua_pop_typval(lstate, ret_tv)) {
- return 0;
- }
- return 0;
-}
-
-/// Evaluate lua string for each line in range
-///
-/// Expects two values on the stack: string to evaluate and pointer to integer
-/// array with line range. Always returns nothing (from the lua point of view).
-static int nlua_exec_luado_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
-{
- const String *const str = (const String *)lua_touserdata(lstate, 1);
- const linenr_T *const range = (const linenr_T *)lua_touserdata(lstate, 2);
- lua_pop(lstate, 2);
-
-#define DOSTART "return function(line, linenr) "
-#define DOEND " end"
- const size_t lcmd_len = (str->size
- + (sizeof(DOSTART) - 1)
- + (sizeof(DOEND) - 1));
- char *lcmd;
- if (lcmd_len < IOSIZE) {
- lcmd = (char *)IObuff;
- } else {
- lcmd = xmalloc(lcmd_len + 1);
- }
- memcpy(lcmd, DOSTART, sizeof(DOSTART) - 1);
- memcpy(lcmd + sizeof(DOSTART) - 1, str->data, str->size);
- memcpy(lcmd + sizeof(DOSTART) - 1 + str->size, DOEND, sizeof(DOEND) - 1);
-#undef DOSTART
-#undef DOEND
-
- if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
- nlua_error(lstate, _("E5109: Error while creating lua chunk: %.*s"));
- if (lcmd_len >= IOSIZE) {
- xfree(lcmd);
- }
- return 0;
- }
- if (lcmd_len >= IOSIZE) {
- xfree(lcmd);
- }
- if (lua_pcall(lstate, 0, 1, 0)) {
- nlua_error(lstate, _("E5110: Error while creating lua function: %.*s"));
- return 0;
- }
- for (linenr_T l = range[0]; l <= range[1]; l++) {
- if (l > curbuf->b_ml.ml_line_count) {
- break;
- }
- lua_pushvalue(lstate, -1);
- lua_pushstring(lstate, (const char *)ml_get_buf(curbuf, l, false));
- lua_pushnumber(lstate, (lua_Number)l);
- if (lua_pcall(lstate, 2, 1, 0)) {
- nlua_error(lstate, _("E5111: Error while calling lua function: %.*s"));
- break;
- }
- if (lua_isstring(lstate, -1)) {
- size_t new_line_len;
- const char *const new_line = lua_tolstring(lstate, -1, &new_line_len);
- char *const new_line_transformed = xmemdupz(new_line, new_line_len);
- for (size_t i = 0; i < new_line_len; i++) {
- if (new_line_transformed[i] == NUL) {
- new_line_transformed[i] = '\n';
- }
- }
- ml_replace(l, (char_u *)new_line_transformed, false);
- changed_bytes(l, 0);
- }
- lua_pop(lstate, 1);
- }
- lua_pop(lstate, 1);
- check_cursor();
- update_screen(NOT_VALID);
- return 0;
-}
-
-/// Evaluate lua file
-///
-/// Expects one value on the stack: file to evaluate. Always returns nothing
-/// (from the lua point of view).
-static int nlua_exec_lua_file(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
-{
- const char *const filename = (const char *)lua_touserdata(lstate, 1);
- lua_pop(lstate, 1);
-
- if (luaL_loadfile(lstate, filename)) {
- nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
- return 0;
- }
- if (lua_pcall(lstate, 0, 0, 0)) {
- nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
- return 0;
- }
- return 0;
-}
-
-/// Initialize lua interpreter state
-///
-/// Called by lua interpreter itself to initialize state.
-static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
-{
- // stricmp
- lua_pushcfunction(lstate, &nlua_stricmp);
- lua_setglobal(lstate, "stricmp");
-
- // print
- lua_pushcfunction(lstate, &nlua_print);
- lua_setglobal(lstate, "print");
-
- // debug.debug
- lua_getglobal(lstate, "debug");
- lua_pushcfunction(lstate, &nlua_debug);
- lua_setfield(lstate, -2, "debug");
- lua_pop(lstate, 1);
-
- // vim
- if (luaL_dostring(lstate, (char *)&vim_module[0])) {
- nlua_error(lstate, _("E5106: Error while creating vim module: %.*s"));
- return 1;
- }
- // vim.api
- nlua_add_api_functions(lstate);
- // vim.types, vim.type_idx, vim.val_idx
- nlua_init_types(lstate);
- lua_setglobal(lstate, "vim");
- return 0;
-}
-
-/// Initialize lua interpreter
-///
-/// Crashes NeoVim if initialization fails. Should be called once per lua
-/// interpreter instance.
-static lua_State *init_lua(void)
- FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
-{
- lua_State *lstate = luaL_newstate();
- if (lstate == NULL) {
- EMSG(_("E970: Failed to initialize lua interpreter"));
- preserve_exit();
- }
- luaL_openlibs(lstate);
- NLUA_CALL_C_FUNCTION_0(lstate, nlua_state_init, 0);
- return lstate;
-}
-
-static lua_State *global_lstate = NULL;
-
-/// Execute lua string
-///
-/// @param[in] str String to execute.
-/// @param[out] ret_tv Location where result will be saved.
-///
-/// @return Result of the execution.
-void executor_exec_lua(const String str, typval_T *const ret_tv)
- FUNC_ATTR_NONNULL_ALL
-{
- if (global_lstate == NULL) {
- global_lstate = init_lua();
- }
-
- NLUA_CALL_C_FUNCTION_2(global_lstate, nlua_exec_lua_string, 0,
- (void *)&str, ret_tv);
-}
-
-/// Evaluate lua string
-///
-/// Used for luaeval(). Expects three values on the stack:
-///
-/// 1. String to evaluate.
-/// 2. _A value.
-/// 3. Pointer to location where result is saved.
-///
-/// @param[in,out] lstate Lua interpreter state.
-static int nlua_eval_lua_string(lua_State *const lstate)
- FUNC_ATTR_NONNULL_ALL
-{
- const String *const str = (const String *)lua_touserdata(lstate, 1);
- typval_T *const arg = (typval_T *)lua_touserdata(lstate, 2);
- typval_T *const ret_tv = (typval_T *)lua_touserdata(lstate, 3);
- lua_pop(lstate, 3);
-
- garray_T str_ga;
- ga_init(&str_ga, 1, 80);
-#define EVALHEADER "local _A=select(1,...) return ("
- const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str->size + 1;
- char *lcmd;
- if (lcmd_len < IOSIZE) {
- lcmd = (char *)IObuff;
- } else {
- lcmd = xmalloc(lcmd_len);
- }
- memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1);
- memcpy(lcmd + sizeof(EVALHEADER) - 1, str->data, str->size);
- lcmd[lcmd_len - 1] = ')';
-#undef EVALHEADER
- if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
- nlua_error(lstate,
- _("E5107: Error while creating lua chunk for luaeval(): %.*s"));
- if (lcmd != (char *)IObuff) {
- xfree(lcmd);
- }
- return 0;
- }
- if (lcmd != (char *)IObuff) {
- xfree(lcmd);
- }
-
- if (arg == NULL || arg->v_type == VAR_UNKNOWN) {
- lua_pushnil(lstate);
- } else {
- nlua_push_typval(lstate, arg);
- }
- if (lua_pcall(lstate, 1, 1, 0)) {
- nlua_error(lstate,
- _("E5108: Error while calling lua chunk for luaeval(): %.*s"));
- return 0;
- }
- if (!nlua_pop_typval(lstate, ret_tv)) {
- return 0;
- }
-
- return 0;
-}
-
-/// Print as a Vim message
-///
-/// @param lstate Lua interpreter state.
-static int nlua_print(lua_State *const lstate)
- FUNC_ATTR_NONNULL_ALL
-{
-#define PRINT_ERROR(msg) \
- do { \
- errmsg = msg; \
- errmsg_len = sizeof(msg) - 1; \
- goto nlua_print_error; \
- } while (0)
- const int nargs = lua_gettop(lstate);
- lua_getglobal(lstate, "tostring");
- const char *errmsg = NULL;
- size_t errmsg_len = 0;
- garray_T msg_ga;
- ga_init(&msg_ga, 1, 80);
- int curargidx = 1;
- for (; curargidx <= nargs; curargidx++) {
- lua_pushvalue(lstate, -1); // tostring
- lua_pushvalue(lstate, curargidx); // arg
- if (lua_pcall(lstate, 1, 1, 0)) {
- errmsg = lua_tolstring(lstate, -1, &errmsg_len);
- goto nlua_print_error;
- }
- size_t len;
- const char *const s = lua_tolstring(lstate, -1, &len);
- if (s == NULL) {
- PRINT_ERROR(
- "<Unknown error: lua_tolstring returned NULL for tostring result>");
- }
- ga_concat_len(&msg_ga, s, len);
- if (curargidx < nargs) {
- ga_append(&msg_ga, ' ');
- }
- lua_pop(lstate, 1);
- }
-#undef PRINT_ERROR
- lua_pop(lstate, nargs + 1);
- ga_append(&msg_ga, NUL);
- {
- const size_t len = (size_t)msg_ga.ga_len - 1;
- char *const str = (char *)msg_ga.ga_data;
-
- for (size_t i = 0; i < len;) {
- const size_t start = i;
- while (i < len) {
- switch (str[i]) {
- case NUL: {
- str[i] = NL;
- i++;
- continue;
- }
- case NL: {
- str[i] = NUL;
- i++;
- break;
- }
- default: {
- i++;
- continue;
- }
- }
- break;
- }
- msg((char_u *)str + start);
- }
- if (str[len - 1] == NUL) { // Last was newline
- msg((char_u *)"");
- }
- }
- ga_clear(&msg_ga);
- return 0;
-nlua_print_error:
- emsgf(_("E5114: Error while converting print argument #%i: %.*s"),
- curargidx, errmsg_len, errmsg);
- ga_clear(&msg_ga);
- lua_pop(lstate, lua_gettop(lstate));
- return 0;
-}
-
-/// debug.debug implementation: interaction with user while debugging
-///
-/// @param lstate Lua interpreter state.
-int nlua_debug(lua_State *lstate)
- FUNC_ATTR_NONNULL_ALL
-{
- const typval_T input_args[] = {
- {
- .v_lock = VAR_FIXED,
- .v_type = VAR_STRING,
- .vval.v_string = (char_u *)"lua_debug> ",
- },
- {
- .v_type = VAR_UNKNOWN,
- },
- };
- for (;;) {
- lua_settop(lstate, 0);
- typval_T input;
- get_user_input(input_args, &input, false);
- msg_putchar('\n'); // Avoid outputting on input line.
- if (input.v_type != VAR_STRING
- || input.vval.v_string == NULL
- || *input.vval.v_string == NUL
- || STRCMP(input.vval.v_string, "cont") == 0) {
- tv_clear(&input);
- return 0;
- }
- if (luaL_loadbuffer(lstate, (const char *)input.vval.v_string,
- STRLEN(input.vval.v_string), "=(debug command)")) {
- nlua_error(lstate, _("E5115: Error while loading debug string: %.*s"));
- }
- tv_clear(&input);
- if (lua_pcall(lstate, 0, 0, 0)) {
- nlua_error(lstate, _("E5116: Error while calling debug string: %.*s"));
- }
- }
- return 0;
-}
-
-/// Evaluate lua string
-///
-/// Used for luaeval().
-///
-/// @param[in] str String to execute.
-/// @param[in] arg Second argument to `luaeval()`.
-/// @param[out] ret_tv Location where result will be saved.
-///
-/// @return Result of the execution.
-void executor_eval_lua(const String str, typval_T *const arg,
- typval_T *const ret_tv)
- FUNC_ATTR_NONNULL_ALL
-{
- if (global_lstate == NULL) {
- global_lstate = init_lua();
- }
-
- NLUA_CALL_C_FUNCTION_3(global_lstate, nlua_eval_lua_string, 0,
- (void *)&str, arg, ret_tv);
-}
-
-/// Run lua string
-///
-/// Used for :lua.
-///
-/// @param eap VimL command being run.
-void ex_lua(exarg_T *const eap)
- FUNC_ATTR_NONNULL_ALL
-{
- size_t len;
- char *const code = script_get(eap, &len);
- if (eap->skip) {
- xfree(code);
- return;
- }
- typval_T tv = { .v_type = VAR_UNKNOWN };
- executor_exec_lua((String) { .data = code, .size = len }, &tv);
- tv_clear(&tv);
- xfree(code);
-}
-
-/// Run lua string for each line in range
-///
-/// Used for :luado.
-///
-/// @param eap VimL command being run.
-void ex_luado(exarg_T *const eap)
- FUNC_ATTR_NONNULL_ALL
-{
- if (global_lstate == NULL) {
- global_lstate = init_lua();
- }
- if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) {
- EMSG(_("cannot save undo information"));
- return;
- }
- const String cmd = {
- .size = STRLEN(eap->arg),
- .data = (char *)eap->arg,
- };
- const linenr_T range[] = { eap->line1, eap->line2 };
- NLUA_CALL_C_FUNCTION_2(global_lstate, nlua_exec_luado_string, 0,
- (void *)&cmd, (void *)range);
-}
-
-/// Run lua file
-///
-/// Used for :luafile.
-///
-/// @param eap VimL command being run.
-void ex_luafile(exarg_T *const eap)
- FUNC_ATTR_NONNULL_ALL
-{
- if (global_lstate == NULL) {
- global_lstate = init_lua();
- }
- NLUA_CALL_C_FUNCTION_1(global_lstate, nlua_exec_lua_file, 0,
- (void *)eap->arg);
-}
diff --git a/src/nvim/viml/executor/executor.h b/src/nvim/viml/executor/executor.h
deleted file mode 100644
index 648bb73785..0000000000
--- a/src/nvim/viml/executor/executor.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef NVIM_VIML_EXECUTOR_EXECUTOR_H
-#define NVIM_VIML_EXECUTOR_EXECUTOR_H
-
-#include <lua.h>
-
-#include "nvim/api/private/defs.h"
-#include "nvim/func_attr.h"
-#include "nvim/eval/typval.h"
-#include "nvim/ex_cmds_defs.h"
-
-// Generated by msgpack-gen.lua
-void nlua_add_api_functions(lua_State *lstate) REAL_FATTR_NONNULL_ALL;
-
-#define set_api_error(s, err) \
- do { \
- Error *err_ = (err); \
- err_->type = kErrorTypeException; \
- err_->set = true; \
- memcpy(&err_->msg[0], s, sizeof(s)); \
- } while (0)
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "viml/executor/executor.h.generated.h"
-#endif
-#endif // NVIM_VIML_EXECUTOR_EXECUTOR_H
diff --git a/src/nvim/viml/executor/vim.lua b/src/nvim/viml/executor/vim.lua
deleted file mode 100644
index 8d1c5bdf4f..0000000000
--- a/src/nvim/viml/executor/vim.lua
+++ /dev/null
@@ -1,2 +0,0 @@
--- TODO(ZyX-I): Create compatibility layer.
-return {}