patch 9.1.0219: Vim9: No enum support

Problem:  No enum support
Solution: Implement enums for Vim9 script
          (Yegappan Lakshmanan)

closes: #14224

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index ec70220..1f7a4f1 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt*	For Vim version 9.1.  Last change: 2024 Mar 23
+*builtin.txt*	For Vim version 9.1.  Last change: 2024 Mar 28
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -9598,6 +9598,8 @@
 			Dictionary	{key: value, key: value}
 			Class		class SomeName
 			Object		object of SomeName {lnum: 1, col: 3}
+			Enum		enum EnumName
+			EnumValue	enum.value
 
 		When a |List| or |Dictionary| has a recursive reference it is
 		replaced by "[...]" or "{...}".  Using eval() on the result
@@ -10461,6 +10463,8 @@
 			Class:	   12  |v:t_class|
 			Object:	   13  |v:t_object|
 			Typealias: 14  |v:t_typealias|
+			Enum:	   15  |v:t_enum|
+			EnumValue: 16  |v:t_enumvalue|
 		For backward compatibility, this method can be used: >
 			:if type(myvar) == type(0)
 			:if type(myvar) == type("")
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index f2ff3a8..fd37d97 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt*	For Vim version 9.1.  Last change: 2024 Mar 20
+*eval.txt*	For Vim version 9.1.  Last change: 2024 Mar 28
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -2601,6 +2601,10 @@
 v:t_object	Value of |object| type.  Read-only.  See: |type()|
 					*v:t_typealias* *t_typealias-variable*
 v:t_typealias	Value of |typealias| type.  Read-only.  See: |type()|
