@canvasengine/compiler 2.0.0-beta.5 → 2.0.0-beta.7
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 +58 -7
- package/package.json +1 -1
- package/tests/compiler.spec.ts +74 -11
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}`;
|
|
@@ -139,8 +162,13 @@ textElement
|
|
|
139
162
|
}
|
|
140
163
|
|
|
141
164
|
forLoop
|
|
142
|
-
= _ "@for" _ "(" _ variableName:identifier _ "of" _ iterable:identifier _ ")" _ "{" _ content:content _ "}" _ {
|
|
143
|
-
return `loop(${iterable},
|
|
165
|
+
= _ "@for" _ "(" _ variableName:(tupleDestructuring / identifier) _ "of" _ iterable:identifier _ ")" _ "{" _ content:content _ "}" _ {
|
|
166
|
+
return `loop(${iterable}, ${variableName} => ${content})`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
tupleDestructuring
|
|
170
|
+
= "(" _ first:identifier _ "," _ second:identifier _ ")" {
|
|
171
|
+
return `(${first}, ${second})`;
|
|
144
172
|
}
|
|
145
173
|
|
|
146
174
|
ifCondition
|
|
@@ -164,7 +192,30 @@ iterable
|
|
|
164
192
|
= [a-zA-Z_][a-zA-Z0-9_]* { return text(); }
|
|
165
193
|
|
|
166
194
|
condition
|
|
167
|
-
=
|
|
195
|
+
= functionCall
|
|
196
|
+
/ $([^)]*) { return text().trim(); }
|
|
197
|
+
|
|
198
|
+
functionCall
|
|
199
|
+
= name:identifier "(" args:functionArgs? ")" {
|
|
200
|
+
return `${name}(${args || ''})`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
functionArgs
|
|
204
|
+
= arg:functionArg rest:("," _ functionArg)* {
|
|
205
|
+
return [arg].concat(rest.map(r => r[2])).join(', ');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
functionArg
|
|
209
|
+
= _ value:(identifier / number / string) _ {
|
|
210
|
+
return value;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
number
|
|
214
|
+
= [0-9]+ ("." [0-9]+)? { return text(); }
|
|
215
|
+
|
|
216
|
+
string
|
|
217
|
+
= '"' chars:[^"]* '"' { return text(); }
|
|
218
|
+
/ "'" chars:[^']* "'" { return text(); }
|
|
168
219
|
|
|
169
220
|
eventAction
|
|
170
221
|
= [^"]* { 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", () => {
|
|
@@ -195,7 +236,7 @@ describe("Loop", () => {
|
|
|
195
236
|
`;
|
|
196
237
|
const output = parser.parse(input);
|
|
197
238
|
expect(output.replace(/\s+/g, "")).toBe(
|
|
198
|
-
`h(Canvas,null,loop(sprites,
|
|
239
|
+
`h(Canvas,null,loop(sprites,sprite=>h(Sprite)))`.replace(/\s+/g, "")
|
|
199
240
|
);
|
|
200
241
|
});
|
|
201
242
|
|
|
@@ -207,7 +248,19 @@ describe("Loop", () => {
|
|
|
207
248
|
`;
|
|
208
249
|
const output = parser.parse(input);
|
|
209
250
|
expect(output.replace(/\s+/g, "")).toBe(
|
|
210
|
-
`loop(sprites,
|
|
251
|
+
`loop(sprites,sprite=>h(Sprite))`.replace(/\s+/g, "")
|
|
252
|
+
);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test("should compile loop with destructuring", () => {
|
|
256
|
+
const input = `
|
|
257
|
+
@for ((sprite, index) of sprites) {
|
|
258
|
+
<Sprite key={index} />
|
|
259
|
+
}
|
|
260
|
+
`;
|
|
261
|
+
const output = parser.parse(input);
|
|
262
|
+
expect(output.replace(/\s+/g, "")).toBe(
|
|
263
|
+
`loop(sprites,(sprite,index)=>h(Sprite, { key: index }))`.replace(/\s+/g, "")
|
|
211
264
|
);
|
|
212
265
|
});
|
|
213
266
|
|
|
@@ -221,7 +274,7 @@ describe("Loop", () => {
|
|
|
221
274
|
`;
|
|
222
275
|
const output = parser.parse(input);
|
|
223
276
|
expect(output.replace(/\s+/g, "")).toBe(
|
|
224
|
-
`loop(sprites,
|
|
277
|
+
`loop(sprites,sprite=>loop(others,other=>h(Sprite)))`.replace(
|
|
225
278
|
/\s+/g,
|
|
226
279
|
""
|
|
227
280
|
)
|
|
@@ -240,6 +293,16 @@ describe("Condition", () => {
|
|
|
240
293
|
expect(output).toBe(`cond(sprite.visible, () => h(Sprite))`);
|
|
241
294
|
});
|
|
242
295
|
|
|
296
|
+
test("should compile condition when function value", () => {
|
|
297
|
+
const input = `
|
|
298
|
+
@if (val()) {
|
|
299
|
+
<Sprite />
|
|
300
|
+
}
|
|
301
|
+
`;
|
|
302
|
+
const output = parser.parse(input);
|
|
303
|
+
expect(output).toBe(`cond(val(), () => h(Sprite))`);
|
|
304
|
+
});
|
|
305
|
+
|
|
243
306
|
test("should compile condition for multiple sprites", () => {
|
|
244
307
|
const input = `
|
|
245
308
|
@if (sprite) {
|
|
@@ -314,7 +377,7 @@ describe("Condition in Loops", () => {
|
|
|
314
377
|
`;
|
|
315
378
|
const output = parser.parse(input);
|
|
316
379
|
expect(output.replace(/\s+/g, "")).toBe(
|
|
317
|
-
`h(Canvas,null,loop(sprites,
|
|
380
|
+
`h(Canvas,null,loop(sprites,sprite=>cond(sprite.visible,()=>h(Sprite))))`.replace(/\s+/g, "")
|
|
318
381
|
);
|
|
319
382
|
});
|
|
320
383
|
|
|
@@ -328,7 +391,7 @@ describe("Condition in Loops", () => {
|
|
|
328
391
|
`;
|
|
329
392
|
const output = parser.parse(input);
|
|
330
393
|
expect(output.replace(/\s+/g, "")).toBe(
|
|
331
|
-
`h(Canvas,null,loop(sprites,
|
|
394
|
+
`h(Canvas,null,loop(sprites,sprite=>h(Sprite)))`.replace(/\s+/g, "")
|
|
332
395
|
);
|
|
333
396
|
});
|
|
334
397
|
|
|
@@ -345,7 +408,7 @@ describe("Condition in Loops", () => {
|
|
|
345
408
|
`;
|
|
346
409
|
const output = parser.parse(input);
|
|
347
410
|
expect(output.replace(/\s+/g, "")).toBe(
|
|
348
|
-
`h(Canvas,null,[loop(sprites,
|
|
411
|
+
`h(Canvas,null,[loop(sprites,sprite=>h(Sprite)),loop(others,other=>h(Sprite))])`.replace(/\s+/g, "")
|
|
349
412
|
);
|
|
350
413
|
});
|
|
351
414
|
|