diff src/scriptfile.c @ 20339:7587d892c00c v8.2.0725

patch 8.2.0725: Vim9: cannot call a function declared later in Vim9 script Commit: https://github.com/vim/vim/commit/09689a02840be40fa7bb10b1921fb5bc5b2908f1 Author: Bram Moolenaar <Bram@vim.org> Date: Sat May 9 22:50:08 2020 +0200 patch 8.2.0725: Vim9: cannot call a function declared later in Vim9 script Problem: Vim9: cannot call a function declared later in Vim9 script. Solution: Make two passes through the script file.
author Bram Moolenaar <Bram@vim.org>
date Sat, 09 May 2020 23:00:04 +0200
parents d821c03b890c
children 0e1dfff4f294
line wrap: on
line diff
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -998,6 +998,8 @@ struct source_cookie
     int		error;		// TRUE if LF found after CR-LF
 #endif
 #ifdef FEAT_EVAL
+    garray_T	lines_ga;	// lines read in previous pass
+    int		use_lines_ga;	// next line to get from "lines_ga"
     linenr_T	breakpoint;	// next line with breakpoint or zero
     char_u	*fname;		// name of sourced file
     int		dbg_tick;	// debug_tick when breakpoint was set
@@ -1017,6 +1019,24 @@ source_breakpoint(void *cookie)
 }
 
 /*
+ * Get the grow array to store script lines in.
+ */
+    garray_T *
+source_get_line_ga(void *cookie)
+{
+    return &((struct source_cookie *)cookie)->lines_ga;
+}
+
+/*
+ * Set the index to start reading from the grow array with script lines.
+ */
+    void
+source_use_line_ga(void *cookie)
+{
+    ((struct source_cookie *)cookie)->use_lines_ga = 0;
+}
+
+/*
  * Return the address holding the debug tick for a source cookie.
  */
     int *
@@ -1235,6 +1255,9 @@ do_source(
     cookie.finished = FALSE;
 
 #ifdef FEAT_EVAL
+    ga_init2(&cookie.lines_ga, sizeof(char_u *), 200);
+    cookie.use_lines_ga = -1;
+
     // Check if this script has a breakpoint.
     cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
     cookie.fname = fname_exp;
@@ -1447,6 +1470,9 @@ almosttheend:
     vim_free(cookie.nextline);
     vim_free(firstline);
     convert_setup(&cookie.conv, NULL, NULL);
+#ifdef FEAT_EVAL
+    ga_clear_strings(&cookie.lines_ga);
+#endif
 
     if (trigger_source_post)
 	apply_autocmds(EVENT_SOURCEPOST, fname_exp, fname_exp, FALSE, curbuf);
@@ -1702,6 +1728,31 @@ getsourceline(int c UNUSED, void *cookie
     // one now.
     if (sp->finished)
 	line = NULL;
+#ifdef FEAT_EVAL
+    else if (sp->use_lines_ga >= 0)
+    {
+	// Get a line that was read in ex_vim9script().
+	for (;;)
+	{
+	    if (sp->use_lines_ga >= sp->lines_ga.ga_len)
+	    {
+		line = NULL;
+		break;
+	    }
+	    else
+	    {
+		line = ((char_u **)(sp->lines_ga.ga_data))[sp->use_lines_ga];
+		((char_u **)(sp->lines_ga.ga_data))[sp->use_lines_ga] = NULL;
+		++sp->use_lines_ga;
+		if (line != NULL)
+		    break;
+		// Skip NULL lines, they are equivalent to blank lines.
+		++sp->sourcing_lnum;
+	    }
+	}
+	SOURCING_LNUM = sp->sourcing_lnum + 1;
+    }
+#endif
     else if (sp->nextline == NULL)
 	line = get_one_sourceline(sp);
     else