+					*v:t_enum* *t_enum-variable*
+v:t_enum	Value of |enum| type.  Read-only.  See: |type()|
+					*v:t_enumvalue* *t_enumvalue-variable*
+v:t_enumvalue	Value of |enumvalue| type.  Read-only.  See: |type()|
 
 				*v:termresponse* *termresponse-variable*
 v:termresponse	The escape sequence returned by the terminal for the |t_RV|
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 4ff7095..528538e 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -4520,7 +4520,20 @@
 E1411	vim9class.txt	/*E1411*
 E1412	vim9class.txt	/*E1412*
 E1413	vim9class.txt	/*E1413*
+E1414	vim9class.txt	/*E1414*
+E1415	vim9class.txt	/*E1415*
+E1416	vim9class.txt	/*E1416*
+E1417	vim9class.txt	/*E1417*
+E1418	vim9class.txt	/*E1418*
+E1419	vim9class.txt	/*E1419*
 E142	message.txt	/*E142*
+E1420	vim9class.txt	/*E1420*
+E1421	vim9class.txt	/*E1421*
+E1422	vim9class.txt	/*E1422*
+E1423	vim9class.txt	/*E1423*
+E1424	vim9class.txt	/*E1424*
+E1425	vim9class.txt	/*E1425*
+E1426	vim9class.txt	/*E1426*
 E143	autocmd.txt	/*E143*
 E144	various.txt	/*E144*
 E145	starting.txt	/*E145*
@@ -6874,6 +6887,12 @@
 end	intro.txt	/*end*
 end-of-file	pattern.txt	/*end-of-file*
 enlightened-terminal	syntax.txt	/*enlightened-terminal*
+enum	vim9class.txt	/*enum*
+enum-constructor	vim9class.txt	/*enum-constructor*
+enum-name	vim9class.txt	/*enum-name*
+enum-ordinal	vim9class.txt	/*enum-ordinal*
+enum-values	vim9class.txt	/*enum-values*
+enumvalue	vim9class.txt	/*enumvalue*
 environ()	builtin.txt	/*environ()*
 eol-and-eof	editing.txt	/*eol-and-eof*
 erlang.vim	syntax.txt	/*erlang.vim*
@@ -10290,6 +10309,8 @@
 t_ds	term.txt	/*t_ds*
 t_ed	version4.txt	/*t_ed*
 t_el	version4.txt	/*t_el*
+t_enum-variable	eval.txt	/*t_enum-variable*
+t_enumvalue-variable	eval.txt	/*t_enumvalue-variable*
 t_f1	version4.txt	/*t_f1*
 t_f10	version4.txt	/*t_f10*
 t_f2	version4.txt	/*t_f2*
@@ -10863,6 +10884,8 @@
 v:t_channel	eval.txt	/*v:t_channel*
 v:t_class	eval.txt	/*v:t_class*
 v:t_dict	eval.txt	/*v:t_dict*
+v:t_enum	eval.txt	/*v:t_enum*
+v:t_enumvalue	eval.txt	/*v:t_enumvalue*
 v:t_float	eval.txt	/*v:t_float*
 v:t_func	eval.txt	/*v:t_func*
 v:t_job	eval.txt	/*v:t_job*
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index 2b4a70a..8712008 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 9.1.  Last change: 2024 Mar 03
+*todo.txt*      For Vim version 9.1.  Last change: 2024 Mar 28
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -144,7 +144,6 @@
   - More efficient way for interface member index than iterating over list?
   - a variant of type() that returns a different type for each class?
       list<number> and list<string> should also differ.
-- implement :enum
 - Promise class, could be used to wait on a popup close callback?
 - class local to a function
 - Use Vim9 for more runtime files.
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 8ea30a4..587cdd5 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -41548,6 +41548,8 @@
 Add support for internal builtin functions with vim9 objects, see
 |builtin-object-methods|
 
+Enum support for Vim9 script |:enum|
+
 Other improvements				*new-other-9.2*
 ------------------
 
diff --git a/runtime/doc/vim9class.txt b/runtime/doc/vim9class.txt
index a00a5b7..8820d77 100644
--- a/runtime/doc/vim9class.txt
+++ b/runtime/doc/vim9class.txt
@@ -1,4 +1,4 @@
-*vim9class.txt*	For Vim version 9.1.  Last change: 2024 Mar 03
+*vim9class.txt*	For Vim version 9.1.  Last change: 2024 Mar 28
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -904,19 +904,125 @@
 
 8.  Enum					*Vim9-enum* *:enum* *:endenum*
 
-{not implemented yet}
-
+						*enum* *E1418* *E1419* *E1420*
 An enum is a type that can have one of a list of values.  Example: >
 
-	:enum Color
-		White
-		Red
-		Green
-		Blue
-		Black
-	:endenum
+    :enum Color
+	White,
+	Red,
+	Green, Blue, Black
+    :endenum
+<
+						*enumvalue* *E1422*
+The enum values are separated by commas.  More than one enum value can be
+listed in a single line.  The final enum value should not be followed by a
+comma.
 
+An enum value is accessed using the enum name followed by the value name: >
 
+    var a: Color = Color.Blue
+<
+Enums are treated as classes, where each enum value is essentially an instance
+of that class.  Unlike typical object instantiation with the |new()| method,
+enum instances cannot be created this way.
+
+An enum can only be defined in a |Vim9| script file.	*E1414*
+An enum cannot be defined inside a function.
+
+							*E1415*
+An enum name must start with an uppercase letter.  The name of an enum value
+in an enum can start with an upper or lowercase letter.
+
+							*E1416*
+An enum can implement an interface but cannot extend a class: >
+
+    enum MyEnum implements MyIntf
+	Value1,
+	Value2
+
+	def SomeMethod()
+	enddef
+    endenum
+<
+							*enum-constructor*
+The enum value objects in an enum are constructed like any other objects using
+the |new()| method.  Arguments can be passed to the enum constructor by
+specifying them after the enum value name, just like calling a function.  The
+default constructor doesn't have any arguments.
+
+							*E1417*
+An enum can contain class variables, class methods, object variables and
+object methods.  The methods in an enum cannot be |:abstract| methods.
+
+The following example shows an enum with object variables and methods: >
+
+    vim9script
+    enum Planet
+	Earth(1, false),
+	Jupiter(95, true),
+	Saturn(146, true)
+
+	var moons: number
+	var has_rings: bool
+	def GetMoons(): number
+	    return this.moons
+	enddef
+    endenum
+    echo Planet.Jupiter.GetMoons()
+    echo Planet.Earth.has_rings
+<
+						*E1421* *E1423* *E1424* *E1425*
+Enums and their values are immutable. They cannot be modified after
+declaration and cannot be utilized as numerical or string types.
+
+						*enum-name*
+Each enum value object has a "name" instance variable which contains the name
+of the enum value.  This is a readonly variable.
+
+						*enum-ordinal* *E1426*
+Each enum value has an associated ordinal number starting with 0.  The ordinal
+number of an enum value can be accessed using the "ordinal" instance variable.
+This is a readonly variable.  Note that if the ordering of the enum values in
+an enum is changed, then their ordinal values will also change.
+
+						*enum-values*
+All the values in an enum can be accessed using the "values" class variable
+which is a List of the enum objects.  This is a readonly variable.
+
+Example: >
+    enum Planet
+	Mercury,
+	Venus,
+	Earth
+    endenum
+
+    echo Planet.Mercury
+    echo Planet.Venus.name
+    echo Planet.Venus.ordinal
+    for p in Planet.values
+	# ...
+    endfor
+<
+An enum is a class with class variables for the enum value objects and object
+variables for the enum value name and the enum value ordinal: >
+
+    enum Planet
+	Mercury,
+	Venus
+    endenum
+<
+The above enum definition is equivalent to the following class definition: >
+
+    class Planet
+      public static final Mercury: Planet = Planet.new('Mercury', 0)
+      public static final Venus: Planet = Planet.new('Venus', 1)
+
+      public static const values: list<Planet> = [Planet.Mercury, Planet.Venus]
+
+      public const name: string
+      public const ordinal: number
+    endclass
+<
 ==============================================================================
 
 9.  Rationale