• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ucode/tests/custom/00_syntax/29_function_forward_declarations

  1 The `function foo;` syntax allows forward-declaring a function name
  2 before providing its definition. This enables mutual recursion between
  3 functions at the same scope level.
  4 
  5 
  6 1. A forward-declared function can be defined and called normally.
  7 
  8 -- Expect stdout --
  9 hello
 10 -- End --
 11 
 12 -- Testcase --
 13 {%
 14         function greet;
 15 
 16         function greet() {
 17                 return "hello";
 18         }
 19 
 20         print(greet(), "\n");
 21 %}
 22 -- End --
 23 
 24 
 25 2. Forward declarations enable mutual recursion.
 26 
 27 -- Expect stdout --
 28 [
 29         true,
 30         true,
 31         true,
 32         true
 33 ]
 34 -- End --
 35 
 36 -- Testcase --
 37 {%
 38         function is_even;
 39         function is_odd;
 40 
 41         function is_even(n) {
 42                 if (n == 0) return true;
 43                 return is_odd(n - 1);
 44         }
 45 
 46         function is_odd(n) {
 47                 if (n == 0) return false;
 48                 return is_even(n - 1);
 49         }
 50 
 51         printf("%.J\n", [
 52                 is_even(0),
 53                 is_odd(1),
 54                 is_even(10),
 55                 is_odd(11)
 56         ]);
 57 %}
 58 -- End --
 59 
 60 
 61 3. Assignment to a forward-declared function is forbidden (constant binding).
 62 
 63 -- Expect stderr --
 64 Syntax error: Invalid assignment to constant 'foo'
 65 In line 4, byte 31:
 66 
 67  `    foo = function() { return 2; };`
 68       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
 69 
 70 
 71 -- End --
 72 
 73 -- Testcase --
 74 {%
 75         function foo;
 76 
 77         foo = function() { return 2; };
 78 %}
 79 -- End --
 80 
 81 
 82 4. A `let` declaration after a forward declaration is forbidden.
 83 
 84 -- Expect stderr --
 85 Syntax error: Variable 'foo' redeclared
 86 In line 4, byte 6:
 87 
 88  `    let foo = 1;`
 89           ^-- Near here
 90 
 91 
 92 -- End --
 93 
 94 -- Testcase --
 95 {%
 96         function foo;
 97 
 98         let foo = 1;
 99 %}
