ether-code 0.9.0 → 0.9.1
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/cli/ether.js +1 -1
- package/generators/php-generator.js +253 -250
- package/i18n/i18n-php.json +8 -0
- package/lexer/ether-lexer.js +399 -392
- package/package.json +1 -1
- package/parsers/ether-parser-php.js +294 -317
|
@@ -226,12 +226,6 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
226
226
|
this.phpModifiers = ['statique', 'static', 'final', 'finale', 'abstrait', 'abstraite', 'abstract', 'readonly', 'lecture seule']
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
safeStr(val) {
|
|
230
|
-
if (typeof val === 'string') return val
|
|
231
|
-
if (val && typeof val === 'object') return String(val.name || val.value || '')
|
|
232
|
-
return String(val || '')
|
|
233
|
-
}
|
|
234
|
-
|
|
235
229
|
translatePHP(word) {
|
|
236
230
|
if (!word) return word
|
|
237
231
|
const lower = this.normalizeAccents(String(word))
|
|
@@ -278,10 +272,6 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
278
272
|
|
|
279
273
|
const value = token.value != null ? this.normalizeAccents(String(token.value).toLowerCase()) : ''
|
|
280
274
|
|
|
281
|
-
if (this.isDeclare(value)) {
|
|
282
|
-
return this.parseDeclare(lang)
|
|
283
|
-
}
|
|
284
|
-
|
|
285
275
|
if (this.isNamespace(value)) {
|
|
286
276
|
return this.parseNamespace(lang)
|
|
287
277
|
}
|
|
@@ -290,6 +280,10 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
290
280
|
return this.parseUseStatement(lang)
|
|
291
281
|
}
|
|
292
282
|
|
|
283
|
+
if (this.isDeclare(value)) {
|
|
284
|
+
return this.parseDeclareStatement(lang)
|
|
285
|
+
}
|
|
286
|
+
|
|
293
287
|
if (this.isClassDeclaration(value)) {
|
|
294
288
|
return this.parseClassDeclaration(lang)
|
|
295
289
|
}
|
|
@@ -326,16 +320,6 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
326
320
|
return this.parseSwitch(lang)
|
|
327
321
|
}
|
|
328
322
|
|
|
329
|
-
if (token.type === TokenType.IDENTIFIER) {
|
|
330
|
-
const multiWordCall = this.tryParseMultiWordCallFromStart(lang)
|
|
331
|
-
if (multiWordCall) {
|
|
332
|
-
return {
|
|
333
|
-
type: 'ExpressionStatement',
|
|
334
|
-
expression: multiWordCall
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
323
|
if (this.isTry(value)) {
|
|
340
324
|
return this.parseTryStatement(lang)
|
|
341
325
|
}
|
|
@@ -385,23 +369,17 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
385
369
|
}
|
|
386
370
|
|
|
387
371
|
isNamespace(value) {
|
|
388
|
-
|
|
389
|
-
if (value === 'espace') {
|
|
390
|
-
const next1 = this.peek(1)
|
|
391
|
-
const next2 = this.peek(2)
|
|
392
|
-
if (next1 && next2) {
|
|
393
|
-
const val1 = this.normalizeAccents(String(next1.value).toLowerCase())
|
|
394
|
-
const val2 = this.normalizeAccents(String(next2.value).toLowerCase())
|
|
395
|
-
if (val1 === 'de' && val2 === 'noms') return true
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
return false
|
|
372
|
+
return ['namespace', 'espace de noms'].includes(value)
|
|
399
373
|
}
|
|
400
374
|
|
|
401
375
|
isUse(value) {
|
|
402
376
|
return ['utiliser', 'use'].includes(value)
|
|
403
377
|
}
|
|
404
378
|
|
|
379
|
+
isDeclare(value) {
|
|
380
|
+
return ['declarer', 'declare'].includes(value)
|
|
381
|
+
}
|
|
382
|
+
|
|
405
383
|
isClassDeclaration(value) {
|
|
406
384
|
const keywords = ['classe', 'class', 'abstrait', 'abstraite', 'abstract', 'final', 'finale', 'readonly']
|
|
407
385
|
if (keywords.includes(value)) {
|
|
@@ -493,54 +471,8 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
493
471
|
return value === 'match'
|
|
494
472
|
}
|
|
495
473
|
|
|
496
|
-
isDeclare(value) {
|
|
497
|
-
return ['declare', 'declarer', 'déclarer'].includes(value)
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
parseDeclare(lang) {
|
|
501
|
-
this.advance()
|
|
502
|
-
|
|
503
|
-
const directives = []
|
|
504
|
-
|
|
505
|
-
if (this.match(TokenType.LPAREN)) {
|
|
506
|
-
do {
|
|
507
|
-
const nameToken = this.current()
|
|
508
|
-
const name = nameToken ? this.safeStr(nameToken.value) : ''
|
|
509
|
-
this.advance()
|
|
510
|
-
|
|
511
|
-
this.match(TokenType.EQUALS)
|
|
512
|
-
|
|
513
|
-
const value = this.parseExpression(lang)
|
|
514
|
-
directives.push({ name, value })
|
|
515
|
-
} while (this.match(TokenType.COMMA))
|
|
516
|
-
|
|
517
|
-
this.match(TokenType.RPAREN)
|
|
518
|
-
} else {
|
|
519
|
-
const nameToken = this.current()
|
|
520
|
-
const name = nameToken ? this.safeStr(nameToken.value) : ''
|
|
521
|
-
this.advance()
|
|
522
|
-
|
|
523
|
-
this.match(TokenType.EQUALS)
|
|
524
|
-
|
|
525
|
-
const value = this.parseExpression(lang)
|
|
526
|
-
directives.push({ name, value })
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
return {
|
|
530
|
-
type: 'DeclareStatement',
|
|
531
|
-
directives: directives
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
474
|
parseNamespace(lang) {
|
|
536
|
-
|
|
537
|
-
const firstVal = this.normalizeAccents(String(first.value).toLowerCase())
|
|
538
|
-
|
|
539
|
-
if (firstVal === 'espace' && firstVal !== 'espace de noms') {
|
|
540
|
-
this.advance()
|
|
541
|
-
this.advance()
|
|
542
|
-
}
|
|
543
|
-
|
|
475
|
+
this.advance()
|
|
544
476
|
const name = this.parseNamespacePath(lang)
|
|
545
477
|
this.skipNewlines()
|
|
546
478
|
|
|
@@ -608,6 +540,42 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
608
540
|
}
|
|
609
541
|
}
|
|
610
542
|
|
|
543
|
+
parseDeclareStatement(lang) {
|
|
544
|
+
this.advance()
|
|
545
|
+
|
|
546
|
+
const directives = []
|
|
547
|
+
|
|
548
|
+
do {
|
|
549
|
+
const nameToken = this.current()
|
|
550
|
+
if (!nameToken || nameToken.type !== TokenType.IDENTIFIER) break
|
|
551
|
+
|
|
552
|
+
let name = String(nameToken.value)
|
|
553
|
+
this.advance()
|
|
554
|
+
|
|
555
|
+
if (name === 'strict' && this.current()) {
|
|
556
|
+
const next = this.normalizeAccents(String(this.current().value).toLowerCase())
|
|
557
|
+
if (next === 'types' || next === '_types') {
|
|
558
|
+
name = 'strict_types'
|
|
559
|
+
this.advance()
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
this.match(TokenType.EQUALS)
|
|
564
|
+
|
|
565
|
+
const value = this.parseExpression(lang)
|
|
566
|
+
|
|
567
|
+
directives.push({
|
|
568
|
+
name: name,
|
|
569
|
+
value: value
|
|
570
|
+
})
|
|
571
|
+
} while (this.match(TokenType.COMMA))
|
|
572
|
+
|
|
573
|
+
return {
|
|
574
|
+
type: 'DeclareStatement',
|
|
575
|
+
directives: directives
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
611
579
|
parseClassDeclaration(lang) {
|
|
612
580
|
const modifiers = []
|
|
613
581
|
|
|
@@ -743,6 +711,10 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
743
711
|
return this.parseTraitUse(lang)
|
|
744
712
|
}
|
|
745
713
|
|
|
714
|
+
if (val === 'variable' || val === 'var') {
|
|
715
|
+
this.advance()
|
|
716
|
+
}
|
|
717
|
+
|
|
746
718
|
return this.parsePropertyDeclaration(lang, visibility, isStatic, isReadonly)
|
|
747
719
|
}
|
|
748
720
|
|
|
@@ -803,11 +775,6 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
803
775
|
}
|
|
804
776
|
|
|
805
777
|
parsePropertyDeclaration(lang, visibility, isStatic, isReadonly) {
|
|
806
|
-
const val = this.current() ? this.normalizeAccents(String(this.current().value).toLowerCase()) : ''
|
|
807
|
-
if (val === 'variable' || val === 'var') {
|
|
808
|
-
this.advance()
|
|
809
|
-
}
|
|
810
|
-
|
|
811
778
|
let typeHint = null
|
|
812
779
|
|
|
813
780
|
const current = this.current()
|
|
@@ -819,10 +786,12 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
819
786
|
}
|
|
820
787
|
|
|
821
788
|
const nameToken = this.current()
|
|
822
|
-
let name =
|
|
789
|
+
let name = nameToken ? nameToken.value : 'property'
|
|
823
790
|
|
|
824
|
-
if (name.startsWith('$')) {
|
|
791
|
+
if (typeof name === 'string' && name.startsWith('$')) {
|
|
825
792
|
name = name.substring(1)
|
|
793
|
+
} else if (typeof name !== 'string') {
|
|
794
|
+
name = String(name)
|
|
826
795
|
}
|
|
827
796
|
|
|
828
797
|
if (nameToken) this.advance()
|
|
@@ -1091,6 +1060,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1091
1060
|
}
|
|
1092
1061
|
}
|
|
1093
1062
|
|
|
1063
|
+
this.match(TokenType.COLON)
|
|
1094
1064
|
this.skipNewlines()
|
|
1095
1065
|
|
|
1096
1066
|
let body
|
|
@@ -1109,8 +1079,6 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1109
1079
|
}
|
|
1110
1080
|
}
|
|
1111
1081
|
|
|
1112
|
-
this.match(TokenType.COLON)
|
|
1113
|
-
this.skipNewlines()
|
|
1114
1082
|
body = this.parseBlock(lang)
|
|
1115
1083
|
|
|
1116
1084
|
return {
|
|
@@ -1135,7 +1103,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1135
1103
|
}
|
|
1136
1104
|
|
|
1137
1105
|
const varToken = this.current()
|
|
1138
|
-
let varName =
|
|
1106
|
+
let varName = varToken ? String(varToken.value) : ''
|
|
1139
1107
|
if (varName.startsWith('$')) {
|
|
1140
1108
|
varName = varName.substring(1)
|
|
1141
1109
|
}
|
|
@@ -1180,7 +1148,6 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1180
1148
|
let variadic = false
|
|
1181
1149
|
let byReference = false
|
|
1182
1150
|
let defaultValue = null
|
|
1183
|
-
let name = null
|
|
1184
1151
|
|
|
1185
1152
|
const val = this.current() ? this.normalizeAccents(String(this.current().value).toLowerCase()) : ''
|
|
1186
1153
|
if (this.phpVisibility.includes(val)) {
|
|
@@ -1194,6 +1161,19 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1194
1161
|
this.advance()
|
|
1195
1162
|
}
|
|
1196
1163
|
|
|
1164
|
+
const currentType = this.current()
|
|
1165
|
+
if (currentType && currentType.type === TokenType.IDENTIFIER) {
|
|
1166
|
+
const typeLower = this.normalizeAccents(String(currentType.value).toLowerCase())
|
|
1167
|
+
const nextToken = this.peek(1)
|
|
1168
|
+
|
|
1169
|
+
if (nextToken && nextToken.type === TokenType.COLON) {
|
|
1170
|
+
} else if (this.phpTypes[typeLower] || (typeLower[0] && typeLower[0] === typeLower[0].toUpperCase())) {
|
|
1171
|
+
if (!nextToken || nextToken.type !== TokenType.EQUALS) {
|
|
1172
|
+
typeHint = this.parseTypeHint(lang)
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1197
1177
|
if (this.match(TokenType.SPREAD) || this.matchValue('...')) {
|
|
1198
1178
|
variadic = true
|
|
1199
1179
|
}
|
|
@@ -1202,33 +1182,17 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1202
1182
|
byReference = true
|
|
1203
1183
|
}
|
|
1204
1184
|
|
|
1205
|
-
const
|
|
1206
|
-
if (!
|
|
1207
|
-
|
|
1208
|
-
const nextToken = this.peek(1)
|
|
1185
|
+
const nameToken = this.current()
|
|
1186
|
+
if (!nameToken) return null
|
|
1209
1187
|
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
this.advance()
|
|
1214
|
-
this.advance()
|
|
1215
|
-
typeHint = this.parseTypeHint(lang)
|
|
1216
|
-
} else {
|
|
1217
|
-
const typeLower = this.normalizeAccents(String(currentToken.value).toLowerCase())
|
|
1218
|
-
if (this.phpTypes[typeLower] || /^[A-Z]/.test(currentToken.value)) {
|
|
1219
|
-
typeHint = this.parseTypeHint(lang)
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1222
|
-
const nameToken = this.current()
|
|
1223
|
-
if (nameToken && nameToken.type === TokenType.IDENTIFIER) {
|
|
1224
|
-
name = this.safeStr(nameToken.value)
|
|
1225
|
-
if (name.startsWith('$')) name = name.substring(1)
|
|
1226
|
-
this.advance()
|
|
1227
|
-
}
|
|
1188
|
+
let name = String(nameToken.value)
|
|
1189
|
+
if (name.startsWith('$')) {
|
|
1190
|
+
name = name.substring(1)
|
|
1228
1191
|
}
|
|
1192
|
+
this.advance()
|
|
1229
1193
|
|
|
1230
|
-
if (
|
|
1231
|
-
|
|
1194
|
+
if (this.match(TokenType.COLON)) {
|
|
1195
|
+
typeHint = this.parseTypeHint(lang)
|
|
1232
1196
|
}
|
|
1233
1197
|
|
|
1234
1198
|
if (this.match(TokenType.EQUALS)) {
|
|
@@ -1317,7 +1281,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1317
1281
|
}
|
|
1318
1282
|
|
|
1319
1283
|
const nameToken = this.current()
|
|
1320
|
-
let name =
|
|
1284
|
+
let name = nameToken ? String(nameToken.value) : 'variable'
|
|
1321
1285
|
if (name.startsWith('$')) {
|
|
1322
1286
|
name = name.substring(1)
|
|
1323
1287
|
}
|
|
@@ -1357,37 +1321,59 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1357
1321
|
|
|
1358
1322
|
const elseVal = this.current() ? this.normalizeAccents(String(this.current().value).toLowerCase()) : ''
|
|
1359
1323
|
if (elseVal === 'sinon si' || elseVal === 'elseif') {
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1324
|
+
this.advance()
|
|
1325
|
+
|
|
1326
|
+
let elseCondition
|
|
1327
|
+
if (this.match(TokenType.LPAREN)) {
|
|
1328
|
+
elseCondition = this.parseExpression(lang)
|
|
1329
|
+
this.match(TokenType.RPAREN)
|
|
1330
|
+
} else {
|
|
1331
|
+
elseCondition = this.parseConditionUntilColon(lang)
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
this.match(TokenType.COLON)
|
|
1335
|
+
this.skipNewlines()
|
|
1336
|
+
const elseConsequent = this.parseBlock(lang)
|
|
1337
|
+
|
|
1338
|
+
alternate = {
|
|
1339
|
+
type: 'IfStatement',
|
|
1340
|
+
condition: elseCondition,
|
|
1341
|
+
consequent: elseConsequent,
|
|
1342
|
+
alternate: null
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
this.skipNewlines()
|
|
1346
|
+
const nextElse = this.current() ? this.normalizeAccents(String(this.current().value).toLowerCase()) : ''
|
|
1347
|
+
if (nextElse === 'sinon' || nextElse === 'else') {
|
|
1348
|
+
this.advance()
|
|
1349
|
+
this.match(TokenType.COLON)
|
|
1350
|
+
this.skipNewlines()
|
|
1351
|
+
alternate.alternate = this.parseBlock(lang)
|
|
1352
|
+
}
|
|
1353
|
+
} else if (elseVal === 'sinon' || elseVal === 'else') {
|
|
1363
1354
|
this.advance()
|
|
1364
1355
|
|
|
1365
1356
|
const nextVal = this.current() ? this.normalizeAccents(String(this.current().value).toLowerCase()) : ''
|
|
1366
1357
|
if (nextVal === 'si' || nextVal === 'if') {
|
|
1367
1358
|
alternate = this.parseConditional(lang)
|
|
1368
|
-
alternate.type = '
|
|
1359
|
+
alternate.type = 'ElseIfStatement'
|
|
1369
1360
|
} else {
|
|
1370
1361
|
this.match(TokenType.COLON)
|
|
1371
1362
|
this.skipNewlines()
|
|
1372
1363
|
alternate = this.parseBlock(lang)
|
|
1373
1364
|
}
|
|
1374
|
-
} else if (elseVal === 'else') {
|
|
1375
|
-
this.advance()
|
|
1376
|
-
this.match(TokenType.COLON)
|
|
1377
|
-
this.skipNewlines()
|
|
1378
|
-
alternate = this.parseBlock(lang)
|
|
1379
1365
|
}
|
|
1380
1366
|
|
|
1381
1367
|
return {
|
|
1382
1368
|
type: 'IfStatement',
|
|
1383
|
-
|
|
1369
|
+
condition: condition,
|
|
1384
1370
|
consequent: consequent,
|
|
1385
1371
|
alternate: alternate
|
|
1386
1372
|
}
|
|
1387
1373
|
}
|
|
1388
1374
|
|
|
1389
1375
|
parseConditionUntilColon(lang) {
|
|
1390
|
-
const
|
|
1376
|
+
const tokens = []
|
|
1391
1377
|
let depth = 0
|
|
1392
1378
|
|
|
1393
1379
|
while (!this.isAtEnd()) {
|
|
@@ -1404,23 +1390,36 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1404
1390
|
break
|
|
1405
1391
|
}
|
|
1406
1392
|
|
|
1393
|
+
tokens.push(token)
|
|
1407
1394
|
this.advance()
|
|
1408
1395
|
}
|
|
1409
1396
|
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
if (endPos > startPos) {
|
|
1414
|
-
return this.parseExpression(lang)
|
|
1397
|
+
if (tokens.length === 0) {
|
|
1398
|
+
return { type: 'Literal', value: true }
|
|
1415
1399
|
}
|
|
1416
1400
|
|
|
1417
|
-
|
|
1401
|
+
const savedPos = this.pos
|
|
1402
|
+
const savedTokens = this.tokens
|
|
1403
|
+
this.tokens = tokens
|
|
1404
|
+
this.pos = 0
|
|
1405
|
+
|
|
1406
|
+
const expr = this.parseExpression(lang)
|
|
1407
|
+
|
|
1408
|
+
this.tokens = savedTokens
|
|
1409
|
+
this.pos = savedPos
|
|
1410
|
+
|
|
1411
|
+
return expr
|
|
1418
1412
|
}
|
|
1419
1413
|
|
|
1420
1414
|
parseLoop(lang) {
|
|
1421
1415
|
const token = this.current()
|
|
1422
1416
|
const value = this.normalizeAccents(String(token.value).toLowerCase())
|
|
1423
1417
|
|
|
1418
|
+
if (value === 'pour chaque' || value === 'foreach') {
|
|
1419
|
+
this.advance()
|
|
1420
|
+
return this.parseForeach(lang)
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1424
1423
|
if (value === 'pour') {
|
|
1425
1424
|
const next = this.peek(1)
|
|
1426
1425
|
if (next && this.normalizeAccents(String(next.value).toLowerCase()) === 'chaque') {
|
|
@@ -1431,16 +1430,14 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1431
1430
|
return this.parseFor(lang)
|
|
1432
1431
|
}
|
|
1433
1432
|
|
|
1434
|
-
if (value === '
|
|
1433
|
+
if (value === 'tant que' || value === 'while') {
|
|
1435
1434
|
this.advance()
|
|
1436
|
-
return this.
|
|
1435
|
+
return this.parseWhile(lang)
|
|
1437
1436
|
}
|
|
1438
1437
|
|
|
1439
|
-
if (value === '
|
|
1438
|
+
if (value === 'tant') {
|
|
1440
1439
|
this.advance()
|
|
1441
|
-
|
|
1442
|
-
this.matchValue('que')
|
|
1443
|
-
}
|
|
1440
|
+
this.matchValue('que')
|
|
1444
1441
|
return this.parseWhile(lang)
|
|
1445
1442
|
}
|
|
1446
1443
|
|
|
@@ -1454,7 +1451,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1454
1451
|
|
|
1455
1452
|
parseFor(lang) {
|
|
1456
1453
|
this.advance()
|
|
1457
|
-
|
|
1454
|
+
|
|
1458
1455
|
let init = null
|
|
1459
1456
|
let test = null
|
|
1460
1457
|
let update = null
|
|
@@ -1475,19 +1472,13 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1475
1472
|
}
|
|
1476
1473
|
this.match(TokenType.RPAREN)
|
|
1477
1474
|
} else {
|
|
1478
|
-
|
|
1479
|
-
init = this.parseExpression(lang)
|
|
1480
|
-
}
|
|
1475
|
+
init = this.parseForInitUntilSemicolon(lang)
|
|
1481
1476
|
this.match(TokenType.SEMICOLON)
|
|
1482
1477
|
|
|
1483
|
-
|
|
1484
|
-
test = this.parseExpression(lang)
|
|
1485
|
-
}
|
|
1478
|
+
test = this.parseForConditionUntilSemicolon(lang)
|
|
1486
1479
|
this.match(TokenType.SEMICOLON)
|
|
1487
1480
|
|
|
1488
|
-
|
|
1489
|
-
update = this.parseExpression(lang)
|
|
1490
|
-
}
|
|
1481
|
+
update = this.parseForUpdateUntilColon(lang)
|
|
1491
1482
|
}
|
|
1492
1483
|
|
|
1493
1484
|
this.match(TokenType.COLON)
|
|
@@ -1503,6 +1494,82 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1503
1494
|
}
|
|
1504
1495
|
}
|
|
1505
1496
|
|
|
1497
|
+
parseForInitUntilSemicolon(lang) {
|
|
1498
|
+
const tokens = []
|
|
1499
|
+
while (!this.isAtEnd()) {
|
|
1500
|
+
const token = this.current()
|
|
1501
|
+
if (!token) break
|
|
1502
|
+
if (token.type === TokenType.SEMICOLON) break
|
|
1503
|
+
tokens.push(token)
|
|
1504
|
+
this.advance()
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
if (tokens.length === 0) return null
|
|
1508
|
+
|
|
1509
|
+
const savedPos = this.pos
|
|
1510
|
+
const savedTokens = this.tokens
|
|
1511
|
+
this.tokens = tokens
|
|
1512
|
+
this.pos = 0
|
|
1513
|
+
|
|
1514
|
+
const expr = this.parseExpression(lang)
|
|
1515
|
+
|
|
1516
|
+
this.tokens = savedTokens
|
|
1517
|
+
this.pos = savedPos
|
|
1518
|
+
|
|
1519
|
+
return expr
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
parseForConditionUntilSemicolon(lang) {
|
|
1523
|
+
const tokens = []
|
|
1524
|
+
while (!this.isAtEnd()) {
|
|
1525
|
+
const token = this.current()
|
|
1526
|
+
if (!token) break
|
|
1527
|
+
if (token.type === TokenType.SEMICOLON) break
|
|
1528
|
+
tokens.push(token)
|
|
1529
|
+
this.advance()
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
if (tokens.length === 0) return null
|
|
1533
|
+
|
|
1534
|
+
const savedPos = this.pos
|
|
1535
|
+
const savedTokens = this.tokens
|
|
1536
|
+
this.tokens = tokens
|
|
1537
|
+
this.pos = 0
|
|
1538
|
+
|
|
1539
|
+
const expr = this.parseExpression(lang)
|
|
1540
|
+
|
|
1541
|
+
this.tokens = savedTokens
|
|
1542
|
+
this.pos = savedPos
|
|
1543
|
+
|
|
1544
|
+
return expr
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
parseForUpdateUntilColon(lang) {
|
|
1548
|
+
const tokens = []
|
|
1549
|
+
while (!this.isAtEnd()) {
|
|
1550
|
+
const token = this.current()
|
|
1551
|
+
if (!token) break
|
|
1552
|
+
if (token.type === TokenType.COLON) break
|
|
1553
|
+
if (token.type === TokenType.NEWLINE) break
|
|
1554
|
+
tokens.push(token)
|
|
1555
|
+
this.advance()
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
if (tokens.length === 0) return null
|
|
1559
|
+
|
|
1560
|
+
const savedPos = this.pos
|
|
1561
|
+
const savedTokens = this.tokens
|
|
1562
|
+
this.tokens = tokens
|
|
1563
|
+
this.pos = 0
|
|
1564
|
+
|
|
1565
|
+
const expr = this.parseExpression(lang)
|
|
1566
|
+
|
|
1567
|
+
this.tokens = savedTokens
|
|
1568
|
+
this.pos = savedPos
|
|
1569
|
+
|
|
1570
|
+
return expr
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1506
1573
|
parseForeach(lang) {
|
|
1507
1574
|
let array = null
|
|
1508
1575
|
let key = null
|
|
@@ -1522,7 +1589,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1522
1589
|
}
|
|
1523
1590
|
|
|
1524
1591
|
const firstVar = this.current()
|
|
1525
|
-
let firstName =
|
|
1592
|
+
let firstName = firstVar ? String(firstVar.value) : 'item'
|
|
1526
1593
|
if (firstName.startsWith('$')) firstName = firstName.substring(1)
|
|
1527
1594
|
this.advance()
|
|
1528
1595
|
|
|
@@ -1534,7 +1601,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1534
1601
|
}
|
|
1535
1602
|
|
|
1536
1603
|
const valueVar = this.current()
|
|
1537
|
-
value =
|
|
1604
|
+
value = valueVar ? String(valueVar.value) : 'value'
|
|
1538
1605
|
if (value.startsWith('$')) value = value.substring(1)
|
|
1539
1606
|
this.advance()
|
|
1540
1607
|
} else {
|
|
@@ -1543,12 +1610,28 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1543
1610
|
|
|
1544
1611
|
this.match(TokenType.RPAREN)
|
|
1545
1612
|
} else {
|
|
1546
|
-
const
|
|
1547
|
-
|
|
1548
|
-
|
|
1613
|
+
const tokens = []
|
|
1614
|
+
while (!this.isAtEnd()) {
|
|
1615
|
+
const token = this.current()
|
|
1616
|
+
if (!token) break
|
|
1617
|
+
const tokenVal = this.normalizeAccents(String(token.value).toLowerCase())
|
|
1618
|
+
if (tokenVal === 'comme' || tokenVal === 'as') break
|
|
1619
|
+
if (token.type === TokenType.COLON) break
|
|
1620
|
+
if (token.type === TokenType.NEWLINE) break
|
|
1621
|
+
tokens.push(token)
|
|
1549
1622
|
this.advance()
|
|
1550
1623
|
}
|
|
1551
1624
|
|
|
1625
|
+
if (tokens.length > 0) {
|
|
1626
|
+
const savedPos = this.pos
|
|
1627
|
+
const savedTokens = this.tokens
|
|
1628
|
+
this.tokens = tokens
|
|
1629
|
+
this.pos = 0
|
|
1630
|
+
array = this.parseExpression(lang)
|
|
1631
|
+
this.tokens = savedTokens
|
|
1632
|
+
this.pos = savedPos
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1552
1635
|
const asVal = this.current() ? this.normalizeAccents(String(this.current().value).toLowerCase()) : ''
|
|
1553
1636
|
if (asVal === 'comme' || asVal === 'as') {
|
|
1554
1637
|
this.advance()
|
|
@@ -1559,23 +1642,27 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1559
1642
|
}
|
|
1560
1643
|
|
|
1561
1644
|
const firstVar = this.current()
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1645
|
+
if (firstVar && firstVar.type === TokenType.IDENTIFIER) {
|
|
1646
|
+
let firstName = String(firstVar.value)
|
|
1647
|
+
if (firstName.startsWith('$')) firstName = firstName.substring(1)
|
|
1648
|
+
this.advance()
|
|
1565
1649
|
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1650
|
+
if (this.match(TokenType.DOUBLE_ARROW) || this.matchValue('=>')) {
|
|
1651
|
+
key = firstName
|
|
1652
|
+
|
|
1653
|
+
if (this.match(TokenType.AMPERSAND)) {
|
|
1654
|
+
byRef = true
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
const valueVar = this.current()
|
|
1658
|
+
if (valueVar && valueVar.type === TokenType.IDENTIFIER) {
|
|
1659
|
+
value = String(valueVar.value)
|
|
1660
|
+
if (value.startsWith('$')) value = value.substring(1)
|
|
1661
|
+
this.advance()
|
|
1662
|
+
}
|
|
1663
|
+
} else {
|
|
1664
|
+
value = firstName
|
|
1571
1665
|
}
|
|
1572
|
-
|
|
1573
|
-
const valueVar = this.current()
|
|
1574
|
-
value = this.safeStr(valueVar ? valueVar.value : 'value')
|
|
1575
|
-
if (value.startsWith('$')) value = value.substring(1)
|
|
1576
|
-
this.advance()
|
|
1577
|
-
} else {
|
|
1578
|
-
value = firstName
|
|
1579
1666
|
}
|
|
1580
1667
|
}
|
|
1581
1668
|
|
|
@@ -1608,7 +1695,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1608
1695
|
|
|
1609
1696
|
return {
|
|
1610
1697
|
type: 'WhileStatement',
|
|
1611
|
-
|
|
1698
|
+
condition: condition,
|
|
1612
1699
|
body: body
|
|
1613
1700
|
}
|
|
1614
1701
|
}
|
|
@@ -1686,25 +1773,29 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1686
1773
|
|
|
1687
1774
|
if (val === 'cas' || val === 'case') {
|
|
1688
1775
|
this.advance()
|
|
1689
|
-
const test = this.
|
|
1776
|
+
const test = this.parseConditionUntilColon(lang)
|
|
1690
1777
|
this.match(TokenType.COLON)
|
|
1691
1778
|
this.skipNewlines()
|
|
1692
|
-
this.match(TokenType.INDENT)
|
|
1693
1779
|
|
|
1780
|
+
const hasInnerIndent = this.match(TokenType.INDENT)
|
|
1694
1781
|
const consequent = []
|
|
1782
|
+
|
|
1695
1783
|
while (!this.isAtEnd()) {
|
|
1696
1784
|
this.skipNewlines()
|
|
1697
|
-
const
|
|
1698
|
-
if (!
|
|
1785
|
+
const nextToken = this.current()
|
|
1786
|
+
if (!nextToken) break
|
|
1699
1787
|
|
|
1700
|
-
const nextVal = this.normalizeAccents(String(
|
|
1701
|
-
if (['cas', 'case', 'defaut', 'default'].includes(nextVal)) {
|
|
1788
|
+
const nextVal = this.normalizeAccents(String(nextToken.value).toLowerCase())
|
|
1789
|
+
if (['cas', 'case', 'defaut', 'default', 'défaut'].includes(nextVal)) {
|
|
1702
1790
|
break
|
|
1703
1791
|
}
|
|
1704
|
-
if (
|
|
1705
|
-
|
|
1792
|
+
if (nextToken.type === TokenType.RBRACE || nextToken.type === TokenType.DEDENT) {
|
|
1793
|
+
if (hasInnerIndent) {
|
|
1794
|
+
this.advance()
|
|
1795
|
+
}
|
|
1706
1796
|
break
|
|
1707
1797
|
}
|
|
1798
|
+
|
|
1708
1799
|
const stmt = this.parseStatement(lang)
|
|
1709
1800
|
if (stmt) consequent.push(stmt)
|
|
1710
1801
|
this.skipNewlines()
|
|
@@ -1715,21 +1806,26 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1715
1806
|
test: test,
|
|
1716
1807
|
consequent: consequent
|
|
1717
1808
|
})
|
|
1718
|
-
} else if (val === 'defaut' || val === 'default') {
|
|
1809
|
+
} else if (val === 'defaut' || val === 'default' || val === 'défaut') {
|
|
1719
1810
|
this.advance()
|
|
1720
1811
|
this.match(TokenType.COLON)
|
|
1721
1812
|
this.skipNewlines()
|
|
1722
|
-
this.match(TokenType.INDENT)
|
|
1723
1813
|
|
|
1814
|
+
const hasInnerIndent = this.match(TokenType.INDENT)
|
|
1724
1815
|
const consequent = []
|
|
1816
|
+
|
|
1725
1817
|
while (!this.isAtEnd()) {
|
|
1726
1818
|
this.skipNewlines()
|
|
1727
|
-
const
|
|
1728
|
-
if (!
|
|
1729
|
-
|
|
1730
|
-
|
|
1819
|
+
const nextToken = this.current()
|
|
1820
|
+
if (!nextToken) break
|
|
1821
|
+
|
|
1822
|
+
if (nextToken.type === TokenType.RBRACE || nextToken.type === TokenType.DEDENT) {
|
|
1823
|
+
if (hasInnerIndent) {
|
|
1824
|
+
this.advance()
|
|
1825
|
+
}
|
|
1731
1826
|
break
|
|
1732
1827
|
}
|
|
1828
|
+
|
|
1733
1829
|
const stmt = this.parseStatement(lang)
|
|
1734
1830
|
if (stmt) consequent.push(stmt)
|
|
1735
1831
|
this.skipNewlines()
|
|
@@ -1833,7 +1929,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1833
1929
|
do {
|
|
1834
1930
|
const typeToken = this.current()
|
|
1835
1931
|
if (typeToken && typeToken.type === TokenType.IDENTIFIER) {
|
|
1836
|
-
const typeName =
|
|
1932
|
+
const typeName = String(typeToken.value)
|
|
1837
1933
|
if (typeName.startsWith('$')) {
|
|
1838
1934
|
param = typeName.substring(1)
|
|
1839
1935
|
} else {
|
|
@@ -1846,7 +1942,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1846
1942
|
if (!param) {
|
|
1847
1943
|
const paramToken = this.current()
|
|
1848
1944
|
if (paramToken && paramToken.type === TokenType.IDENTIFIER) {
|
|
1849
|
-
param =
|
|
1945
|
+
param = String(paramToken.value)
|
|
1850
1946
|
if (param.startsWith('$')) param = param.substring(1)
|
|
1851
1947
|
this.advance()
|
|
1852
1948
|
}
|
|
@@ -1855,7 +1951,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1855
1951
|
} else {
|
|
1856
1952
|
const typeToken = this.current()
|
|
1857
1953
|
if (typeToken && typeToken.type === TokenType.IDENTIFIER) {
|
|
1858
|
-
types.push(
|
|
1954
|
+
types.push(String(typeToken.value))
|
|
1859
1955
|
this.advance()
|
|
1860
1956
|
}
|
|
1861
1957
|
|
|
@@ -1864,7 +1960,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1864
1960
|
this.advance()
|
|
1865
1961
|
const paramToken = this.current()
|
|
1866
1962
|
if (paramToken && paramToken.type === TokenType.IDENTIFIER) {
|
|
1867
|
-
param =
|
|
1963
|
+
param = String(paramToken.value)
|
|
1868
1964
|
if (param.startsWith('$')) param = param.substring(1)
|
|
1869
1965
|
this.advance()
|
|
1870
1966
|
}
|
|
@@ -1979,7 +2075,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1979
2075
|
const variables = []
|
|
1980
2076
|
do {
|
|
1981
2077
|
const varToken = this.current()
|
|
1982
|
-
let varName =
|
|
2078
|
+
let varName = varToken ? String(varToken.value) : ''
|
|
1983
2079
|
if (varName.startsWith('$')) varName = varName.substring(1)
|
|
1984
2080
|
this.advance()
|
|
1985
2081
|
variables.push(varName)
|
|
@@ -2196,12 +2292,12 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2196
2292
|
return { type: 'UnaryExpression', operator: '!', operand }
|
|
2197
2293
|
}
|
|
2198
2294
|
|
|
2199
|
-
if (this.match(TokenType.MINUS)
|
|
2295
|
+
if (this.match(TokenType.MINUS)) {
|
|
2200
2296
|
const operand = this.parseUnary(lang)
|
|
2201
2297
|
return { type: 'UnaryExpression', operator: '-', operand }
|
|
2202
2298
|
}
|
|
2203
2299
|
|
|
2204
|
-
if (this.match(TokenType.PLUS)
|
|
2300
|
+
if (this.match(TokenType.PLUS)) {
|
|
2205
2301
|
const operand = this.parseUnary(lang)
|
|
2206
2302
|
return { type: 'UnaryExpression', operator: '+', operand }
|
|
2207
2303
|
}
|
|
@@ -2216,15 +2312,12 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2216
2312
|
return { type: 'UnaryExpression', operator: '~', operand }
|
|
2217
2313
|
}
|
|
2218
2314
|
|
|
2219
|
-
|
|
2220
|
-
if (current && current.type === TokenType.PLUS && current.value === '++') {
|
|
2221
|
-
this.advance()
|
|
2315
|
+
if (this.match(TokenType.DOUBLE_PLUS)) {
|
|
2222
2316
|
const operand = this.parseUnary(lang)
|
|
2223
2317
|
return { type: 'UpdateExpression', operator: '++', prefix: true, operand }
|
|
2224
2318
|
}
|
|
2225
2319
|
|
|
2226
|
-
if (
|
|
2227
|
-
this.advance()
|
|
2320
|
+
if (this.match(TokenType.DOUBLE_MINUS)) {
|
|
2228
2321
|
const operand = this.parseUnary(lang)
|
|
2229
2322
|
return { type: 'UpdateExpression', operator: '--', prefix: true, operand }
|
|
2230
2323
|
}
|
|
@@ -2333,123 +2426,14 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2333
2426
|
}
|
|
2334
2427
|
}
|
|
2335
2428
|
|
|
2336
|
-
tryParseMultiWordCall(firstName, lang) {
|
|
2337
|
-
const words = [firstName]
|
|
2338
|
-
let lookAhead = 0
|
|
2339
|
-
|
|
2340
|
-
while (true) {
|
|
2341
|
-
const nextToken = this.peek(lookAhead)
|
|
2342
|
-
if (!nextToken) break
|
|
2343
|
-
|
|
2344
|
-
if (nextToken.type === TokenType.LPAREN) {
|
|
2345
|
-
if (words.length > 1) {
|
|
2346
|
-
for (let i = 0; i < lookAhead; i++) {
|
|
2347
|
-
this.advance()
|
|
2348
|
-
}
|
|
2349
|
-
this.advance()
|
|
2350
|
-
|
|
2351
|
-
const args = []
|
|
2352
|
-
while (!this.isAtEnd() && !this.check(TokenType.RPAREN)) {
|
|
2353
|
-
this.skipNewlines()
|
|
2354
|
-
if (this.check(TokenType.RPAREN)) break
|
|
2355
|
-
|
|
2356
|
-
if (this.match(TokenType.SPREAD) || this.matchValue('...')) {
|
|
2357
|
-
const arg = this.parseExpression(lang)
|
|
2358
|
-
args.push({ type: 'SpreadElement', argument: arg })
|
|
2359
|
-
} else {
|
|
2360
|
-
const arg = this.parseExpression(lang)
|
|
2361
|
-
args.push(arg)
|
|
2362
|
-
}
|
|
2363
|
-
this.match(TokenType.COMMA)
|
|
2364
|
-
this.skipNewlines()
|
|
2365
|
-
}
|
|
2366
|
-
this.match(TokenType.RPAREN)
|
|
2367
|
-
|
|
2368
|
-
const funcName = words.join(' ')
|
|
2369
|
-
return {
|
|
2370
|
-
type: 'CallExpression',
|
|
2371
|
-
callee: { type: 'Identifier', name: funcName },
|
|
2372
|
-
arguments: args
|
|
2373
|
-
}
|
|
2374
|
-
}
|
|
2375
|
-
break
|
|
2376
|
-
}
|
|
2377
|
-
|
|
2378
|
-
if (nextToken.type === TokenType.IDENTIFIER) {
|
|
2379
|
-
words.push(this.safeStr(nextToken.value))
|
|
2380
|
-
lookAhead++
|
|
2381
|
-
} else {
|
|
2382
|
-
break
|
|
2383
|
-
}
|
|
2384
|
-
}
|
|
2385
|
-
|
|
2386
|
-
return null
|
|
2387
|
-
}
|
|
2388
|
-
|
|
2389
|
-
tryParseMultiWordCallFromStart(lang) {
|
|
2390
|
-
const words = []
|
|
2391
|
-
let lookAhead = 0
|
|
2392
|
-
|
|
2393
|
-
while (true) {
|
|
2394
|
-
const token = this.peek(lookAhead)
|
|
2395
|
-
if (!token) break
|
|
2396
|
-
|
|
2397
|
-
if (token.type === TokenType.LPAREN) {
|
|
2398
|
-
if (words.length >= 2) {
|
|
2399
|
-
for (let i = 0; i < lookAhead; i++) {
|
|
2400
|
-
this.advance()
|
|
2401
|
-
}
|
|
2402
|
-
this.advance()
|
|
2403
|
-
|
|
2404
|
-
const args = []
|
|
2405
|
-
while (!this.isAtEnd() && !this.check(TokenType.RPAREN)) {
|
|
2406
|
-
this.skipNewlines()
|
|
2407
|
-
if (this.check(TokenType.RPAREN)) break
|
|
2408
|
-
|
|
2409
|
-
if (this.match(TokenType.SPREAD) || this.matchValue('...')) {
|
|
2410
|
-
const arg = this.parseExpression(lang)
|
|
2411
|
-
args.push({ type: 'SpreadElement', argument: arg })
|
|
2412
|
-
} else {
|
|
2413
|
-
const arg = this.parseExpression(lang)
|
|
2414
|
-
args.push(arg)
|
|
2415
|
-
}
|
|
2416
|
-
this.match(TokenType.COMMA)
|
|
2417
|
-
this.skipNewlines()
|
|
2418
|
-
}
|
|
2419
|
-
this.match(TokenType.RPAREN)
|
|
2420
|
-
|
|
2421
|
-
const funcName = words.join(' ')
|
|
2422
|
-
return {
|
|
2423
|
-
type: 'CallExpression',
|
|
2424
|
-
callee: { type: 'Identifier', name: funcName },
|
|
2425
|
-
arguments: args
|
|
2426
|
-
}
|
|
2427
|
-
}
|
|
2428
|
-
break
|
|
2429
|
-
}
|
|
2430
|
-
|
|
2431
|
-
if (token.type === TokenType.IDENTIFIER) {
|
|
2432
|
-
words.push(this.safeStr(token.value))
|
|
2433
|
-
lookAhead++
|
|
2434
|
-
} else {
|
|
2435
|
-
break
|
|
2436
|
-
}
|
|
2437
|
-
}
|
|
2438
|
-
|
|
2439
|
-
return null
|
|
2440
|
-
}
|
|
2441
|
-
|
|
2442
2429
|
parsePostfix(lang) {
|
|
2443
2430
|
let expr = this.parseCall(lang)
|
|
2444
2431
|
|
|
2445
|
-
|
|
2446
|
-
if (current && current.type === TokenType.PLUS && current.value === '++') {
|
|
2447
|
-
this.advance()
|
|
2432
|
+
if (this.match(TokenType.DOUBLE_PLUS) || this.matchValue('++')) {
|
|
2448
2433
|
return { type: 'UpdateExpression', operator: '++', prefix: false, operand: expr }
|
|
2449
2434
|
}
|
|
2450
2435
|
|
|
2451
|
-
if (
|
|
2452
|
-
this.advance()
|
|
2436
|
+
if (this.match(TokenType.DOUBLE_MINUS) || this.matchValue('--')) {
|
|
2453
2437
|
return { type: 'UpdateExpression', operator: '--', prefix: false, operand: expr }
|
|
2454
2438
|
}
|
|
2455
2439
|
|
|
@@ -2459,13 +2443,6 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2459
2443
|
parseCall(lang) {
|
|
2460
2444
|
let expr = this.parsePrimary(lang)
|
|
2461
2445
|
|
|
2462
|
-
if (expr && expr.type === 'Identifier') {
|
|
2463
|
-
const multiWordResult = this.tryParseMultiWordCall(expr.name, lang)
|
|
2464
|
-
if (multiWordResult) {
|
|
2465
|
-
return multiWordResult
|
|
2466
|
-
}
|
|
2467
|
-
}
|
|
2468
|
-
|
|
2469
2446
|
while (true) {
|
|
2470
2447
|
if (this.match(TokenType.LPAREN)) {
|
|
2471
2448
|
const args = []
|
|
@@ -2548,11 +2525,11 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2548
2525
|
|
|
2549
2526
|
if (token.type === TokenType.STRING) {
|
|
2550
2527
|
this.advance()
|
|
2551
|
-
let value =
|
|
2528
|
+
let value = token.value
|
|
2552
2529
|
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
2553
2530
|
value = value.slice(1, -1)
|
|
2554
2531
|
}
|
|
2555
|
-
const isDouble =
|
|
2532
|
+
const isDouble = token.value.startsWith('"')
|
|
2556
2533
|
return { type: 'StringLiteral', value, doubleQuoted: isDouble }
|
|
2557
2534
|
}
|
|
2558
2535
|
|
|
@@ -2562,7 +2539,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2562
2539
|
}
|
|
2563
2540
|
|
|
2564
2541
|
if (token.type === TokenType.IDENTIFIER) {
|
|
2565
|
-
const value =
|
|
2542
|
+
const value = token.value
|
|
2566
2543
|
const valueLower = this.normalizeAccents(value.toLowerCase())
|
|
2567
2544
|
|
|
2568
2545
|
if (valueLower === 'vrai' || valueLower === 'true') {
|
|
@@ -2612,7 +2589,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2612
2589
|
return this.parseMatchExpression(lang)
|
|
2613
2590
|
}
|
|
2614
2591
|
|
|
2615
|
-
if (value.startsWith('$')) {
|
|
2592
|
+
if (typeof value === 'string' && value.startsWith('$')) {
|
|
2616
2593
|
this.advance()
|
|
2617
2594
|
return { type: 'Variable', name: value.substring(1) }
|
|
2618
2595
|
}
|
|
@@ -2623,7 +2600,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2623
2600
|
|
|
2624
2601
|
if (token.type === TokenType.VARIABLE) {
|
|
2625
2602
|
this.advance()
|
|
2626
|
-
let name =
|
|
2603
|
+
let name = String(token.value)
|
|
2627
2604
|
if (name.startsWith('$')) name = name.substring(1)
|
|
2628
2605
|
return { type: 'Variable', name }
|
|
2629
2606
|
}
|