patch 9.0.1031: Vim9 class is not implemented yet
Problem: Vim9 class is not implemented yet.
Solution: Add very basic class support.
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 217147a..b164502 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -2029,6 +2029,7 @@
for (ni = iptr + 1; ni->isn_type != ISN_FINISH; ++ni)
if (ni->isn_type == ISN_DEBUG
|| ni->isn_type == ISN_RETURN
+ || ni->isn_type == ISN_RETURN_OBJECT
|| ni->isn_type == ISN_RETURN_VOID)
{
end_lnum = ni->isn_lnum + (ni->isn_type == ISN_DEBUG ? 0 : 1);
@@ -2082,7 +2083,7 @@
// Stack contains:
// -3 value to be stored
// -2 index
- // -1 dict or list
+ // -1 dict, list, blob or object
tv = STACK_TV_BOT(-3);
SOURCING_LNUM = iptr->isn_lnum;
if (dest_type == VAR_ANY)
@@ -2203,6 +2204,13 @@
return FAIL;
blob_set_append(blob, lidx, nr);
}
+ else if (dest_type == VAR_CLASS || dest_type == VAR_OBJECT)
+ {
+ long idx = (long)tv_idx->vval.v_number;
+ object_T *obj = tv_dest->vval.v_object;
+ typval_T *otv = (typval_T *)(obj + 1);
+ otv[idx] = *tv;
+ }
else
{
status = FAIL;
@@ -3001,6 +3009,18 @@
iptr = &ectx->ec_instr[ectx->ec_iidx++];
switch (iptr->isn_type)
{
+ // Constructor, new() method.
+ case ISN_CONSTRUCT:
+ // "this" is always the local variable at index zero
+ tv = STACK_TV_VAR(0);
+ tv->v_type = VAR_OBJECT;
+ tv->vval.v_object = alloc_clear(
+ iptr->isn_arg.construct.construct_size);
+ tv->vval.v_object->obj_class =
+ iptr->isn_arg.construct.construct_class;
+ tv->vval.v_object->obj_refcount = 1;
+ break;
+
// execute Ex command line
case ISN_EXEC:
if (exec_command(iptr) == FAIL)
@@ -4092,15 +4112,25 @@
goto on_error;
break;
- // return from a :def function call without a value
+ // Return from a :def function call without a value.
+ // Return from a constructor.
case ISN_RETURN_VOID:
+ case ISN_RETURN_OBJECT:
if (GA_GROW_FAILS(&ectx->ec_stack, 1))
goto theend;
tv = STACK_TV_BOT(0);
++ectx->ec_stack.ga_len;
- tv->v_type = VAR_VOID;
- tv->vval.v_number = 0;
- tv->v_lock = 0;
+ if (iptr->isn_type == ISN_RETURN_VOID)
+ {
+ tv->v_type = VAR_VOID;
+ tv->vval.v_number = 0;
+ tv->v_lock = 0;
+ }
+ else
+ {
+ *tv = *STACK_TV_VAR(0);
+ ++tv->vval.v_object->obj_refcount;
+ }
// FALLTHROUGH
// return from a :def function call with what is on the stack
@@ -4193,7 +4223,7 @@
CLEAR_FIELD(ea);
ea.cmd = ea.arg = iptr->isn_arg.string;
ga_init2(&lines_to_free, sizeof(char_u *), 50);
- define_function(&ea, NULL, &lines_to_free);
+ define_function(&ea, NULL, &lines_to_free, NULL);
ga_clear_strings(&lines_to_free);
}
break;
@@ -6018,6 +6048,11 @@
switch (iptr->isn_type)
{
+ case ISN_CONSTRUCT:
+ smsg("%s%4d NEW %s size %d", pfx, current,
+ iptr->isn_arg.construct.construct_class->class_name,
+ (int)iptr->isn_arg.construct.construct_size);
+ break;
case ISN_EXEC:
smsg("%s%4d EXEC %s", pfx, current, iptr->isn_arg.string);
break;
@@ -6447,6 +6482,9 @@
case ISN_RETURN_VOID:
smsg("%s%4d RETURN void", pfx, current);
break;
+ case ISN_RETURN_OBJECT:
+ smsg("%s%4d RETURN object", pfx, current);
+ break;
case ISN_FUNCREF:
{
funcref_T *funcref = &iptr->isn_arg.funcref;
@@ -6979,6 +7017,8 @@
case VAR_ANY:
case VAR_VOID:
case VAR_INSTR:
+ case VAR_CLASS:
+ case VAR_OBJECT:
break;
}
return FALSE;