100 -- End --
101 
102 
103 5. A `const` declaration after a forward declaration is forbidden.
104 
105 -- Expect stderr --
106 Syntax error: Variable 'foo' redeclared
107 In line 4, byte 8:
108 
109  `    const foo = 1;`
110             ^-- Near here
111 
112 
113 -- End --
114 
115 -- Testcase --
116 {%
117         function foo;
118 
119         const foo = 1;
120 %}
121 -- End --
122 
123 
124 6. Defining a function twice after forward declaration is forbidden.
125 
126 -- Expect stderr --
127 Syntax error: Redeclaration of constant 'foo'
128 In line 5, byte 2:
129 
130  `    function foo() { return 2; }`
131       ^-- Near here
132 
133 
134 -- End --
135 
136 -- Testcase --
137 {%
138         function foo;
139 
140         function foo() { return 1; }
141         function foo() { return 2; }
142 %}
143 -- End --
144 
145 
146 7. Duplicate forward declarations are forbidden.
147 
148 -- Expect stderr --
149 Syntax error: Function 'foo' redeclared
150 In line 3, byte 11:
151 
152  `    function foo;`
153   Near here ---^
154 
155 
156 -- End --
157 
158 -- Testcase --
159 {%
160         function foo;
161         function foo;
162 %}
163 -- End --
164 
165 
166 8. Forward declaration after a definition is forbidden.
167 
168 -- Expect stderr --
169 Syntax error: Variable 'foo' redeclared
170 In line 3, byte 11:
171 
172  `    function foo;`
173   Near here ---^
174 
175 
176 -- End --
177 
178 -- Testcase --
179 {%
180         function foo() { return 1; }
181         function foo;
182 %}
183 -- End --
184 
185 
186 9. Calling an unfilled forward declaration raises a runtime error.
187 
188 -- Expect stderr --
189 Type error: `foo` is not a function, got null instead
190 In line 4, byte 6:
191 
192  `    foo();`
193       ~~~~^~
194 
195 
196 -- End --
197 
198 -- Testcase --
199 {%
200         function foo;
201 
202         foo();
203 %}
204 -- End --
205 
206 
207 10. A nested function can capture a forward-declared name as upvalue.
208 
209 -- Expect stdout --
210 hello from foo
211 -- End --
212 
213 -- Testcase --
214 {%
215         function foo;
216 
217         function call_foo() {
218                 return foo();
219         }
220 
221         function foo() {
222                 return "hello from foo";
223         }
224 
225         print(call_foo(), "\n");
226 %}
227 -- End --
228 
229 
230 11. Forward declarations work with export.
231 
232 -- File test-forward-decl.uc --
233 export function foo;
234 
235 function foo() {
236         return "exported";
237 }
238 -- End --
239 
240 -- Args --
241 -R
242 -- End --
243 
244 -- Expect stdout --
245 exported
246 -- End --
247 
248 -- Testcase --
249 import { foo } from "./files/test-forward-decl.uc";
250 
251 print(foo(), "\n");
252 -- End --
253 
254 
255 12. Increment/decrement of a forward-declared function is forbidden.
256 
257 -- Expect stderr --
258 Syntax error: Invalid increment/decrement of constant 'foo'
259 In line 4, byte 5:
260 
261  `    foo++;`
262          ^-- Near here
263 
264 
265 -- End --
266 
267 -- Testcase --
268 {%
269         function foo;
270 
271         foo++;
272 %}
273 -- End --
274 
275 
276 13. In strict mode, the name of a regular function declaration is a
277 constant binding, so assigning to it is forbidden.
278 
279 -- Expect stderr --
280 Syntax error: Invalid assignment to constant 'foo'
281 In line 6, byte 8:
282 
283  `    foo = 1;`
284       ~~~~~~^
285 
286 
287 -- End --
288 
289 -- Testcase --
290 {%
291         "use strict";
292 
293         function foo() { return 1; }
294 
295         foo = 1;
296 %}
297 -- End --
298 
299 
300 14. In strict mode, compound assignments to a regular function
301 name are forbidden as well.
302 
303 -- Expect stderr --
304 Syntax error: Invalid assignment to constant 'foo'
305 In line 6, byte 9:
306 
307  `    foo += 1;`
308       ~~~~~~~^
309 
310 
311 -- End --
312 
313 -- Testcase --
314 {%
315         "use strict";
316 
317         function foo() { return 1; }
318 
319         foo += 1;
320 %}
321 -- End --
322 
323 
324 15. In strict mode, increment/decrement of a regular function name
325 is forbidden.
326 
327 -- Expect stderr --
328 Syntax error: Invalid increment/decrement of constant 'foo'
329 In line 6, byte 5:
330 
331  `    foo++;`
332          ^-- Near here
333 
334 
335 -- End --
336 
337 -- Testcase --
338 {%
339         "use strict";
340 
341         function foo() { return 1; }
342 
343         foo++;
344 %}
345 -- End --
346 
347 
348 16. In strict mode, a regular function may not be declared twice in the
349 same scope.
350 
351 -- Expect stderr --
352 Syntax error: Variable 'foo' redeclared
353 In line 6, byte 11:
354 
355  `    function foo() { return 2; }`
356   Near here ---^
357 
358 
359 -- End --
360 
361 -- Testcase --
362 {%
363         "use strict";
364 
365         function foo() { return 1; }
366 
367         function foo() { return 2; }
368 %}
369 -- End --
370 
371 
372 17. In non-strict mode, the name of a regular function declaration is a
373 mutable binding, so assigning to it rebinds the name.
374 
375 -- Expect exitcode --
376 0
377 -- End --
378 
379 -- Testcase --
380 {%
381         function foo() { return 1; }
382 
383         foo = 1;
384 %}
385 -- End --

This page was automatically generated by LXR 0.3.1.  •  OpenWrt