1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
Besides the ordinary ES5-like function declarations, utpl supports ES6 inspired
arrow function syntax as well. Such arrow functions are useful for callbacks to functions such as replace(), map() or filter().
-- Expect stdout --
() => { ... }
test
(a, b) => { ... }
3
(...args) => { ... }
15
(a) => { ... }
10
(a) => { ... }
36
-- End --
-- Testcase --
{%
// assign arrow function to variable
test1_fn = () => {
return "test";
};
// assign arrow function with parameters
test2_fn = (a, b) => {
return a + b;
};
// nesting functions is legal
test3_fn = (...args) => {
nested_fn = (a, b) => {
return a * b;
};
return args[0] + nested_fn(args[0], args[1]);
};
// parentheses may be omitted if arrow function takes only one argument
test4_fn = a => {
a * 2;
};
// curly braces may be omitted if function body is a single expression
test5_fn = a => a * a;
print(join("\n", [
test1_fn,
test1_fn(),
test2_fn,
test2_fn(1, 2),
test3_fn,
test3_fn(3, 4),
test4_fn,
test4_fn(5),
test5_fn,
test5_fn(6)
]), "\n");
%}
-- End --
While the main advantage of arrow functions is the compact syntax, another
important difference to normal functions is the "this" context behaviour -
arrow functions do not have an own "this" context and simply inherit it from
the outer calling scope.
-- Expect stdout --
this is set to obj: true
arrow function uses outher this: true
normal function has own this: true
arrow function as method has no this: true
-- End --
-- Testcase --
{%
obj = {
method: function() {
let that = this;
let arr = () => {
print("arrow function uses outher this: ", that == this, "\n");
};
let fn = function() {
print("normal function has own this: ", that != this, "\n");
};
print("this is set to obj: ", this == obj, "\n");
arr();
fn();
},
arrowfn: () => {
print("arrow function as method has no this: ", this == null, "\n");
}
};
obj.method();
obj.arrowfn();
%}
-- End --
Due to the difficulty of recognizing arrow function expressions with an LR(1)
grammar the parser has to use a generic expression rule on the lhs argument list
and verify that it does not contain non-label nodes while building the ast. The
subsequent testcase asserts that case.
-- Expect stderr --
Syntax error: Unexpected token
Expecting ';'
In line 2, byte 10:
` (a + 1) => { print("test\n") }`
Near here --^
-- End --
-- Testcase --
{%
(a + 1) => { print("test\n") }
%}
-- End --
|