@canvasengine/compiler 2.0.0-beta.5 → 2.0.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/grammar.pegjs +51 -5
- package/package.json +1 -1
- package/tests/compiler.spec.ts +56 -5
package/grammar.pegjs
CHANGED
|
@@ -72,15 +72,17 @@ eventHandler
|
|
|
72
72
|
|
|
73
73
|
dynamicAttribute
|
|
74
74
|
= attributeName:attributeName _ "=" _ "{" _ attributeValue:attributeValue _ "}" {
|
|
75
|
-
if (attributeValue.
|
|
75
|
+
if (attributeValue.startsWith('h(') || attributeValue.includes('=>')) {
|
|
76
|
+
return `${attributeName}: ${attributeValue}`;
|
|
77
|
+
} else if (attributeValue.trim().match(/^[a-zA-Z_]\w*$/)) {
|
|
76
78
|
return `${attributeName}: ${attributeValue}`;
|
|
77
79
|
} else {
|
|
78
|
-
let foundSignal = false
|
|
80
|
+
let foundSignal = false;
|
|
79
81
|
const computedValue = attributeValue.replace(/@?[a-zA-Z_][a-zA-Z0-9_]*(?!:)/g, (match) => {
|
|
80
82
|
if (match.startsWith('@')) {
|
|
81
83
|
return match.substring(1);
|
|
82
84
|
}
|
|
83
|
-
foundSignal = true
|
|
85
|
+
foundSignal = true;
|
|
84
86
|
return `${match}()`;
|
|
85
87
|
});
|
|
86
88
|
if (foundSignal) {
|
|
@@ -94,7 +96,9 @@ dynamicAttribute
|
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
attributeValue
|
|
97
|
-
=
|
|
99
|
+
= element
|
|
100
|
+
/ functionWithElement
|
|
101
|
+
/ $([^{}]* ("{" [^{}]* "}" [^{}]*)*) {
|
|
98
102
|
const t = text().trim()
|
|
99
103
|
if (t.startsWith("{") && t.endsWith("}")) {
|
|
100
104
|
return `(${t})`;
|
|
@@ -102,6 +106,25 @@ attributeValue
|
|
|
102
106
|
return t
|
|
103
107
|
}
|
|
104
108
|
|
|
109
|
+
functionWithElement
|
|
110
|
+
= "(" _ params:functionParams? _ ")" _ "=>" _ elem:element {
|
|
111
|
+
return `${params ? `(${params}) =>` : '() =>'} ${elem}`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
functionParams
|
|
115
|
+
= destructuredParams
|
|
116
|
+
/ simpleParams
|
|
117
|
+
|
|
118
|
+
destructuredParams
|
|
119
|
+
= "{" _ param:identifier rest:(_ "," _ identifier)* _ "}" {
|
|
120
|
+
return `{${[param].concat(rest.map(r => r[3])).join(', ')}}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
simpleParams
|
|
124
|
+
= param:identifier rest:(_ "," _ identifier)* {
|
|
125
|
+
return [param].concat(rest.map(r => r[3])).join(', ');
|
|
126
|
+
}
|
|
127
|
+
|
|
105
128
|
staticAttribute
|
|
106
129
|
= attributeName:attributeName _ "=" _ "\"" attributeValue:staticValue "\"" {
|
|
107
130
|
return `${attributeName}: ${attributeValue}`;
|
|
@@ -164,7 +187,30 @@ iterable
|
|
|
164
187
|
= [a-zA-Z_][a-zA-Z0-9_]* { return text(); }
|
|
165
188
|
|
|
166
189
|
condition
|
|
167
|
-
=
|
|
190
|
+
= functionCall
|
|
191
|
+
/ $([^)]*) { return text().trim(); }
|
|
192
|
+
|
|
193
|
+
functionCall
|
|
194
|
+
= name:identifier "(" args:functionArgs? ")" {
|
|
195
|
+
return `${name}(${args || ''})`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
functionArgs
|
|
199
|
+
= arg:functionArg rest:("," _ functionArg)* {
|
|
200
|
+
return [arg].concat(rest.map(r => r[2])).join(', ');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
functionArg
|
|
204
|
+
= _ value:(identifier / number / string) _ {
|
|
205
|
+
return value;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
number
|
|
209
|
+
= [0-9]+ ("." [0-9]+)? { return text(); }
|
|
210
|
+
|
|
211
|
+
string
|
|
212
|
+
= '"' chars:[^"]* '"' { return text(); }
|
|
213
|
+
/ "'" chars:[^']* "'" { return text(); }
|
|
168
214
|
|
|
169
215
|
eventAction
|
|
170
216
|
= [^"]* { return text(); }
|
package/package.json
CHANGED
package/tests/compiler.spec.ts
CHANGED
|
@@ -177,11 +177,52 @@ describe("Compiler", () => {
|
|
|
177
177
|
expect(output).toBe(`h(Sprite, { click: () => console.log('click') })`);
|
|
178
178
|
});
|
|
179
179
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
180
|
+
test("should compile component with component attribute", () => {
|
|
181
|
+
const input = `<Canvas child={<Sprite />} />`;
|
|
182
|
+
const output = parser.parse(input);
|
|
183
|
+
expect(output).toBe(`h(Canvas, { child: h(Sprite) })`);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test("should compile component with function returns component attribute", () => {
|
|
187
|
+
const input = `<Canvas child={() => <Sprite />} />`;
|
|
188
|
+
const output = parser.parse(input);
|
|
189
|
+
expect(output).toBe(`h(Canvas, { child: () => h(Sprite) })`);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test("should compile component with function (with params) returns component attribute", () => {
|
|
193
|
+
const input = `<Canvas child={(x, y) => <Sprite />} />`;
|
|
194
|
+
const output = parser.parse(input);
|
|
195
|
+
expect(output).toBe(`h(Canvas, { child: (x, y) => h(Sprite) })`);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test("should compile component with destructuring function (with params)", () => {
|
|
199
|
+
const input = `<Canvas child={({ x, y }) => <Sprite />} />`;
|
|
200
|
+
const output = parser.parse(input);
|
|
201
|
+
expect(output).toBe(`h(Canvas, { child: ({x, y}) => h(Sprite) })`);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("should compile component with function returns component attribute and data", () => {
|
|
205
|
+
const input = `<Canvas child={() => <Text text="Hello" />} />`;
|
|
206
|
+
const output = parser.parse(input);
|
|
207
|
+
expect(output).toBe(`h(Canvas, { child: () => h(Text, { text: 'Hello' }) })`);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test("should compile component with function returns component attribute and child", () => {
|
|
211
|
+
const input = `<Canvas child={() => <Container>
|
|
212
|
+
<Text text="Hello" />
|
|
213
|
+
</Container>} />`;
|
|
214
|
+
const output = parser.parse(input);
|
|
215
|
+
expect(output).toBe(`h(Canvas, { child: () => h(Container, null, h(Text, { text: 'Hello' })) })`);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test("should compile component with function returns component attribute and children", () => {
|
|
219
|
+
const input = `<Canvas child={() => <Container>
|
|
220
|
+
<Text text="Hello 1" />
|
|
221
|
+
<Text text="Hello 2" />
|
|
222
|
+
</Container>} />`;
|
|
223
|
+
const output = parser.parse(input);
|
|
224
|
+
expect(output).toBe(`h(Canvas, { child: () => h(Container, null, [h(Text, { text: 'Hello 1' }), h(Text, { text: 'Hello 2' })]) })`);
|
|
225
|
+
});
|
|
185
226
|
});
|
|
186
227
|
|
|
187
228
|
describe("Loop", () => {
|
|
@@ -240,6 +281,16 @@ describe("Condition", () => {
|
|
|
240
281
|
expect(output).toBe(`cond(sprite.visible, () => h(Sprite))`);
|
|
241
282
|
});
|
|
242
283
|
|
|
284
|
+
test("should compile condition when function value", () => {
|
|
285
|
+
const input = `
|
|
286
|
+
@if (val()) {
|
|
287
|
+
<Sprite />
|
|
288
|
+
}
|
|
289
|
+
`;
|
|
290
|
+
const output = parser.parse(input);
|
|
291
|
+
expect(output).toBe(`cond(val(), () => h(Sprite))`);
|
|
292
|
+
});
|
|
293
|
+
|
|
243
294
|
test("should compile condition for multiple sprites", () => {
|
|
244
295
|
const input = `
|
|
245
296
|
@if (sprite) {
|