patch 8.2.4804: expression in heredoc doesn't work for compiled function

Problem:    Expression in heredoc doesn't work for compiled function.
Solution:   Implement compiling the heredoc expressions. (Yegappan Lakshmanan,
            closes #10232)
diff --git a/src/evalvars.c b/src/evalvars.c
index c83aa61..ffa7e93 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -673,16 +673,21 @@
  *
  * The {marker} is a string. If the optional 'trim' word is supplied before the
  * marker, then the leading indentation before the lines (matching the
- * indentation in the 'cmd' line) is stripped.
+ * indentation in the "cmd" line) is stripped.
  *
  * When getting lines for an embedded script (e.g. python, lua, perl, ruby,
- * tcl, mzscheme), script_get is set to TRUE. In this case, if the marker is
+ * tcl, mzscheme), "script_get" is set to TRUE. In this case, if the marker is
  * missing, then '.' is accepted as a marker.
  *
+ * When compiling a heredoc assignment to a variable in a Vim9 def function,
+ * "vim9compile" is set to TRUE. In this case, instead of generating a list of
+ * string values from the heredoc, vim9 instructions are generated.  On success
+ * the returned list will be empty.
+ *
  * Returns a List with {lines} or NULL on failure.
  */
     list_T *
-heredoc_get(exarg_T *eap, char_u *cmd, int script_get)
+heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
 {
     char_u	*theline = NULL;
     char_u	*marker;
@@ -696,6 +701,8 @@
     int		comment_char = in_vim9script() ? '#' : '"';
     int		evalstr = FALSE;
     int		eval_failed = FALSE;
+    cctx_T	*cctx = vim9compile ? eap->cookie : NULL;
+    int		count = 0;
 
     if (eap->getline == NULL)
     {
@@ -816,25 +823,41 @@
 		    break;
 
 	str = theline + ti;
-	if (evalstr)
+	if (vim9compile)
 	{
-	    str = eval_all_expr_in_str(str);
-	    if (str == NULL)
+	    if (compile_heredoc_string(str, evalstr, cctx) == FAIL)
 	    {
-		// expression evaluation failed
-		eval_failed = TRUE;
-		continue;
+		vim_free(theline);
+		vim_free(text_indent);
+		return FAIL;
 	    }
-	    vim_free(theline);
-	    theline = str;
+	    count++;
 	}
+	else
+	{
+	    if (evalstr)
+	    {
+		str = eval_all_expr_in_str(str);
+		if (str == NULL)
+		{
+		    // expression evaluation failed
+		    eval_failed = TRUE;
+		    continue;
+		}
+		vim_free(theline);
+		theline = str;
+	    }
 
-	if (list_append_string(l, str, -1) == FAIL)
-	    break;
+	    if (list_append_string(l, str, -1) == FAIL)
+		break;
+	}
     }
     vim_free(theline);
     vim_free(text_indent);
 
+    if (vim9compile && cctx->ctx_skip != SKIP_YES && !eval_failed)
+	generate_NEWLIST(cctx, count, FALSE);
+
     if (eval_failed)
     {
 	// expression evaluation in the heredoc failed
@@ -986,7 +1009,7 @@
 	long	cur_lnum = SOURCING_LNUM;
 
 	// HERE document
-	l = heredoc_get(eap, expr + 3, FALSE);
+	l = heredoc_get(eap, expr + 3, FALSE, FALSE);
 	if (l != NULL)
 	{
 	    rettv_list_set(&rettv, l);