annotate src/vim9cmds.c @ 32669:448aef880252

normalize line endings
author Christian Brabandt <cb@256bit.org>
date Mon, 26 Jun 2023 09:54:34 +0200
parents c1f730c2b51e
children 695b50472e85
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32669
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1 /* vi:set ts=8 sts=4 sw=4 noet:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2 *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
3 * VIM - Vi IMproved by Bram Moolenaar
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
4 *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
5 * Do ":help uganda" in Vim to read copying and usage conditions.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
6 * Do ":help credits" in Vim to see a list of people who contributed.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
7 * See README.txt for an overview of the Vim source code.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
8 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
9
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
10 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
11 * vim9cmds.c: Dealing with commands of a compiled function
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
12 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
13
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
14 #define USING_FLOAT_STUFF
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
15 #include "vim.h"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
16
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
17 #if defined(FEAT_EVAL) || defined(PROTO)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
18
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
19 // When not generating protos this is included in proto.h
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
20 #ifdef PROTO
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
21 # include "vim9.h"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
22 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
23
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
24 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
25 * Get the index of the current instruction.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
26 * This compensates for a preceding ISN_CMDMOD and ISN_PROF_START.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
27 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
28 static int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
29 current_instr_idx(cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
30 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
31 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
32 int idx = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
33
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
34 while (idx > 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
35 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
36 if (cctx->ctx_has_cmdmod && ((isn_T *)instr->ga_data)[idx - 1]
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
37 .isn_type == ISN_CMDMOD)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
38 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
39 --idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
40 continue;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
41 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
42 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
43 if (((isn_T *)instr->ga_data)[idx - 1].isn_type == ISN_PROF_START)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
44 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
45 --idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
46 continue;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
47 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
48 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
49 if (((isn_T *)instr->ga_data)[idx - 1].isn_type == ISN_DEBUG)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
50 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
51 --idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
52 continue;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
53 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
54 break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
55 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
56 return idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
57 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
58 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
59 * Remove local variables above "new_top".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
60 * Do this by clearing the name. If "keep" is TRUE do not reset the length, a
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
61 * closure may still need location of the variable.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
62 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
63 static void
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
64 unwind_locals(cctx_T *cctx, int new_top, int keep)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
65 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
66 if (cctx->ctx_locals.ga_len > new_top)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
67 for (int idx = new_top; idx < cctx->ctx_locals.ga_len; ++idx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
68 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
69 lvar_T *lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
70 VIM_CLEAR(lvar->lv_name);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
71 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
72 if (!keep)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
73 cctx->ctx_locals.ga_len = new_top;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
74 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
75
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
76 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
77 * Free all local variables.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
78 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
79 void
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
80 free_locals(cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
81 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
82 unwind_locals(cctx, 0, FALSE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
83 ga_clear(&cctx->ctx_locals);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
84 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
85
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
86
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
87 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
88 * Check if "name" can be "unlet".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
89 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
90 int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
91 check_vim9_unlet(char_u *name)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
92 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
93 if (*name == NUL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
94 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
95 semsg(_(e_argument_required_for_str), "unlet");
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
96 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
97 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
98
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
99 if (name[1] != ':' || vim_strchr((char_u *)"gwtb", *name) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
100 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
101 // "unlet s:var" is allowed in legacy script.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
102 if (*name == 's' && !script_is_vim9())
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
103 return OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
104 semsg(_(e_cannot_unlet_str), name);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
105 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
106 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
107 return OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
108 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
109
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
110 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
111 * Callback passed to ex_unletlock().
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
112 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
113 static int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
114 compile_unlet(
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
115 lval_T *lvp,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
116 char_u *name_end,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
117 exarg_T *eap,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
118 int deep UNUSED,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
119 void *coookie)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
120 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
121 cctx_T *cctx = coookie;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
122 char_u *p = lvp->ll_name;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
123 int cc = *name_end;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
124 int ret = OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
125
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
126 if (cctx->ctx_skip == SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
127 return OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
128
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
129 *name_end = NUL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
130 if (*p == '$')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
131 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
132 // :unlet $ENV_VAR
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
133 ret = generate_UNLET(cctx, ISN_UNLETENV, p + 1, eap->forceit);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
134 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
135 else if (vim_strchr(p, '.') != NULL || vim_strchr(p, '[') != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
136 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
137 lhs_T lhs;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
138
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
139 // This is similar to assigning: lookup the list/dict, compile the
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
140 // idx/key. Then instead of storing the value unlet the item.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
141 // unlet {list}[idx]
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
142 // unlet {dict}[key] dict.key
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
143 //
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
144 // Figure out the LHS type and other properties.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
145 //
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
146 ret = compile_lhs(p, &lhs, CMD_unlet, FALSE, FALSE, 0, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
147
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
148 // Use the info in "lhs" to unlet the item at the index in the
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
149 // list or dict.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
150 if (ret == OK)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
151 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
152 if (!lhs.lhs_has_index)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
153 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
154 semsg(_(e_cannot_unlet_imported_item_str), p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
155 ret = FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
156 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
157 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
158 ret = compile_assign_unlet(p, &lhs, FALSE, &t_void, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
159 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
160
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
161 vim_free(lhs.lhs_name);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
162 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
163 else if (check_vim9_unlet(p) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
164 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
165 ret = FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
166 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
167 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
168 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
169 // Normal name. Only supports g:, w:, t: and b: namespaces.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
170 ret = generate_UNLET(cctx, ISN_UNLET, p, eap->forceit);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
171 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
172
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
173 *name_end = cc;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
174 return ret;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
175 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
176
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
177 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
178 * Callback passed to ex_unletlock().
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
179 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
180 static int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
181 compile_lock_unlock(
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
182 lval_T *lvp,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
183 char_u *name_end,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
184 exarg_T *eap,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
185 int deep,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
186 void *coookie)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
187 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
188 cctx_T *cctx = coookie;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
189 int cc = *name_end;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
190 char_u *p = lvp->ll_name;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
191 int ret = OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
192 size_t len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
193 char_u *buf;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
194 isntype_T isn = ISN_EXEC;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
195 char *cmd = eap->cmdidx == CMD_lockvar ? "lockvar" : "unlockvar";
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
196
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
197 if (cctx->ctx_skip == SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
198 return OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
199
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
200 if (*p == NUL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
201 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
202 semsg(_(e_argument_required_for_str), cmd);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
203 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
204 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
205
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
206 // Cannot use :lockvar and :unlockvar on local variables.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
207 if (p[1] != ':')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
208 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
209 char_u *end = find_name_end(p, NULL, NULL, FNE_CHECK_START);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
210
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
211 if (lookup_local(p, end - p, NULL, cctx) == OK)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
212 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
213 char_u *s = p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
214
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
215 if (*end != '.' && *end != '[')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
216 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
217 emsg(_(e_cannot_lock_unlock_local_variable));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
218 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
219 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
220
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
221 // For "d.member" put the local variable on the stack, it will be
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
222 // passed to ex_lockvar() indirectly.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
223 if (compile_load(&s, end, cctx, FALSE, FALSE) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
224 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
225 isn = ISN_LOCKUNLOCK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
226 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
227 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
228
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
229 // Checking is done at runtime.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
230 *name_end = NUL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
231 len = name_end - p + 20;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
232 buf = alloc(len);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
233 if (buf == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
234 ret = FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
235 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
236 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
237 if (deep < 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
238 vim_snprintf((char *)buf, len, "%s! %s", cmd, p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
239 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
240 vim_snprintf((char *)buf, len, "%s %d %s", cmd, deep, p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
241 ret = generate_EXEC_copy(cctx, isn, buf);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
242
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
243 vim_free(buf);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
244 *name_end = cc;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
245 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
246 return ret;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
247 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
248
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
249 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
250 * compile "unlet var", "lock var" and "unlock var"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
251 * "arg" points to "var".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
252 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
253 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
254 compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
255 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
256 int deep = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
257 char_u *p = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
258
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
259 if (eap->cmdidx != CMD_unlet)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
260 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
261 if (eap->forceit)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
262 deep = -1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
263 else if (vim_isdigit(*p))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
264 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
265 deep = getdigits(&p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
266 p = skipwhite(p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
267 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
268 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
269 deep = 2;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
270 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
271
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
272 ex_unletlock(eap, p, deep, GLV_NO_AUTOLOAD | GLV_COMPILING,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
273 eap->cmdidx == CMD_unlet ? compile_unlet : compile_lock_unlock,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
274 cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
275 return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
276 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
277
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
278 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
279 * Generate a jump to the ":endif"/":endfor"/":endwhile"/":finally"/":endtry".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
280 * "funcref_idx" is used for JUMP_WHILE_FALSE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
281 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
282 static int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
283 compile_jump_to_end(
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
284 endlabel_T **el,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
285 jumpwhen_T when,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
286 int funcref_idx,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
287 cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
288 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
289 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
290 endlabel_T *endlabel = ALLOC_CLEAR_ONE(endlabel_T);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
291
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
292 if (endlabel == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
293 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
294 endlabel->el_next = *el;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
295 *el = endlabel;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
296 endlabel->el_end_label = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
297
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
298 if (when == JUMP_WHILE_FALSE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
299 generate_WHILE(cctx, funcref_idx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
300 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
301 generate_JUMP(cctx, when, 0);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
302 return OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
303 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
304
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
305 static void
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
306 compile_fill_jump_to_end(endlabel_T **el, int jump_where, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
307 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
308 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
309
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
310 while (*el != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
311 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
312 endlabel_T *cur = (*el);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
313 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
314
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
315 isn = ((isn_T *)instr->ga_data) + cur->el_end_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
316 isn->isn_arg.jump.jump_where = jump_where;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
317 *el = cur->el_next;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
318 vim_free(cur);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
319 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
320 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
321
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
322 static void
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
323 compile_free_jump_to_end(endlabel_T **el)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
324 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
325 while (*el != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
326 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
327 endlabel_T *cur = (*el);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
328
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
329 *el = cur->el_next;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
330 vim_free(cur);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
331 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
332 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
333
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
334 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
335 * Create a new scope and set up the generic items.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
336 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
337 static scope_T *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
338 new_scope(cctx_T *cctx, scopetype_T type)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
339 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
340 scope_T *scope = ALLOC_CLEAR_ONE(scope_T);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
341
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
342 if (scope == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
343 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
344 scope->se_outer = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
345 cctx->ctx_scope = scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
346 scope->se_type = type;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
347 scope->se_local_count = cctx->ctx_locals.ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
348 if (scope->se_outer != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
349 scope->se_loop_depth = scope->se_outer->se_loop_depth;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
350 return scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
351 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
352
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
353 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
354 * Free the current scope and go back to the outer scope.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
355 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
356 void
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
357 drop_scope(cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
358 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
359 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
360
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
361 if (scope == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
362 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
363 iemsg("calling drop_scope() without a scope");
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
364 return;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
365 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
366 cctx->ctx_scope = scope->se_outer;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
367 switch (scope->se_type)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
368 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
369 case IF_SCOPE:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
370 compile_free_jump_to_end(&scope->se_u.se_if.is_end_label); break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
371 case FOR_SCOPE:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
372 compile_free_jump_to_end(&scope->se_u.se_for.fs_end_label); break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
373 case WHILE_SCOPE:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
374 compile_free_jump_to_end(&scope->se_u.se_while.ws_end_label); break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
375 case TRY_SCOPE:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
376 compile_free_jump_to_end(&scope->se_u.se_try.ts_end_label); break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
377 case NO_SCOPE:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
378 case BLOCK_SCOPE:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
379 break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
380 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
381 vim_free(scope);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
382 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
383
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
384 static int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
385 misplaced_cmdmod(cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
386 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
387 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
388
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
389 if (cctx->ctx_has_cmdmod
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
390 && ((isn_T *)instr->ga_data)[instr->ga_len - 1].isn_type
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
391 == ISN_CMDMOD)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
392 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
393 emsg(_(e_misplaced_command_modifier));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
394 return TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
395 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
396 return FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
397 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
398
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
399 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
400 * compile "if expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
401 *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
402 * "if expr" Produces instructions:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
403 * EVAL expr Push result of "expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
404 * JUMP_IF_FALSE end
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
405 * ... body ...
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
406 * end:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
407 *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
408 * "if expr | else" Produces instructions:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
409 * EVAL expr Push result of "expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
410 * JUMP_IF_FALSE else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
411 * ... body ...
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
412 * JUMP_ALWAYS end
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
413 * else:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
414 * ... body ...
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
415 * end:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
416 *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
417 * "if expr1 | elseif expr2 | else" Produces instructions:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
418 * EVAL expr Push result of "expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
419 * JUMP_IF_FALSE elseif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
420 * ... body ...
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
421 * JUMP_ALWAYS end
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
422 * elseif:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
423 * EVAL expr Push result of "expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
424 * JUMP_IF_FALSE else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
425 * ... body ...
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
426 * JUMP_ALWAYS end
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
427 * else:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
428 * ... body ...
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
429 * end:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
430 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
431 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
432 compile_if(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
433 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
434 char_u *p = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
435 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
436 int instr_count = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
437 scope_T *scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
438 skip_T skip_save = cctx->ctx_skip;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
439 ppconst_T ppconst;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
440
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
441 CLEAR_FIELD(ppconst);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
442 if (compile_expr1(&p, cctx, &ppconst) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
443 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
444 clear_ppconst(&ppconst);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
445 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
446 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
447 if (!ends_excmd2(arg, skipwhite(p)))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
448 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
449 semsg(_(e_trailing_characters_str), p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
450 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
451 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
452 if (cctx->ctx_skip == SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
453 clear_ppconst(&ppconst);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
454 else if (instr->ga_len == instr_count && ppconst.pp_used == 1)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
455 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
456 int error = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
457 int v;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
458
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
459 // The expression results in a constant.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
460 v = tv_get_bool_chk(&ppconst.pp_tv[0], &error);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
461 clear_ppconst(&ppconst);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
462 if (error)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
463 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
464 cctx->ctx_skip = v ? SKIP_NOT : SKIP_YES;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
465 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
466 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
467 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
468 // Not a constant, generate instructions for the expression.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
469 cctx->ctx_skip = SKIP_UNKNOWN;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
470 if (generate_ppconst(cctx, &ppconst) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
471 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
472 if (bool_on_stack(cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
473 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
474 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
475
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
476 // CMDMOD_REV must come before the jump
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
477 generate_undo_cmdmods(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
478
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
479 scope = new_scope(cctx, IF_SCOPE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
480 if (scope == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
481 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
482 scope->se_skip_save = skip_save;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
483 // "is_had_return" will be reset if any block does not end in :return
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
484 scope->se_u.se_if.is_had_return = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
485
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
486 if (cctx->ctx_skip == SKIP_UNKNOWN)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
487 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
488 // "where" is set when ":elseif", "else" or ":endif" is found
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
489 scope->se_u.se_if.is_if_label = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
490 generate_JUMP(cctx, JUMP_IF_FALSE, 0);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
491 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
492 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
493 scope->se_u.se_if.is_if_label = -1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
494
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
495 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
496 if (cctx->ctx_compile_type == CT_PROFILE && cctx->ctx_skip == SKIP_YES
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
497 && skip_save != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
498 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
499 // generated a profile start, need to generate a profile end, since it
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
500 // won't be done after returning
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
501 cctx->ctx_skip = SKIP_NOT;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
502 generate_instr(cctx, ISN_PROF_END);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
503 cctx->ctx_skip = SKIP_YES;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
504 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
505 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
506
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
507 return p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
508 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
509
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
510 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
511 compile_elseif(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
512 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
513 char_u *p = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
514 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
515 int instr_count;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
516 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
517 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
518 ppconst_T ppconst;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
519 skip_T save_skip = cctx->ctx_skip;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
520
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
521 if (scope == NULL || scope->se_type != IF_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
522 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
523 emsg(_(e_elseif_without_if));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
524 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
525 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
526 unwind_locals(cctx, scope->se_local_count, TRUE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
527 if (!cctx->ctx_had_return)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
528 scope->se_u.se_if.is_had_return = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
529
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
530 if (cctx->ctx_skip == SKIP_NOT)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
531 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
532 // previous block was executed, this one and following will not
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
533 cctx->ctx_skip = SKIP_YES;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
534 scope->se_u.se_if.is_seen_skip_not = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
535 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
536 if (scope->se_u.se_if.is_seen_skip_not)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
537 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
538 // A previous block was executed, skip over expression and bail out.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
539 // Do not count the "elseif" for profiling and cmdmod
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
540 instr->ga_len = current_instr_idx(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
541
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
542 skip_expr_cctx(&p, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
543 return p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
544 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
545
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
546 if (cctx->ctx_skip == SKIP_UNKNOWN)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
547 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
548 int moved_cmdmod = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
549 int saved_debug = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
550 isn_T debug_isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
551
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
552 // Move any CMDMOD instruction to after the jump
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
553 if (((isn_T *)instr->ga_data)[instr->ga_len - 1].isn_type == ISN_CMDMOD)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
554 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
555 if (GA_GROW_FAILS(instr, 1))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
556 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
557 ((isn_T *)instr->ga_data)[instr->ga_len] =
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
558 ((isn_T *)instr->ga_data)[instr->ga_len - 1];
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
559 --instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
560 moved_cmdmod = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
561 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
562
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
563 // Remove the already generated ISN_DEBUG, it is written below the
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
564 // ISN_FOR instruction.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
565 if (cctx->ctx_compile_type == CT_DEBUG && instr->ga_len > 0
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
566 && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
567 .isn_type == ISN_DEBUG)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
568 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
569 --instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
570 debug_isn = ((isn_T *)instr->ga_data)[instr->ga_len];
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
571 saved_debug = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
572 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
573
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
574 if (compile_jump_to_end(&scope->se_u.se_if.is_end_label,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
575 JUMP_ALWAYS, 0, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
576 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
577 // previous "if" or "elseif" jumps here
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
578 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
579 isn->isn_arg.jump.jump_where = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
580
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
581 if (moved_cmdmod)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
582 ++instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
583
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
584 if (saved_debug)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
585 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
586 // move the debug instruction here
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
587 if (GA_GROW_FAILS(instr, 1))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
588 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
589 ((isn_T *)instr->ga_data)[instr->ga_len] = debug_isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
590 ++instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
591 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
592 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
593
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
594 // compile "expr"; if we know it evaluates to FALSE skip the block
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
595 CLEAR_FIELD(ppconst);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
596 if (cctx->ctx_skip == SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
597 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
598 cctx->ctx_skip = SKIP_UNKNOWN;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
599 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
600 if (cctx->ctx_compile_type == CT_PROFILE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
601 // the previous block was skipped, need to profile this line
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
602 generate_instr(cctx, ISN_PROF_START);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
603 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
604 if (cctx->ctx_compile_type == CT_DEBUG)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
605 // the previous block was skipped, may want to debug this line
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
606 generate_instr_debug(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
607 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
608
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
609 instr_count = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
610 if (compile_expr1(&p, cctx, &ppconst) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
611 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
612 clear_ppconst(&ppconst);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
613 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
614 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
615 cctx->ctx_skip = save_skip;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
616 if (!ends_excmd2(arg, skipwhite(p)))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
617 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
618 clear_ppconst(&ppconst);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
619 semsg(_(e_trailing_characters_str), p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
620 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
621 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
622 if (scope->se_skip_save == SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
623 clear_ppconst(&ppconst);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
624 else if (instr->ga_len == instr_count && ppconst.pp_used == 1)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
625 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
626 int error = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
627 int v;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
628
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
629 // The expression result is a constant.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
630 v = tv_get_bool_chk(&ppconst.pp_tv[0], &error);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
631 if (error)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
632 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
633 clear_ppconst(&ppconst);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
634 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
635 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
636 cctx->ctx_skip = v ? SKIP_NOT : SKIP_YES;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
637 clear_ppconst(&ppconst);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
638 scope->se_u.se_if.is_if_label = -1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
639 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
640 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
641 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
642 // Not a constant, generate instructions for the expression.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
643 cctx->ctx_skip = SKIP_UNKNOWN;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
644 if (generate_ppconst(cctx, &ppconst) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
645 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
646 if (bool_on_stack(cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
647 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
648
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
649 // CMDMOD_REV must come before the jump
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
650 generate_undo_cmdmods(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
651
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
652 // "where" is set when ":elseif", "else" or ":endif" is found
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
653 scope->se_u.se_if.is_if_label = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
654 generate_JUMP(cctx, JUMP_IF_FALSE, 0);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
655 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
656
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
657 return p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
658 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
659
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
660 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
661 compile_else(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
662 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
663 char_u *p = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
664 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
665 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
666 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
667
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
668 if (scope == NULL || scope->se_type != IF_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
669 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
670 emsg(_(e_else_without_if));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
671 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
672 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
673 unwind_locals(cctx, scope->se_local_count, TRUE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
674 if (!cctx->ctx_had_return)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
675 scope->se_u.se_if.is_had_return = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
676 scope->se_u.se_if.is_seen_else = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
677
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
678 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
679 if (cctx->ctx_compile_type == CT_PROFILE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
680 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
681 if (cctx->ctx_skip == SKIP_NOT
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
682 && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
683 .isn_type == ISN_PROF_START)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
684 // the previous block was executed, do not count "else" for
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
685 // profiling
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
686 --instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
687 if (cctx->ctx_skip == SKIP_YES && !scope->se_u.se_if.is_seen_skip_not)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
688 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
689 // the previous block was not executed, this one will, do count the
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
690 // "else" for profiling
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
691 cctx->ctx_skip = SKIP_NOT;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
692 generate_instr(cctx, ISN_PROF_END);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
693 generate_instr(cctx, ISN_PROF_START);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
694 cctx->ctx_skip = SKIP_YES;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
695 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
696 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
697 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
698
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
699 if (!scope->se_u.se_if.is_seen_skip_not && scope->se_skip_save != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
700 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
701 // jump from previous block to the end, unless the else block is empty
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
702 if (cctx->ctx_skip == SKIP_UNKNOWN)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
703 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
704 if (!cctx->ctx_had_return
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
705 && compile_jump_to_end(&scope->se_u.se_if.is_end_label,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
706 JUMP_ALWAYS, 0, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
707 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
708 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
709
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
710 if (cctx->ctx_skip == SKIP_UNKNOWN)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
711 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
712 if (scope->se_u.se_if.is_if_label >= 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
713 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
714 // previous "if" or "elseif" jumps here
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
715 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
716 isn->isn_arg.jump.jump_where = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
717 scope->se_u.se_if.is_if_label = -1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
718 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
719 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
720
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
721 if (cctx->ctx_skip != SKIP_UNKNOWN)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
722 cctx->ctx_skip = cctx->ctx_skip == SKIP_YES ? SKIP_NOT : SKIP_YES;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
723 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
724
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
725 return p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
726 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
727
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
728 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
729 compile_endif(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
730 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
731 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
732 ifscope_T *ifscope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
733 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
734 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
735
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
736 if (misplaced_cmdmod(cctx))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
737 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
738
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
739 if (scope == NULL || scope->se_type != IF_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
740 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
741 emsg(_(e_endif_without_if));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
742 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
743 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
744 ifscope = &scope->se_u.se_if;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
745 unwind_locals(cctx, scope->se_local_count, TRUE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
746 if (!cctx->ctx_had_return)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
747 ifscope->is_had_return = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
748
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
749 if (scope->se_u.se_if.is_if_label >= 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
750 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
751 // previous "if" or "elseif" jumps here
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
752 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
753 isn->isn_arg.jump.jump_where = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
754 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
755 // Fill in the "end" label in jumps at the end of the blocks.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
756 compile_fill_jump_to_end(&ifscope->is_end_label, instr->ga_len, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
757
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
758 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
759 // even when skipping we count the endif as executed, unless the block it's
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
760 // in is skipped
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
761 if (cctx->ctx_compile_type == CT_PROFILE && cctx->ctx_skip == SKIP_YES
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
762 && scope->se_skip_save != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
763 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
764 cctx->ctx_skip = SKIP_NOT;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
765 generate_instr(cctx, ISN_PROF_START);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
766 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
767 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
768 cctx->ctx_skip = scope->se_skip_save;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
769
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
770 // If all the blocks end in :return and there is an :else then the
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
771 // had_return flag is set.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
772 cctx->ctx_had_return = ifscope->is_had_return && ifscope->is_seen_else;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
773
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
774 drop_scope(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
775 return arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
776 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
777
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
778 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
779 * Save the info needed for ENDLOOP. Used by :for and :while.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
780 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
781 static void
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
782 compile_fill_loop_info(loop_info_T *loop_info, int funcref_idx, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
783 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
784 loop_info->li_funcref_idx = funcref_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
785 loop_info->li_local_count = cctx->ctx_locals.ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
786 loop_info->li_closure_count = cctx->ctx_closure_count;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
787 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
788
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
789 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
790 * Compile "for var in expr":
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
791 *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
792 * Produces instructions:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
793 * STORE -1 in loop-idx Set index to -1
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
794 * EVAL expr Result of "expr" on top of stack
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
795 * top: FOR loop-idx, end Increment index, use list on bottom of stack
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
796 * - if beyond end, jump to "end"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
797 * - otherwise get item from list and push it
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
798 * - store ec_funcrefs in var "loop-idx" + 1
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
799 * STORE var Store item in "var"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
800 * ... body ...
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
801 * ENDLOOP funcref-idx off count Only if closure uses local var
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
802 * JUMP top Jump back to repeat
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
803 * end: DROP Drop the result of "expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
804 *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
805 * Compile "for [var1, var2] in expr" - as above, but instead of "STORE var":
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
806 * UNPACK 2 Split item in 2
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
807 * STORE var1 Store item in "var1"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
808 * STORE var2 Store item in "var2"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
809 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
810 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
811 compile_for(char_u *arg_start, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
812 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
813 char_u *arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
814 char_u *arg_end;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
815 char_u *name = NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
816 char_u *p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
817 char_u *wp;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
818 int var_count = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
819 int var_list = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
820 int semicolon = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
821 size_t varlen;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
822 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
823 scope_T *scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
824 forscope_T *forscope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
825 lvar_T *loop_lvar; // loop iteration variable
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
826 int loop_lvar_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
827 lvar_T *funcref_lvar;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
828 int funcref_lvar_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
829 lvar_T *var_lvar; // variable for "var"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
830 type_T *vartype;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
831 type_T *item_type = &t_any;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
832 int idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
833 int prev_lnum = cctx->ctx_prev_lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
834
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
835 p = skip_var_list(arg_start, TRUE, &var_count, &semicolon, FALSE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
836 if (p == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
837 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
838 if (var_count == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
839 var_count = 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
840 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
841 var_list = TRUE; // can also be a list of one variable
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
842
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
843 // consume "in"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
844 wp = p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
845 if (may_get_next_line_error(wp, &p, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
846 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
847 if (STRNCMP(p, "in", 2) != 0 || !IS_WHITE_OR_NUL(p[2]))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
848 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
849 if (*p == ':' && wp != p)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
850 semsg(_(e_no_white_space_allowed_before_colon_str), p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
851 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
852 emsg(_(e_missing_in_after_for));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
853 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
854 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
855 wp = p + 2;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
856 if (may_get_next_line_error(wp, &p, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
857 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
858
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
859 // Find the already generated ISN_DEBUG to get the line number for the
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
860 // instruction written below the ISN_FOR instruction.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
861 if (cctx->ctx_compile_type == CT_DEBUG && instr->ga_len > 0
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
862 && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
863 .isn_type == ISN_DEBUG)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
864 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
865 prev_lnum = ((isn_T *)instr->ga_data)[instr->ga_len - 1]
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
866 .isn_arg.debug.dbg_break_lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
867 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
868
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
869 scope = new_scope(cctx, FOR_SCOPE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
870 if (scope == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
871 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
872 if (scope->se_loop_depth == MAX_LOOP_DEPTH)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
873 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
874 emsg(_(e_loop_nesting_too_deep));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
875 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
876 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
877 ++scope->se_loop_depth;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
878 forscope = &scope->se_u.se_for;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
879
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
880 // Reserve a variable to store the loop iteration counter and initialize it
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
881 // to -1.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
882 loop_lvar = reserve_local(cctx, (char_u *)"", 0, ASSIGN_VAR, &t_number);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
883 if (loop_lvar == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
884 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
885 drop_scope(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
886 return NULL; // out of memory
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
887 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
888 // get the index before a following reserve_local() makes the lval invalid
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
889 loop_lvar_idx = loop_lvar->lv_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
890 generate_STORENR(cctx, loop_lvar_idx, -1);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
891
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
892 // Reserve a variable to store ec_funcrefs.ga_len, used in ISN_ENDLOOP.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
893 // The variable index is always the loop var index plus one.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
894 // It is not used when no closures are encountered, we don't know yet.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
895 funcref_lvar = reserve_local(cctx, (char_u *)"", 0, ASSIGN_VAR, &t_number);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
896 if (funcref_lvar == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
897 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
898 drop_scope(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
899 return NULL; // out of memory
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
900 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
901 // get the index before a following reserve_local() makes the lval invalid
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
902 funcref_lvar_idx = funcref_lvar->lv_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
903
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
904 // compile "expr", it remains on the stack until "endfor"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
905 arg = p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
906 if (compile_expr0(&arg, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
907 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
908 drop_scope(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
909 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
910 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
911 arg_end = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
912
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
913 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
914 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
915 // If we know the type of "var" and it is not a supported type we can
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
916 // give an error now.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
917 vartype = get_type_on_stack(cctx, 0);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
918 if (vartype->tt_type != VAR_LIST
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
919 && vartype->tt_type != VAR_STRING
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
920 && vartype->tt_type != VAR_BLOB
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
921 && vartype->tt_type != VAR_ANY
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
922 && vartype->tt_type != VAR_UNKNOWN)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
923 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
924 semsg(_(e_for_loop_on_str_not_supported),
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
925 vartype_name(vartype->tt_type));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
926 drop_scope(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
927 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
928 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
929
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
930 if (vartype->tt_type == VAR_STRING)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
931 item_type = &t_string;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
932 else if (vartype->tt_type == VAR_BLOB)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
933 item_type = &t_number;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
934 else if (vartype->tt_type == VAR_LIST
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
935 && vartype->tt_member->tt_type != VAR_ANY)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
936 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
937 if (!var_list)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
938 item_type = vartype->tt_member;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
939 else if (vartype->tt_member->tt_type == VAR_LIST
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
940 && vartype->tt_member->tt_member->tt_type != VAR_ANY)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
941 item_type = vartype->tt_member->tt_member;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
942 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
943
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
944 // CMDMOD_REV must come before the FOR instruction.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
945 generate_undo_cmdmods(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
946
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
947 // "for_end" is set when ":endfor" is found
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
948 forscope->fs_top_label = current_instr_idx(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
949
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
950 if (cctx->ctx_compile_type == CT_DEBUG)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
951 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
952 int save_prev_lnum = cctx->ctx_prev_lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
953 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
954
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
955 // Add ISN_DEBUG here, before deciding to end the loop. There will
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
956 // be another ISN_DEBUG before the next instruction.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
957 // Use the prev_lnum from the ISN_DEBUG instruction removed above.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
958 // Increment the variable count so that the loop variable can be
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
959 // inspected.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
960 cctx->ctx_prev_lnum = prev_lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
961 isn = generate_instr_debug(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
962 ++isn->isn_arg.debug.dbg_var_names_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
963 cctx->ctx_prev_lnum = save_prev_lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
964 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
965
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
966 generate_FOR(cctx, loop_lvar_idx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
967
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
968 arg = arg_start;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
969 if (var_list)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
970 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
971 generate_UNPACK(cctx, var_count, semicolon);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
972 arg = skipwhite(arg + 1); // skip white after '['
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
973
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
974 // drop the list item
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
975 --cctx->ctx_type_stack.ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
976
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
977 // add type of the items
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
978 for (idx = 0; idx < var_count; ++idx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
979 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
980 type_T *type = (semicolon && idx == 0) ? vartype : item_type;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
981
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
982 if (push_type_stack(cctx, type) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
983 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
984 drop_scope(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
985 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
986 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
987 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
988 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
989
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
990 for (idx = 0; idx < var_count; ++idx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
991 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
992 assign_dest_T dest = dest_local;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
993 int opt_flags = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
994 int vimvaridx = -1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
995 type_T *type = &t_any;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
996 type_T *lhs_type = &t_any;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
997 where_T where = WHERE_INIT;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
998
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
999 p = skip_var_one(arg, FALSE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1000 varlen = p - arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1001 name = vim_strnsave(arg, varlen);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1002 if (name == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1003 goto failed;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1004 if (*skipwhite(p) == ':')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1005 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1006 if (VIM_ISWHITE(*p))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1007 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1008 semsg(_(e_no_white_space_allowed_before_colon_str), p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1009 goto failed;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1010 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1011 p = skipwhite(p + 1);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1012 lhs_type = parse_type(&p, cctx->ctx_type_list, TRUE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1013 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1014
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1015 if (get_var_dest(name, &dest, CMD_for, &opt_flags,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1016 &vimvaridx, &type, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1017 goto failed;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1018 if (dest != dest_local)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1019 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1020 if (generate_store_var(cctx, dest, opt_flags, vimvaridx,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1021 type, name, NULL) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1022 goto failed;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1023 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1024 else if (varlen == 1 && *arg == '_')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1025 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1026 // Assigning to "_": drop the value.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1027 if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1028 goto failed;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1029 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1030 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1031 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1032 // Script var is not supported.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1033 if (STRNCMP(name, "s:", 2) == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1034 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1035 emsg(_(e_cannot_use_script_variable_in_for_loop));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1036 goto failed;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1037 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1038
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1039 if (!valid_varname(arg, (int)varlen, FALSE))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1040 goto failed;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1041 if (lookup_local(arg, varlen, NULL, cctx) == OK)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1042 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1043 semsg(_(e_variable_already_declared_str), arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1044 goto failed;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1045 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1046
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1047 // Reserve a variable to store "var".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1048 where.wt_index = var_list ? idx + 1 : 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1049 where.wt_variable = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1050 if (lhs_type == &t_any)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1051 lhs_type = item_type;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1052 else if (item_type != &t_unknown
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1053 && need_type_where(item_type, lhs_type, FALSE, -1,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1054 where, cctx, FALSE, FALSE) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1055 goto failed;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1056 var_lvar = reserve_local(cctx, arg, varlen, ASSIGN_FINAL,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1057 lhs_type);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1058 if (var_lvar == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1059 // out of memory or used as an argument
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1060 goto failed;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1061
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1062 if (semicolon && idx == var_count - 1)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1063 var_lvar->lv_type = vartype;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1064 generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1065 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1066
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1067 if (*p == ',' || *p == ';')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1068 ++p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1069 arg = skipwhite(p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1070 vim_free(name);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1071 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1072
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1073 // remember the number of variables and closures, used for ENDLOOP
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1074 compile_fill_loop_info(&forscope->fs_loop_info, funcref_lvar_idx, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1075 forscope->fs_loop_info.li_depth = scope->se_loop_depth - 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1076 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1077
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1078 return arg_end;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1079
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1080 failed:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1081 vim_free(name);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1082 drop_scope(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1083 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1084 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1085
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1086 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1087 * Used when ending a loop of :for and :while: Generate an ISN_ENDLOOP
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1088 * instruction if any variable was declared that could be used by a new
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1089 * closure.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1090 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1091 static int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1092 compile_loop_end(loop_info_T *loop_info, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1093 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1094 if (cctx->ctx_locals.ga_len > loop_info->li_local_count
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1095 && cctx->ctx_closure_count > loop_info->li_closure_count)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1096 return generate_ENDLOOP(cctx, loop_info);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1097 return OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1098 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1099
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1100 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1101 * compile "endfor"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1102 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1103 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1104 compile_endfor(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1105 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1106 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1107 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1108 forscope_T *forscope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1109 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1110
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1111 if (misplaced_cmdmod(cctx))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1112 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1113
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1114 if (scope == NULL || scope->se_type != FOR_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1115 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1116 emsg(_(e_endfor_without_for));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1117 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1118 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1119 forscope = &scope->se_u.se_for;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1120 cctx->ctx_scope = scope->se_outer;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1121 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1122 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1123 // Handle the case that any local variables were declared that might be
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1124 // used in a closure.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1125 if (compile_loop_end(&forscope->fs_loop_info, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1126 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1127
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1128 unwind_locals(cctx, scope->se_local_count, FALSE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1129
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1130 // At end of ":for" scope jump back to the FOR instruction.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1131 generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1132
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1133 // Fill in the "end" label in the FOR statement so it can jump here.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1134 // In debug mode an ISN_DEBUG was inserted.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1135 isn = ((isn_T *)instr->ga_data) + forscope->fs_top_label
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1136 + (cctx->ctx_compile_type == CT_DEBUG ? 1 : 0);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1137 isn->isn_arg.forloop.for_end = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1138
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1139 // Fill in the "end" label any BREAK statements
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1140 compile_fill_jump_to_end(&forscope->fs_end_label, instr->ga_len, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1141
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1142 // Below the ":for" scope drop the "expr" list from the stack.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1143 if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1144 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1145 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1146
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1147 vim_free(scope);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1148
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1149 return arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1150 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1151
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1152 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1153 * compile "while expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1154 *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1155 * Produces instructions:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1156 * top: EVAL expr Push result of "expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1157 * WHILE funcref-idx end Jump if false
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1158 * ... body ...
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1159 * ENDLOOP funcref-idx off count only if closure uses local var
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1160 * JUMP top Jump back to repeat
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1161 * end:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1162 *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1163 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1164 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1165 compile_while(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1166 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1167 char_u *p = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1168 scope_T *scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1169 whilescope_T *whilescope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1170 lvar_T *funcref_lvar;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1171 int funcref_lvar_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1172
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1173 scope = new_scope(cctx, WHILE_SCOPE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1174 if (scope == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1175 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1176 if (scope->se_loop_depth == MAX_LOOP_DEPTH)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1177 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1178 emsg(_(e_loop_nesting_too_deep));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1179 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1180 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1181 ++scope->se_loop_depth;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1182 whilescope = &scope->se_u.se_while;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1183
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1184 // "endwhile" jumps back here, one before when profiling or using cmdmods
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1185 whilescope->ws_top_label = current_instr_idx(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1186
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1187 // Reserve a variable to store ec_funcrefs.ga_len, used in ISN_ENDLOOP.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1188 // It is not used when no closures are encountered, we don't know yet.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1189 funcref_lvar = reserve_local(cctx, (char_u *)"", 0, ASSIGN_VAR, &t_number);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1190 if (funcref_lvar == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1191 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1192 drop_scope(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1193 return NULL; // out of memory
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1194 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1195 // get the index before a following reserve_local() makes the lval invalid
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1196 funcref_lvar_idx = funcref_lvar->lv_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1197
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1198 // remember the number of variables and closures, used for ENDLOOP
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1199 compile_fill_loop_info(&whilescope->ws_loop_info, funcref_lvar_idx, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1200 whilescope->ws_loop_info.li_depth = scope->se_loop_depth - 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1201
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1202 // compile "expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1203 if (compile_expr0(&p, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1204 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1205
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1206 if (!ends_excmd2(arg, skipwhite(p)))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1207 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1208 semsg(_(e_trailing_characters_str), p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1209 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1210 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1211
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1212 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1213 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1214 if (bool_on_stack(cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1215 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1216
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1217 // CMDMOD_REV must come before the jump
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1218 generate_undo_cmdmods(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1219
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1220 // "while_end" is set when ":endwhile" is found
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1221 if (compile_jump_to_end(&whilescope->ws_end_label,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1222 JUMP_WHILE_FALSE, funcref_lvar_idx, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1223 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1224 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1225
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1226 return p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1227 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1228
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1229 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1230 * compile "endwhile"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1231 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1232 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1233 compile_endwhile(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1234 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1235 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1236 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1237
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1238 if (misplaced_cmdmod(cctx))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1239 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1240 if (scope == NULL || scope->se_type != WHILE_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1241 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1242 emsg(_(e_endwhile_without_while));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1243 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1244 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1245 cctx->ctx_scope = scope->se_outer;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1246 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1247 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1248 whilescope_T *whilescope = &scope->se_u.se_while;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1249
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1250 // Handle the case that any local variables were declared that might be
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1251 // used in a closure.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1252 if (compile_loop_end(&whilescope->ws_loop_info, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1253 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1254
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1255 unwind_locals(cctx, scope->se_local_count, FALSE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1256
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1257 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1258 // count the endwhile before jumping
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1259 may_generate_prof_end(cctx, cctx->ctx_lnum);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1260 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1261
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1262 // At end of ":for" scope jump back to the FOR instruction.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1263 generate_JUMP(cctx, JUMP_ALWAYS, scope->se_u.se_while.ws_top_label);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1264
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1265 // Fill in the "end" label in the WHILE statement so it can jump here.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1266 // And in any jumps for ":break"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1267 compile_fill_jump_to_end(&scope->se_u.se_while.ws_end_label,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1268 instr->ga_len, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1269 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1270
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1271 vim_free(scope);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1272
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1273 return arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1274 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1275
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1276 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1277 * Get the current information about variables declared inside a loop.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1278 * Returns TRUE if there are any and fills "lvi".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1279 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1280 int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1281 get_loop_var_info(cctx_T *cctx, loopvarinfo_T *lvi)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1282 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1283 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1284 int prev_local_count = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1285
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1286 CLEAR_POINTER(lvi);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1287 for (;;)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1288 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1289 loop_info_T *loopinfo;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1290 int cur_local_last;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1291 int start_local_count;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1292
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1293 while (scope != NULL && scope->se_type != WHILE_SCOPE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1294 && scope->se_type != FOR_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1295 scope = scope->se_outer;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1296 if (scope == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1297 break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1298
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1299 if (scope->se_type == WHILE_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1300 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1301 loopinfo = &scope->se_u.se_while.ws_loop_info;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1302 // :while reserves one variable for funcref count
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1303 cur_local_last = loopinfo->li_local_count - 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1304 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1305 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1306 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1307 loopinfo = &scope->se_u.se_for.fs_loop_info;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1308 // :for reserves three variable: loop count, funcref count and loop
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1309 // var
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1310 cur_local_last = loopinfo->li_local_count - 3;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1311 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1312
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1313 start_local_count = loopinfo->li_local_count;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1314 if (cctx->ctx_locals.ga_len > start_local_count)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1315 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1316 lvi->lvi_loop[loopinfo->li_depth].var_idx =
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1317 (short)start_local_count;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1318 lvi->lvi_loop[loopinfo->li_depth].var_count =
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1319 (short)(cctx->ctx_locals.ga_len - start_local_count
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1320 - prev_local_count);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1321 if (lvi->lvi_depth == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1322 lvi->lvi_depth = loopinfo->li_depth + 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1323 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1324
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1325 scope = scope->se_outer;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1326 prev_local_count = cctx->ctx_locals.ga_len - cur_local_last;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1327 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1328 return lvi->lvi_depth > 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1329 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1330
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1331 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1332 * Get the index of the variable "idx" in a loop, if any.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1333 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1334 void
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1335 get_loop_var_idx(cctx_T *cctx, int idx, lvar_T *lvar)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1336 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1337 loopvarinfo_T lvi;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1338
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1339 lvar->lv_loop_depth = -1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1340 lvar->lv_loop_idx = -1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1341 if (get_loop_var_info(cctx, &lvi))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1342 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1343 int depth;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1344
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1345 for (depth = lvi.lvi_depth - 1; depth >= 0; --depth)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1346 if (idx >= lvi.lvi_loop[depth].var_idx
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1347 && idx < lvi.lvi_loop[depth].var_idx
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1348 + lvi.lvi_loop[depth].var_count)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1349 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1350 lvar->lv_loop_depth = depth;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1351 lvar->lv_loop_idx = lvi.lvi_loop[depth].var_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1352 return;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1353 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1354 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1355 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1356
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1357 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1358 * Common for :break, :continue and :return
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1359 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1360 static int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1361 compile_find_scope(
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1362 int *loop_label, // where to jump to or NULL
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1363 endlabel_T ***el, // end label or NULL
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1364 int *try_scopes, // :try scopes encountered or NULL
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1365 char *error, // error to use when no scope found
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1366 cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1367 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1368 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1369
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1370 for (;;)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1371 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1372 if (scope == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1373 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1374 if (error != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1375 emsg(_(error));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1376 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1377 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1378 if (scope->se_type == FOR_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1379 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1380 if (compile_loop_end(&scope->se_u.se_for.fs_loop_info, cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1381 == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1382 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1383 if (loop_label != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1384 *loop_label = scope->se_u.se_for.fs_top_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1385 if (el != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1386 *el = &scope->se_u.se_for.fs_end_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1387 break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1388 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1389 if (scope->se_type == WHILE_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1390 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1391 if (compile_loop_end(&scope->se_u.se_while.ws_loop_info, cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1392 == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1393 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1394 if (loop_label != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1395 *loop_label = scope->se_u.se_while.ws_top_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1396 if (el != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1397 *el = &scope->se_u.se_while.ws_end_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1398 break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1399 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1400 if (try_scopes != NULL && scope->se_type == TRY_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1401 ++*try_scopes;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1402 scope = scope->se_outer;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1403 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1404 return OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1405 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1406
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1407 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1408 * compile "continue"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1409 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1410 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1411 compile_continue(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1412 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1413 int try_scopes = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1414 int loop_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1415
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1416 if (compile_find_scope(&loop_label, NULL, &try_scopes,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1417 e_continue_without_while_or_for, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1418 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1419 if (try_scopes > 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1420 // Inside one or more try/catch blocks we first need to jump to the
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1421 // "finally" or "endtry" to cleanup.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1422 generate_TRYCONT(cctx, try_scopes, loop_label);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1423 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1424 // Jump back to the FOR or WHILE instruction.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1425 generate_JUMP(cctx, JUMP_ALWAYS, loop_label);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1426
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1427 return arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1428 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1429
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1430 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1431 * compile "break"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1432 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1433 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1434 compile_break(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1435 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1436 int try_scopes = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1437 endlabel_T **el;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1438
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1439 if (compile_find_scope(NULL, &el, &try_scopes,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1440 e_break_without_while_or_for, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1441 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1442
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1443 if (cctx->ctx_skip == SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1444 return arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1445
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1446 if (try_scopes > 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1447 // Inside one or more try/catch blocks we first need to jump to the
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1448 // "finally" or "endtry" to cleanup. Then come to the next JUMP
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1449 // instruction, which we don't know the index of yet.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1450 generate_TRYCONT(cctx, try_scopes, cctx->ctx_instr.ga_len + 1);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1451
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1452 // Jump to the end of the FOR or WHILE loop. The instruction index will be
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1453 // filled in later.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1454 if (compile_jump_to_end(el, JUMP_ALWAYS, 0, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1455 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1456
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1457 return arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1458 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1459
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1460 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1461 * compile "{" start of block
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1462 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1463 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1464 compile_block(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1465 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1466 if (new_scope(cctx, BLOCK_SCOPE) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1467 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1468 return skipwhite(arg + 1);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1469 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1470
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1471 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1472 * compile end of block: drop one scope
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1473 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1474 void
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1475 compile_endblock(cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1476 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1477 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1478
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1479 cctx->ctx_scope = scope->se_outer;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1480 unwind_locals(cctx, scope->se_local_count, TRUE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1481 vim_free(scope);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1482 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1483
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1484 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1485 * Compile "try".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1486 * Creates a new scope for the try-endtry, pointing to the first catch and
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1487 * finally.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1488 * Creates another scope for the "try" block itself.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1489 * TRY instruction sets up exception handling at runtime.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1490 *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1491 * "try"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1492 * TRY -> catch1, -> finally push trystack entry
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1493 * ... try block
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1494 * "throw {exception}"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1495 * EVAL {exception}
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1496 * THROW create exception
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1497 * ... try block
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1498 * " catch {expr}"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1499 * JUMP -> finally
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1500 * catch1: PUSH exception
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1501 * EVAL {expr}
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1502 * MATCH
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1503 * JUMP nomatch -> catch2
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1504 * CATCH remove exception
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1505 * ... catch block
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1506 * " catch"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1507 * JUMP -> finally
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1508 * catch2: CATCH remove exception
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1509 * ... catch block
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1510 * " finally"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1511 * finally:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1512 * ... finally block
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1513 * " endtry"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1514 * ENDTRY pop trystack entry, may rethrow
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1515 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1516 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1517 compile_try(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1518 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1519 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1520 scope_T *try_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1521 scope_T *scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1522
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1523 if (misplaced_cmdmod(cctx))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1524 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1525
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1526 // scope that holds the jumps that go to catch/finally/endtry
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1527 try_scope = new_scope(cctx, TRY_SCOPE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1528 if (try_scope == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1529 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1530
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1531 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1532 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1533 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1534
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1535 // "try_catch" is set when the first ":catch" is found or when no catch
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1536 // is found and ":finally" is found.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1537 // "try_finally" is set when ":finally" is found
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1538 // "try_endtry" is set when ":endtry" is found
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1539 try_scope->se_u.se_try.ts_try_label = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1540 if ((isn = generate_instr(cctx, ISN_TRY)) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1541 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1542 isn->isn_arg.tryref.try_ref = ALLOC_CLEAR_ONE(tryref_T);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1543 if (isn->isn_arg.tryref.try_ref == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1544 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1545 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1546
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1547 // scope for the try block itself
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1548 scope = new_scope(cctx, BLOCK_SCOPE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1549 if (scope == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1550 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1551
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1552 return arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1553 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1554
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1555 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1556 * Compile "catch {expr}".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1557 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1558 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1559 compile_catch(char_u *arg, cctx_T *cctx UNUSED)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1560 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1561 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1562 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1563 char_u *p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1564 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1565
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1566 if (misplaced_cmdmod(cctx))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1567 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1568
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1569 // end block scope from :try or :catch
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1570 if (scope != NULL && scope->se_type == BLOCK_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1571 compile_endblock(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1572 scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1573
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1574 // Error if not in a :try scope
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1575 if (scope == NULL || scope->se_type != TRY_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1576 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1577 emsg(_(e_catch_without_try));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1578 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1579 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1580
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1581 if (scope->se_u.se_try.ts_caught_all
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1582 && !ignore_unreachable_code_for_testing)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1583 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1584 emsg(_(e_catch_unreachable_after_catch_all));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1585 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1586 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1587 if (!cctx->ctx_had_return)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1588 scope->se_u.se_try.ts_no_return = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1589
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1590 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1591 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1592 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1593 // the profile-start should be after the jump
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1594 if (cctx->ctx_compile_type == CT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1595 && instr->ga_len > 0
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1596 && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1597 .isn_type == ISN_PROF_START)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1598 --instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1599 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1600 // Jump from end of previous block to :finally or :endtry
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1601 if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1602 JUMP_ALWAYS, 0, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1603 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1604
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1605 // End :try or :catch scope: set value in ISN_TRY instruction
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1606 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1607 if (isn->isn_arg.tryref.try_ref->try_catch == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1608 isn->isn_arg.tryref.try_ref->try_catch = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1609 if (scope->se_u.se_try.ts_catch_label != 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1610 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1611 // Previous catch without match jumps here
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1612 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1613 isn->isn_arg.jump.jump_where = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1614 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1615 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1616 if (cctx->ctx_compile_type == CT_PROFILE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1617 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1618 // a "throw" that jumps here needs to be counted
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1619 generate_instr(cctx, ISN_PROF_END);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1620 // the "catch" is also counted
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1621 generate_instr(cctx, ISN_PROF_START);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1622 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1623 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1624 if (cctx->ctx_compile_type == CT_DEBUG)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1625 generate_instr_debug(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1626 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1627
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1628 p = skipwhite(arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1629 if (ends_excmd2(arg, p))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1630 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1631 scope->se_u.se_try.ts_caught_all = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1632 scope->se_u.se_try.ts_catch_label = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1633 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1634 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1635 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1636 char_u *end;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1637 char_u *pat;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1638 char_u *tofree = NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1639 int dropped = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1640 int len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1641
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1642 // Push v:exception, push {expr} and MATCH
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1643 generate_instr_type(cctx, ISN_PUSHEXC, &t_string);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1644
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1645 end = skip_regexp_ex(p + 1, *p, TRUE, &tofree, &dropped, NULL);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1646 if (*end != *p)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1647 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1648 semsg(_(e_separator_mismatch_str), p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1649 vim_free(tofree);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1650 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1651 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1652 if (tofree == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1653 len = (int)(end - (p + 1));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1654 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1655 len = (int)(end - tofree);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1656 pat = vim_strnsave(tofree == NULL ? p + 1 : tofree, len);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1657 vim_free(tofree);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1658 p += len + 2 + dropped;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1659 if (pat == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1660 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1661 if (generate_PUSHS(cctx, &pat) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1662 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1663
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1664 if (generate_COMPARE(cctx, EXPR_MATCH, FALSE) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1665 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1666
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1667 scope->se_u.se_try.ts_catch_label = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1668 if (generate_JUMP(cctx, JUMP_IF_FALSE, 0) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1669 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1670 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1671
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1672 if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_CATCH) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1673 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1674
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1675 if (new_scope(cctx, BLOCK_SCOPE) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1676 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1677 return p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1678 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1679
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1680 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1681 compile_finally(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1682 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1683 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1684 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1685 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1686 int this_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1687
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1688 if (misplaced_cmdmod(cctx))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1689 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1690
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1691 // end block scope from :try or :catch
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1692 if (scope != NULL && scope->se_type == BLOCK_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1693 compile_endblock(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1694 scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1695
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1696 // Error if not in a :try scope
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1697 if (scope == NULL || scope->se_type != TRY_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1698 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1699 emsg(_(e_finally_without_try));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1700 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1701 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1702
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1703 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1704 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1705 // End :catch or :finally scope: set value in ISN_TRY instruction
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1706 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1707 if (isn->isn_arg.tryref.try_ref->try_finally != 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1708 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1709 emsg(_(e_multiple_finally));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1710 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1711 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1712
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1713 this_instr = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1714 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1715 if (cctx->ctx_compile_type == CT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1716 && ((isn_T *)instr->ga_data)[this_instr - 1]
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1717 .isn_type == ISN_PROF_START)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1718 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1719 // jump to the profile start of the "finally"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1720 --this_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1721
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1722 // jump to the profile end above it
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1723 if (this_instr > 0 && ((isn_T *)instr->ga_data)[this_instr - 1]
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1724 .isn_type == ISN_PROF_END)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1725 --this_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1726 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1727 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1728
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1729 // Fill in the "end" label in jumps at the end of the blocks.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1730 compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1731 this_instr, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1732
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1733 // If there is no :catch then an exception jumps to :finally.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1734 if (isn->isn_arg.tryref.try_ref->try_catch == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1735 isn->isn_arg.tryref.try_ref->try_catch = this_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1736 isn->isn_arg.tryref.try_ref->try_finally = this_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1737 if (scope->se_u.se_try.ts_catch_label != 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1738 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1739 // Previous catch without match jumps here
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1740 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1741 isn->isn_arg.jump.jump_where = this_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1742 scope->se_u.se_try.ts_catch_label = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1743 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1744 scope->se_u.se_try.ts_has_finally = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1745 if (generate_instr(cctx, ISN_FINALLY) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1746 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1747 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1748
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1749 return arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1750 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1751
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1752 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1753 compile_endtry(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1754 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1755 scope_T *scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1756 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1757 isn_T *try_isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1758
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1759 if (misplaced_cmdmod(cctx))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1760 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1761
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1762 // end block scope from :catch or :finally
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1763 if (scope != NULL && scope->se_type == BLOCK_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1764 compile_endblock(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1765 scope = cctx->ctx_scope;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1766
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1767 // Error if not in a :try scope
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1768 if (scope == NULL || scope->se_type != TRY_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1769 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1770 if (scope == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1771 emsg(_(e_endtry_without_try));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1772 else if (scope->se_type == WHILE_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1773 emsg(_(e_missing_endwhile));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1774 else if (scope->se_type == FOR_SCOPE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1775 emsg(_(e_missing_endfor));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1776 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1777 emsg(_(e_missing_endif));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1778 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1779 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1780
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1781 try_isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1782 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1783 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1784 if (try_isn->isn_arg.tryref.try_ref->try_catch == 0
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1785 && try_isn->isn_arg.tryref.try_ref->try_finally == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1786 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1787 emsg(_(e_missing_catch_or_finally));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1788 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1789 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1790
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1791 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1792 if (cctx->ctx_compile_type == CT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1793 && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1794 .isn_type == ISN_PROF_START)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1795 // move the profile start after "endtry" so that it's not counted when
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1796 // the exception is rethrown.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1797 --instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1798 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1799
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1800 // Fill in the "end" label in jumps at the end of the blocks, if not
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1801 // done by ":finally".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1802 compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1803 instr->ga_len, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1804
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1805 if (scope->se_u.se_try.ts_catch_label != 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1806 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1807 // Last catch without match jumps here
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1808 isn_T *isn = ((isn_T *)instr->ga_data)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1809 + scope->se_u.se_try.ts_catch_label;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1810 isn->isn_arg.jump.jump_where = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1811 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1812 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1813
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1814 // If there is a finally clause that ends in return then we will return.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1815 // If one of the blocks didn't end in "return" or we did not catch all
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1816 // exceptions reset the had_return flag.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1817 if (!(scope->se_u.se_try.ts_has_finally && cctx->ctx_had_return)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1818 && (scope->se_u.se_try.ts_no_return
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1819 || !scope->se_u.se_try.ts_caught_all))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1820 cctx->ctx_had_return = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1821
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1822 compile_endblock(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1823
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1824 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1825 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1826 // End :catch or :finally scope: set instruction index in ISN_TRY
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1827 // instruction
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1828 try_isn->isn_arg.tryref.try_ref->try_endtry = instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1829 if (generate_instr(cctx, ISN_ENDTRY) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1830 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1831 #ifdef FEAT_PROFILE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1832 if (cctx->ctx_compile_type == CT_PROFILE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1833 generate_instr(cctx, ISN_PROF_START);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1834 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1835 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1836 return arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1837 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1838
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1839 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1840 * compile "throw {expr}"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1841 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1842 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1843 compile_throw(char_u *arg, cctx_T *cctx UNUSED)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1844 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1845 char_u *p = skipwhite(arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1846
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1847 if (compile_expr0(&p, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1848 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1849 if (cctx->ctx_skip == SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1850 return p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1851 if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1852 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1853 if (generate_instr_drop(cctx, ISN_THROW, 1) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1854 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1855
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1856 return p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1857 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1858
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1859 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1860 * Compile an expression or function call.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1861 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1862 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1863 compile_eval(char_u *arg, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1864 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1865 char_u *p = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1866 int name_only;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1867 long lnum = SOURCING_LNUM;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1868
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1869 // find_ex_command() will consider a variable name an expression, assuming
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1870 // that something follows on the next line. Check that something actually
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1871 // follows, otherwise it's probably a misplaced command.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1872 name_only = cmd_is_name_only(arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1873
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1874 if (compile_expr0(&p, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1875 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1876
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1877 if (name_only && lnum == SOURCING_LNUM)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1878 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1879 semsg(_(e_expression_without_effect_str), arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1880 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1881 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1882
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1883 // drop the result
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1884 generate_instr_drop(cctx, ISN_DROP, 1);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1885
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1886 return skipwhite(p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1887 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1888
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1889 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1890 * Get the local variable index for deferred function calls.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1891 * Reserve it when not done already.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1892 * Returns zero for failure.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1893 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1894 int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1895 get_defer_var_idx(cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1896 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1897 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1898 + cctx->ctx_ufunc->uf_dfunc_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1899 if (dfunc->df_defer_var_idx == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1900 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1901 lvar_T *lvar = reserve_local(cctx, (char_u *)"@defer@", 7,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1902 TRUE, &t_list_any);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1903 if (lvar == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1904 return 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1905 dfunc->df_defer_var_idx = lvar->lv_idx + 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1906 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1907 return dfunc->df_defer_var_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1908 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1909
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1910 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1911 * Compile "defer func(arg)".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1912 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1913 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1914 compile_defer(char_u *arg_start, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1915 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1916 char_u *paren;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1917 char_u *arg = arg_start;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1918 int argcount = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1919 int defer_var_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1920 type_T *type;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1921 int func_idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1922 int obj_method = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1923
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1924 // Get a funcref for the function name.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1925 // TODO: better way to find the "(".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1926 paren = vim_strchr(arg, '(');
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1927 if (paren == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1928 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1929 semsg(_(e_missing_parenthesis_str), arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1930 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1931 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1932 *paren = NUL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1933 func_idx = find_internal_func(arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1934 if (func_idx >= 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1935 // TODO: better type
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1936 generate_PUSHFUNC(cctx, (char_u *)internal_func_name(func_idx),
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1937 &t_func_any, FALSE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1938 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1939 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1940 int typecount = cctx->ctx_type_stack.ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1941 if (compile_expr0(&arg, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1942 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1943 if (cctx->ctx_type_stack.ga_len >= typecount + 2)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1944 // must have seen "obj.Func", pushed an object and a function
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1945 obj_method = 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1946 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1947 *paren = '(';
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1948
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1949 // check for function type
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1950 type = get_type_on_stack(cctx, 0);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1951 if (type->tt_type != VAR_FUNC)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1952 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1953 emsg(_(e_function_name_required));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1954 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1955 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1956
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1957 // compile the arguments
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1958 arg = skipwhite(paren + 1);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1959 if (compile_arguments(&arg, cctx, &argcount, CA_NOT_SPECIAL) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1960 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1961
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1962 if (func_idx >= 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1963 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1964 type2_T *argtypes = NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1965 type2_T shuffled_argtypes[MAX_FUNC_ARGS];
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1966
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1967 if (check_internal_func_args(cctx, func_idx, argcount, FALSE,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1968 &argtypes, shuffled_argtypes) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1969 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1970 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1971 else if (check_func_args_from_type(cctx, type, argcount, TRUE,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1972 arg_start) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1973 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1974
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1975 defer_var_idx = get_defer_var_idx(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1976 if (defer_var_idx == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1977 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1978 if (generate_DEFER(cctx, defer_var_idx - 1, obj_method, argcount) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1979 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1980
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1981 return skipwhite(arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1982 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1983
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1984 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1985 * compile "echo expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1986 * compile "echomsg expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1987 * compile "echoerr expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1988 * compile "echoconsole expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1989 * compile "echowindow expr" - may have cmd_count set
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1990 * compile "execute expr"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1991 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1992 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1993 compile_mult_expr(
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1994 char_u *arg,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1995 int cmdidx,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1996 long cmd_count UNUSED,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1997 cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1998 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
1999 char_u *p = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2000 char_u *prev = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2001 char_u *expr_start;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2002 int count = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2003 int start_ctx_lnum = cctx->ctx_lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2004 type_T *type;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2005 int r = OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2006
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2007 for (;;)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2008 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2009 if (ends_excmd2(prev, p))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2010 break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2011 expr_start = p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2012 if (compile_expr0(&p, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2013 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2014
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2015 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2016 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2017 // check for non-void type
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2018 type = get_type_on_stack(cctx, 0);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2019 if (type->tt_type == VAR_VOID)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2020 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2021 semsg(_(e_expression_does_not_result_in_value_str), expr_start);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2022 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2023 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2024 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2025
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2026 ++count;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2027 prev = p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2028 p = skipwhite(p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2029 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2030
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2031 if (count > 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2032 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2033 long save_lnum = cctx->ctx_lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2034
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2035 // Use the line number where the command started.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2036 cctx->ctx_lnum = start_ctx_lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2037
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2038 if (cmdidx == CMD_echo || cmdidx == CMD_echon)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2039 r = generate_ECHO(cctx, cmdidx == CMD_echo, count);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2040 else if (cmdidx == CMD_execute)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2041 r = generate_MULT_EXPR(cctx, ISN_EXECUTE, count);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2042 else if (cmdidx == CMD_echomsg)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2043 r = generate_MULT_EXPR(cctx, ISN_ECHOMSG, count);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2044 #ifdef HAS_MESSAGE_WINDOW
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2045 else if (cmdidx == CMD_echowindow)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2046 r = generate_ECHOWINDOW(cctx, count, cmd_count);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2047 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2048 else if (cmdidx == CMD_echoconsole)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2049 r = generate_MULT_EXPR(cctx, ISN_ECHOCONSOLE, count);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2050 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2051 r = generate_MULT_EXPR(cctx, ISN_ECHOERR, count);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2052
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2053 cctx->ctx_lnum = save_lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2054 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2055 return r == OK ? p : NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2056 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2057
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2058 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2059 * If "eap" has a range that is not a constant generate an ISN_RANGE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2060 * instruction to compute it and return OK.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2061 * Otherwise return FAIL, the caller must deal with any range.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2062 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2063 static int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2064 compile_variable_range(exarg_T *eap, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2065 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2066 char_u *range_end = skip_range(eap->cmd, TRUE, NULL);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2067 char_u *p = skipdigits(eap->cmd);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2068
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2069 if (p == range_end)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2070 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2071 return generate_RANGE(cctx, vim_strnsave(eap->cmd, range_end - eap->cmd));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2072 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2073
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2074 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2075 * :put r
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2076 * :put ={expr}
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2077 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2078 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2079 compile_put(char_u *arg, exarg_T *eap, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2080 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2081 char_u *line = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2082 linenr_T lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2083 char *errormsg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2084 int above = eap->forceit;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2085
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2086 eap->regname = *line;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2087
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2088 if (eap->regname == '=')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2089 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2090 char_u *p = skipwhite(line + 1);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2091
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2092 if (compile_expr0(&p, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2093 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2094 line = p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2095 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2096 else if (eap->regname != NUL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2097 ++line;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2098
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2099 if (compile_variable_range(eap, cctx) == OK)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2100 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2101 lnum = above ? LNUM_VARIABLE_RANGE_ABOVE : LNUM_VARIABLE_RANGE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2102 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2103 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2104 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2105 // Either no range or a number.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2106 // "errormsg" will not be set because the range is ADDR_LINES.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2107 if (parse_cmd_address(eap, &errormsg, FALSE) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2108 // cannot happen
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2109 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2110 if (eap->addr_count == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2111 lnum = -1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2112 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2113 lnum = eap->line2;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2114 if (above)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2115 --lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2116 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2117
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2118 generate_PUT(cctx, eap->regname, lnum);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2119 return line;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2120 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2121
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2122 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2123 * A command that is not compiled, execute with legacy code.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2124 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2125 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2126 compile_exec(char_u *line_arg, exarg_T *eap, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2127 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2128 char_u *line = line_arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2129 char_u *p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2130 int has_expr = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2131 char_u *nextcmd = (char_u *)"";
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2132 char_u *tofree = NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2133 char_u *cmd_arg = NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2134
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2135 if (cctx->ctx_skip == SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2136 goto theend;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2137
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2138 // If there was a prececing command modifier, drop it and include it in the
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2139 // EXEC command.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2140 if (cctx->ctx_has_cmdmod)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2141 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2142 garray_T *instr = &cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2143 isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2144
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2145 if (isn->isn_type == ISN_CMDMOD)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2146 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2147 vim_regfree(isn->isn_arg.cmdmod.cf_cmdmod
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2148 ->cmod_filter_regmatch.regprog);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2149 vim_free(isn->isn_arg.cmdmod.cf_cmdmod);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2150 --instr->ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2151 cctx->ctx_has_cmdmod = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2152 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2153 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2154
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2155 if (eap->cmdidx >= 0 && eap->cmdidx < CMD_SIZE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2156 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2157 long argt = eap->argt;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2158 int usefilter = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2159
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2160 has_expr = argt & (EX_XFILE | EX_EXPAND);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2161
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2162 // If the command can be followed by a bar, find the bar and truncate
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2163 // it, so that the following command can be compiled.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2164 // The '|' is overwritten with a NUL, it is put back below.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2165 if ((eap->cmdidx == CMD_write || eap->cmdidx == CMD_read)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2166 && *eap->arg == '!')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2167 // :w !filter or :r !filter or :r! filter
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2168 usefilter = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2169 if ((argt & EX_TRLBAR) && !usefilter)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2170 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2171 eap->argt = argt;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2172 separate_nextcmd(eap, TRUE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2173 if (eap->nextcmd != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2174 nextcmd = eap->nextcmd;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2175 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2176 else if (eap->cmdidx == CMD_wincmd)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2177 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2178 p = eap->arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2179 if (*p != NUL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2180 ++p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2181 if (*p == 'g' || *p == Ctrl_G)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2182 ++p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2183 p = skipwhite(p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2184 if (*p == '|')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2185 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2186 *p = NUL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2187 nextcmd = p + 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2188 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2189 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2190 else if (eap->cmdidx == CMD_command || eap->cmdidx == CMD_autocmd)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2191 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2192 // If there is a trailing '{' read lines until the '}'
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2193 p = eap->arg + STRLEN(eap->arg) - 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2194 while (p > eap->arg && VIM_ISWHITE(*p))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2195 --p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2196 if (*p == '{')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2197 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2198 exarg_T ea;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2199 int flags = 0; // unused
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2200 int start_lnum = SOURCING_LNUM;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2201
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2202 CLEAR_FIELD(ea);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2203 ea.arg = eap->arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2204 fill_exarg_from_cctx(&ea, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2205 (void)may_get_cmd_block(&ea, p, &tofree, &flags);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2206 if (tofree != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2207 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2208 *p = NUL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2209 line = concat_str(line, tofree);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2210 if (line == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2211 goto theend;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2212 vim_free(tofree);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2213 tofree = line;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2214 SOURCING_LNUM = start_lnum;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2215 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2216 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2217 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2218 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2219
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2220 if (eap->cmdidx == CMD_syntax && STRNCMP(eap->arg, "include ", 8) == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2221 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2222 // expand filename in "syntax include [@group] filename"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2223 has_expr = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2224 eap->arg = skipwhite(eap->arg + 7);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2225 if (*eap->arg == '@')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2226 eap->arg = skiptowhite(eap->arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2227 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2228
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2229 if ((eap->cmdidx == CMD_global || eap->cmdidx == CMD_vglobal)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2230 && STRLEN(eap->arg) > 4)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2231 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2232 int delim = *eap->arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2233
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2234 p = skip_regexp_ex(eap->arg + 1, delim, TRUE, NULL, NULL, NULL);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2235 if (*p == delim)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2236 cmd_arg = p + 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2237 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2238
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2239 if (eap->cmdidx == CMD_folddoopen || eap->cmdidx == CMD_folddoclosed)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2240 cmd_arg = eap->arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2241
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2242 if (cmd_arg != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2243 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2244 exarg_T nea;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2245
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2246 CLEAR_FIELD(nea);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2247 nea.cmd = cmd_arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2248 p = find_ex_command(&nea, NULL, lookup_scriptitem, NULL);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2249 if (nea.cmdidx < CMD_SIZE)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2250 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2251 has_expr = excmd_get_argt(nea.cmdidx) & (EX_XFILE | EX_EXPAND);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2252 if (has_expr)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2253 eap->arg = skiptowhite(eap->arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2254 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2255 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2256
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2257 if (has_expr && (p = (char_u *)strstr((char *)eap->arg, "`=")) != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2258 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2259 int count = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2260 char_u *start = skipwhite(line);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2261
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2262 // :cmd xxx`=expr1`yyy`=expr2`zzz
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2263 // PUSHS ":cmd xxx"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2264 // eval expr1
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2265 // PUSHS "yyy"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2266 // eval expr2
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2267 // PUSHS "zzz"
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2268 // EXECCONCAT 5
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2269 for (;;)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2270 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2271 if (p > start)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2272 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2273 char_u *val = vim_strnsave(start, p - start);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2274
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2275 generate_PUSHS(cctx, &val);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2276 ++count;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2277 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2278 p += 2;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2279 if (compile_expr0(&p, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2280 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2281 may_generate_2STRING(-1, TRUE, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2282 ++count;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2283 p = skipwhite(p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2284 if (*p != '`')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2285 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2286 emsg(_(e_missing_backtick));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2287 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2288 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2289 start = p + 1;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2290
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2291 p = (char_u *)strstr((char *)start, "`=");
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2292 if (p == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2293 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2294 if (*skipwhite(start) != NUL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2295 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2296 char_u *val = vim_strsave(start);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2297
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2298 generate_PUSHS(cctx, &val);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2299 ++count;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2300 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2301 break;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2302 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2303 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2304 generate_EXECCONCAT(cctx, count);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2305 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2306 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2307 generate_EXEC_copy(cctx, ISN_EXEC, line);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2308
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2309 theend:
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2310 if (*nextcmd != NUL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2311 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2312 // the parser expects a pointer to the bar, put it back
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2313 --nextcmd;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2314 *nextcmd = '|';
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2315 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2316 vim_free(tofree);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2317
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2318 return nextcmd;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2319 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2320
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2321 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2322 * A script command with heredoc, e.g.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2323 * ruby << EOF
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2324 * command
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2325 * EOF
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2326 * Has been turned into one long line with NL characters by
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2327 * get_function_body():
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2328 * ruby << EOF<NL> command<NL>EOF
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2329 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2330 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2331 compile_script(char_u *line, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2332 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2333 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2334 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2335 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2336
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2337 if ((isn = generate_instr(cctx, ISN_EXEC_SPLIT)) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2338 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2339 isn->isn_arg.string = vim_strsave(line);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2340 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2341 return (char_u *)"";
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2342 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2343
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2344
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2345 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2346 * :s/pat/repl/
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2347 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2348 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2349 compile_substitute(char_u *arg, exarg_T *eap, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2350 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2351 char_u *cmd = eap->arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2352 char_u *expr = (char_u *)strstr((char *)cmd, "\\=");
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2353
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2354 if (expr != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2355 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2356 int delimiter = *cmd++;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2357
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2358 // There is a \=expr, find it in the substitute part.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2359 cmd = skip_regexp_ex(cmd, delimiter, magic_isset(), NULL, NULL, NULL);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2360 if (cmd[0] == delimiter && cmd[1] == '\\' && cmd[2] == '=')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2361 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2362 garray_T save_ga = cctx->ctx_instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2363 char_u *end;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2364 int expr_res;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2365 int trailing_error;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2366 int instr_count;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2367 isn_T *instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2368 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2369
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2370 cmd += 3;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2371 end = skip_substitute(cmd, delimiter);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2372
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2373 // Temporarily reset the list of instructions so that the jump
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2374 // labels are correct.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2375 cctx->ctx_instr.ga_len = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2376 cctx->ctx_instr.ga_maxlen = 0;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2377 cctx->ctx_instr.ga_data = NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2378 expr_res = compile_expr0(&cmd, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2379 if (end[-1] == NUL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2380 end[-1] = delimiter;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2381 cmd = skipwhite(cmd);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2382 trailing_error = *cmd != delimiter && *cmd != NUL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2383
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2384 if (expr_res == FAIL || trailing_error
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2385 || GA_GROW_FAILS(&cctx->ctx_instr, 1))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2386 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2387 if (trailing_error)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2388 semsg(_(e_trailing_characters_str), cmd);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2389 clear_instr_ga(&cctx->ctx_instr);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2390 cctx->ctx_instr = save_ga;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2391 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2392 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2393
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2394 // Move the generated instructions into the ISN_SUBSTITUTE
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2395 // instructions, then restore the list of instructions before
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2396 // adding the ISN_SUBSTITUTE instruction.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2397 instr_count = cctx->ctx_instr.ga_len;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2398 instr = cctx->ctx_instr.ga_data;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2399 instr[instr_count].isn_type = ISN_FINISH;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2400
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2401 cctx->ctx_instr = save_ga;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2402 if ((isn = generate_instr(cctx, ISN_SUBSTITUTE)) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2403 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2404 int idx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2405
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2406 for (idx = 0; idx < instr_count; ++idx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2407 delete_instr(instr + idx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2408 vim_free(instr);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2409 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2410 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2411 isn->isn_arg.subs.subs_cmd = vim_strsave(arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2412 isn->isn_arg.subs.subs_instr = instr;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2413
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2414 // skip over flags
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2415 if (*end == '&')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2416 ++end;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2417 while (ASCII_ISALPHA(*end) || *end == '#')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2418 ++end;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2419 return end;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2420 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2421 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2422
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2423 return compile_exec(arg, eap, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2424 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2425
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2426 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2427 compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2428 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2429 char_u *arg = eap->arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2430 lhs_T *lhs = &cctx->ctx_redir_lhs;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2431
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2432 if (lhs->lhs_name != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2433 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2434 if (STRNCMP(arg, "END", 3) == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2435 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2436 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2437 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2438 if (lhs->lhs_append)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2439 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2440 // First load the current variable value.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2441 if (compile_load_lhs_with_index(lhs, lhs->lhs_whole,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2442 cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2443 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2444 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2445
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2446 // Gets the redirected text and put it on the stack, then store
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2447 // it in the variable.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2448 generate_instr_type(cctx, ISN_REDIREND, &t_string);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2449
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2450 if (lhs->lhs_append)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2451 generate_CONCAT(cctx, 2);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2452
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2453 if (lhs->lhs_has_index)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2454 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2455 // Use the info in "lhs" to store the value at the index in
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2456 // the list or dict.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2457 if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2458 &t_string, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2459 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2460 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2461 else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2462 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2463
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2464 VIM_CLEAR(lhs->lhs_name);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2465 VIM_CLEAR(lhs->lhs_whole);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2466 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2467 return arg + 3;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2468 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2469 emsg(_(e_cannot_nest_redir));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2470 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2471 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2472
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2473 if (arg[0] == '=' && arg[1] == '>')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2474 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2475 int append = FALSE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2476
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2477 // redirect to a variable is compiled
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2478 arg += 2;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2479 if (*arg == '>')
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2480 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2481 ++arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2482 append = TRUE;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2483 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2484 arg = skipwhite(arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2485
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2486 if (compile_assign_lhs(arg, lhs, CMD_redir,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2487 FALSE, FALSE, FALSE, 1, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2488 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2489 if (need_type(&t_string, lhs->lhs_member_type, FALSE,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2490 -1, 0, cctx, FALSE, FALSE) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2491 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2492 if (cctx->ctx_skip == SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2493 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2494 VIM_CLEAR(lhs->lhs_name);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2495 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2496 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2497 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2498 generate_instr(cctx, ISN_REDIRSTART);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2499 lhs->lhs_append = append;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2500 if (lhs->lhs_has_index)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2501 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2502 lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2503 if (lhs->lhs_whole == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2504 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2505 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2506 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2507
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2508 return arg + lhs->lhs_varlen_total;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2509 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2510
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2511 // other redirects are handled like at script level
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2512 return compile_exec(line, eap, cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2513 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2514
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2515 #if defined(FEAT_QUICKFIX) || defined(PROTO)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2516 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2517 compile_cexpr(char_u *line, exarg_T *eap, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2518 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2519 isn_T *isn;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2520 char_u *p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2521
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2522 isn = generate_instr(cctx, ISN_CEXPR_AUCMD);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2523 if (isn == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2524 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2525 isn->isn_arg.number = eap->cmdidx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2526
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2527 p = eap->arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2528 if (compile_expr0(&p, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2529 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2530
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2531 isn = generate_instr(cctx, ISN_CEXPR_CORE);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2532 if (isn == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2533 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2534 isn->isn_arg.cexpr.cexpr_ref = ALLOC_ONE(cexprref_T);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2535 if (isn->isn_arg.cexpr.cexpr_ref == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2536 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2537 isn->isn_arg.cexpr.cexpr_ref->cer_cmdidx = eap->cmdidx;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2538 isn->isn_arg.cexpr.cexpr_ref->cer_forceit = eap->forceit;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2539 isn->isn_arg.cexpr.cexpr_ref->cer_cmdline = vim_strsave(skipwhite(line));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2540
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2541 return p;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2542 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2543 #endif
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2544
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2545 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2546 * Compile "return [expr]".
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2547 * When "legacy" is TRUE evaluate [expr] with legacy syntax
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2548 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2549 char_u *
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2550 compile_return(char_u *arg, int check_return_type, int legacy, cctx_T *cctx)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2551 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2552 char_u *p = arg;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2553 type_T *stack_type;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2554
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2555 if (*p != NUL && *p != '|' && *p != '\n'
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2556 && (legacy || !vim9_comment_start(p)))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2557 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2558 // For a lambda, "return expr" is always used, also when "expr" results
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2559 // in a void.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2560 if (cctx->ctx_ufunc->uf_ret_type->tt_type == VAR_VOID
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2561 && (cctx->ctx_ufunc->uf_flags & FC_LAMBDA) == 0)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2562 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2563 emsg(_(e_returning_value_in_function_without_return_type));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2564 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2565 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2566 if (legacy)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2567 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2568 int save_flags = cmdmod.cmod_flags;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2569
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2570 generate_LEGACY_EVAL(cctx, p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2571 if (need_type(&t_any, cctx->ctx_ufunc->uf_ret_type, FALSE, -1,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2572 0, cctx, FALSE, FALSE) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2573 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2574 cmdmod.cmod_flags |= CMOD_LEGACY;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2575 (void)skip_expr(&p, NULL);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2576 cmdmod.cmod_flags = save_flags;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2577 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2578 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2579 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2580 // compile return argument into instructions
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2581 if (compile_expr0(&p, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2582 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2583 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2584
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2585 if (cctx->ctx_skip != SKIP_YES)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2586 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2587 // "check_return_type" with uf_ret_type set to &t_unknown is used
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2588 // for an inline function without a specified return type. Set the
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2589 // return type here.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2590 stack_type = get_type_on_stack(cctx, 0);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2591 if ((check_return_type && (cctx->ctx_ufunc->uf_ret_type == NULL
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2592 || cctx->ctx_ufunc->uf_ret_type == &t_unknown))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2593 || (!check_return_type
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2594 && cctx->ctx_ufunc->uf_ret_type == &t_unknown))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2595 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2596 cctx->ctx_ufunc->uf_ret_type = stack_type;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2597 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2598 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2599 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2600 if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, FALSE,
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2601 -1, 0, cctx, FALSE, FALSE) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2602 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2603 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2604 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2605 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2606 else
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2607 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2608 // "check_return_type" cannot be TRUE, only used for a lambda which
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2609 // always has an argument.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2610 if (cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_VOID
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2611 && cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_UNKNOWN)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2612 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2613 emsg(_(e_missing_return_value));
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2614 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2615 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2616
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2617 // No argument, return zero.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2618 generate_PUSHNR(cctx, 0);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2619 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2620
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2621 // may need ENDLOOP when inside a :for or :while loop
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2622 if (compile_find_scope(NULL, NULL, NULL, NULL, cctx) == FAIL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2623
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2624 // Undo any command modifiers.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2625 generate_undo_cmdmods(cctx);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2626
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2627 if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_RETURN) == NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2628 return NULL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2629
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2630 // "return val | endif" is possible
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2631 return skipwhite(p);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2632 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2633
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2634 /*
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2635 * Check if the separator for a :global or :substitute command is OK.
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2636 */
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2637 int
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2638 check_global_and_subst(char_u *cmd, char_u *arg)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2639 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2640 if (arg == cmd + 1 && vim_strchr((char_u *)":-.", *arg) != NULL)
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2641 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2642 semsg(_(e_separator_not_supported_str), arg);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2643 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2644 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2645 if (VIM_ISWHITE(cmd[1]))
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2646 {
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2647 semsg(_(e_no_white_space_allowed_before_separator_str), cmd);
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2648 return FAIL;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2649 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2650 return OK;
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2651 }
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2652
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2653
448aef880252 normalize line endings
Christian Brabandt <cb@256bit.org>
parents: 32452
diff changeset
2654 #endif // defined(FEAT_EVAL)