ether-code 0.4.4 → 0.4.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/cli/compiler.js +9 -4
- package/cli/ether.js +1 -1
- package/ether-parser.js +240 -8
- package/package.json +1 -1
package/cli/compiler.js
CHANGED
|
@@ -145,17 +145,22 @@ class EtherCompiler {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
detectTarget(content, filePath) {
|
|
148
|
-
const
|
|
148
|
+
const atMatch = content.match(/^@(?:cible|target)\s*:\s*(\w+)/im)
|
|
149
|
+
if (atMatch) {
|
|
150
|
+
return atMatch[1].toLowerCase()
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const directiveMatch = content.match(/^\/\/\s*(?:cible|target|@cible|@target)\s*:\s*(\w+)/im)
|
|
149
154
|
if (directiveMatch) {
|
|
150
155
|
return directiveMatch[1].toLowerCase()
|
|
151
156
|
}
|
|
152
157
|
|
|
153
|
-
const commentMatch = content.match(/^\/\*\s*(?:cible|target)\s*:\s*(\w+)\s*\*\//im)
|
|
158
|
+
const commentMatch = content.match(/^\/\*\s*(?:cible|target|@cible|@target)\s*:\s*(\w+)\s*\*\//im)
|
|
154
159
|
if (commentMatch) {
|
|
155
160
|
return commentMatch[1].toLowerCase()
|
|
156
161
|
}
|
|
157
162
|
|
|
158
|
-
const hashMatch = content.match(/^#\s*(?:cible|target)\s*:\s*(\w+)/im)
|
|
163
|
+
const hashMatch = content.match(/^#\s*(?:cible|target|@cible|@target)\s*:\s*(\w+)/im)
|
|
159
164
|
if (hashMatch) {
|
|
160
165
|
return hashMatch[1].toLowerCase()
|
|
161
166
|
}
|
|
@@ -249,4 +254,4 @@ class EtherCompiler {
|
|
|
249
254
|
}
|
|
250
255
|
}
|
|
251
256
|
|
|
252
|
-
module.exports = { EtherCompiler, GENERATORS, TARGET_EXTENSIONS }
|
|
257
|
+
module.exports = { EtherCompiler, GENERATORS, TARGET_EXTENSIONS }
|
package/cli/ether.js
CHANGED
package/ether-parser.js
CHANGED
|
@@ -11,6 +11,206 @@ class EtherParser {
|
|
|
11
11
|
this.targetLang = options.targetLang || 'auto'
|
|
12
12
|
|
|
13
13
|
this.loadAllI18n(options.i18nDir || './i18n')
|
|
14
|
+
this.initCompoundTerms()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
initCompoundTerms() {
|
|
18
|
+
this.compoundOperators = {
|
|
19
|
+
'strictement egal': '===',
|
|
20
|
+
'strictement égal': '===',
|
|
21
|
+
'strictement different': '!==',
|
|
22
|
+
'strictement différent': '!==',
|
|
23
|
+
'superieur ou egal': '>=',
|
|
24
|
+
'supérieur ou égal': '>=',
|
|
25
|
+
'inferieur ou egal': '<=',
|
|
26
|
+
'inférieur ou égal': '<=',
|
|
27
|
+
'coalescence nulle': '??',
|
|
28
|
+
'chainage optionnel': '?.',
|
|
29
|
+
'chaînage optionnel': '?.'
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
this.compoundKeywords = {
|
|
33
|
+
'sinon si': 'else if',
|
|
34
|
+
'tant que': 'while',
|
|
35
|
+
'pour chaque': 'forEach',
|
|
36
|
+
'fonction asynchrone': 'async function',
|
|
37
|
+
'fonction async': 'async function',
|
|
38
|
+
'fonction generatrice': 'function*',
|
|
39
|
+
'fonction génératrice': 'function*',
|
|
40
|
+
'variable globale': 'var'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
this.jsTranslations = {
|
|
44
|
+
'variable': 'let',
|
|
45
|
+
'constante': 'const',
|
|
46
|
+
'fonction': 'function',
|
|
47
|
+
'retourner': 'return',
|
|
48
|
+
'si': 'if',
|
|
49
|
+
'sinon': 'else',
|
|
50
|
+
'pour': 'for',
|
|
51
|
+
'de': 'of',
|
|
52
|
+
'dans': 'in',
|
|
53
|
+
'selon': 'switch',
|
|
54
|
+
'cas': 'case',
|
|
55
|
+
'defaut': 'default',
|
|
56
|
+
'sortir': 'break',
|
|
57
|
+
'continuer': 'continue',
|
|
58
|
+
'essayer': 'try',
|
|
59
|
+
'attraper': 'catch',
|
|
60
|
+
'finalement': 'finally',
|
|
61
|
+
'lancer': 'throw',
|
|
62
|
+
'nouveau': 'new',
|
|
63
|
+
'supprimer': 'delete',
|
|
64
|
+
'vrai': 'true',
|
|
65
|
+
'faux': 'false',
|
|
66
|
+
'nul': 'null',
|
|
67
|
+
'indefini': 'undefined',
|
|
68
|
+
'ceci': 'this',
|
|
69
|
+
'classe': 'class',
|
|
70
|
+
'etendre': 'extends',
|
|
71
|
+
'super': 'super',
|
|
72
|
+
'constructeur': 'constructor',
|
|
73
|
+
'statique': 'static',
|
|
74
|
+
'obtenir': 'get',
|
|
75
|
+
'definir': 'set',
|
|
76
|
+
'asynchrone': 'async',
|
|
77
|
+
'attendre': 'await',
|
|
78
|
+
'importer': 'import',
|
|
79
|
+
'exporter': 'export',
|
|
80
|
+
'depuis': 'from',
|
|
81
|
+
'comme': 'as',
|
|
82
|
+
'addition': '+',
|
|
83
|
+
'soustraction': '-',
|
|
84
|
+
'multiplication': '*',
|
|
85
|
+
'division': '/',
|
|
86
|
+
'modulo': '%',
|
|
87
|
+
'puissance': '**',
|
|
88
|
+
'increment': '++',
|
|
89
|
+
'decrement': '--',
|
|
90
|
+
'egal': '==',
|
|
91
|
+
'different': '!=',
|
|
92
|
+
'superieur': '>',
|
|
93
|
+
'inferieur': '<',
|
|
94
|
+
'et': '&&',
|
|
95
|
+
'ou': '||',
|
|
96
|
+
'non': '!',
|
|
97
|
+
'document': 'document',
|
|
98
|
+
'fenetre': 'window',
|
|
99
|
+
'console': 'console',
|
|
100
|
+
'journal': 'console.log',
|
|
101
|
+
'erreur': 'console.error',
|
|
102
|
+
'avertir': 'console.warn',
|
|
103
|
+
'info': 'console.info',
|
|
104
|
+
'promesse': 'Promise',
|
|
105
|
+
'resoudre': 'resolve',
|
|
106
|
+
'rejeter': 'reject',
|
|
107
|
+
'alors': 'then',
|
|
108
|
+
'tout': 'all',
|
|
109
|
+
'course': 'race',
|
|
110
|
+
'json': 'JSON',
|
|
111
|
+
'serialiser': 'stringify',
|
|
112
|
+
'analyser': 'parse',
|
|
113
|
+
'math': 'Math',
|
|
114
|
+
'aleatoire': 'random',
|
|
115
|
+
'arrondir': 'round',
|
|
116
|
+
'plancher': 'floor',
|
|
117
|
+
'plafond': 'ceil',
|
|
118
|
+
'absolu': 'abs',
|
|
119
|
+
'maximum': 'max',
|
|
120
|
+
'minimum': 'min',
|
|
121
|
+
'date': 'Date',
|
|
122
|
+
'maintenant': 'now',
|
|
123
|
+
'carte': 'Map',
|
|
124
|
+
'ensemble': 'Set',
|
|
125
|
+
'symbole': 'Symbol',
|
|
126
|
+
'objet': 'Object',
|
|
127
|
+
'selecteur': 'querySelector',
|
|
128
|
+
'sur': 'addEventListener',
|
|
129
|
+
'longueur': 'length',
|
|
130
|
+
'taille': 'size',
|
|
131
|
+
'recuperer': 'fetch',
|
|
132
|
+
'transformer': 'map',
|
|
133
|
+
'filtrer': 'filter',
|
|
134
|
+
'reduire': 'reduce',
|
|
135
|
+
'trouver': 'find',
|
|
136
|
+
'certains': 'some',
|
|
137
|
+
'tous': 'every',
|
|
138
|
+
'inclut': 'includes',
|
|
139
|
+
'joindre': 'join',
|
|
140
|
+
'inverser': 'reverse',
|
|
141
|
+
'trier': 'sort',
|
|
142
|
+
'decouper': 'slice',
|
|
143
|
+
'concatener': 'concat',
|
|
144
|
+
'ajouter': 'push',
|
|
145
|
+
'retirer': 'pop',
|
|
146
|
+
'diviser': 'split',
|
|
147
|
+
'remplacer': 'replace',
|
|
148
|
+
'rogner': 'trim',
|
|
149
|
+
'repeter': 'repeat'
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
normalizeAccents(str) {
|
|
154
|
+
return str.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
tryMatchCompoundOperator() {
|
|
158
|
+
const current = this.current()
|
|
159
|
+
if (!current || current.type !== TokenType.IDENTIFIER) return null
|
|
160
|
+
|
|
161
|
+
const val1 = this.normalizeAccents(String(current.value))
|
|
162
|
+
const next = this.peek(1)
|
|
163
|
+
const next2 = this.peek(2)
|
|
164
|
+
|
|
165
|
+
if (next && next.type === TokenType.IDENTIFIER) {
|
|
166
|
+
const val2 = this.normalizeAccents(String(next.value))
|
|
167
|
+
|
|
168
|
+
if (next2 && next2.type === TokenType.IDENTIFIER) {
|
|
169
|
+
const val3 = this.normalizeAccents(String(next2.value))
|
|
170
|
+
const compound3 = `${val1} ${val2} ${val3}`
|
|
171
|
+
if (this.compoundOperators[compound3]) {
|
|
172
|
+
this.advance()
|
|
173
|
+
this.advance()
|
|
174
|
+
this.advance()
|
|
175
|
+
return this.compoundOperators[compound3]
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const compound2 = `${val1} ${val2}`
|
|
180
|
+
if (this.compoundOperators[compound2]) {
|
|
181
|
+
this.advance()
|
|
182
|
+
this.advance()
|
|
183
|
+
return this.compoundOperators[compound2]
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return null
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
tryMatchCompoundKeyword() {
|
|
191
|
+
const current = this.current()
|
|
192
|
+
if (!current || current.type !== TokenType.IDENTIFIER) return null
|
|
193
|
+
|
|
194
|
+
const val1 = this.normalizeAccents(String(current.value))
|
|
195
|
+
const next = this.peek(1)
|
|
196
|
+
|
|
197
|
+
if (next && next.type === TokenType.IDENTIFIER) {
|
|
198
|
+
const val2 = this.normalizeAccents(String(next.value))
|
|
199
|
+
const compound2 = `${val1} ${val2}`
|
|
200
|
+
if (this.compoundKeywords[compound2]) {
|
|
201
|
+
this.advance()
|
|
202
|
+
this.advance()
|
|
203
|
+
return this.compoundKeywords[compound2]
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return null
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
translateJSIdentifier(word) {
|
|
211
|
+
if (!word) return word
|
|
212
|
+
const lower = this.normalizeAccents(String(word))
|
|
213
|
+
return this.jsTranslations[lower] || word
|
|
14
214
|
}
|
|
15
215
|
|
|
16
216
|
loadAllI18n(dir) {
|
|
@@ -1153,7 +1353,14 @@ class EtherParser {
|
|
|
1153
1353
|
return this.parseExport(lang)
|
|
1154
1354
|
}
|
|
1155
1355
|
|
|
1156
|
-
|
|
1356
|
+
const expr = this.parseExpression(lang)
|
|
1357
|
+
if (expr) {
|
|
1358
|
+
return {
|
|
1359
|
+
type: 'ExpressionStatement',
|
|
1360
|
+
expression: expr
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
return null
|
|
1157
1364
|
}
|
|
1158
1365
|
|
|
1159
1366
|
isVariableDeclaration(value) {
|
|
@@ -1717,6 +1924,13 @@ class EtherParser {
|
|
|
1717
1924
|
let left = this.parseComparison(lang)
|
|
1718
1925
|
|
|
1719
1926
|
while (true) {
|
|
1927
|
+
const compoundOp = this.tryMatchCompoundOperator()
|
|
1928
|
+
if (compoundOp === '===' || compoundOp === '!==') {
|
|
1929
|
+
const right = this.parseComparison(lang)
|
|
1930
|
+
left = { type: 'BinaryExpression', operator: compoundOp, left, right }
|
|
1931
|
+
continue
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1720
1934
|
if (this.match(TokenType.DOUBLE_EQUALS) || this.matchValue('egal') || this.matchValue('egale')) {
|
|
1721
1935
|
const right = this.parseComparison(lang)
|
|
1722
1936
|
left = { type: 'BinaryExpression', operator: '===', left, right }
|
|
@@ -1735,16 +1949,23 @@ class EtherParser {
|
|
|
1735
1949
|
let left = this.parseAdditive(lang)
|
|
1736
1950
|
|
|
1737
1951
|
while (true) {
|
|
1952
|
+
const compoundOp = this.tryMatchCompoundOperator()
|
|
1953
|
+
if (compoundOp === '>=' || compoundOp === '<=') {
|
|
1954
|
+
const right = this.parseAdditive(lang)
|
|
1955
|
+
left = { type: 'BinaryExpression', operator: compoundOp, left, right }
|
|
1956
|
+
continue
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1738
1959
|
if (this.match(TokenType.LT) || this.matchValue('inferieur')) {
|
|
1739
1960
|
const right = this.parseAdditive(lang)
|
|
1740
1961
|
left = { type: 'BinaryExpression', operator: '<', left, right }
|
|
1741
1962
|
} else if (this.match(TokenType.GT) || this.matchValue('superieur')) {
|
|
1742
1963
|
const right = this.parseAdditive(lang)
|
|
1743
1964
|
left = { type: 'BinaryExpression', operator: '>', left, right }
|
|
1744
|
-
} else if (this.match(TokenType.LTE)
|
|
1965
|
+
} else if (this.match(TokenType.LTE)) {
|
|
1745
1966
|
const right = this.parseAdditive(lang)
|
|
1746
1967
|
left = { type: 'BinaryExpression', operator: '<=', left, right }
|
|
1747
|
-
} else if (this.match(TokenType.GTE)
|
|
1968
|
+
} else if (this.match(TokenType.GTE)) {
|
|
1748
1969
|
const right = this.parseAdditive(lang)
|
|
1749
1970
|
left = { type: 'BinaryExpression', operator: '>=', left, right }
|
|
1750
1971
|
} else {
|
|
@@ -1759,10 +1980,10 @@ class EtherParser {
|
|
|
1759
1980
|
let left = this.parseMultiplicative(lang)
|
|
1760
1981
|
|
|
1761
1982
|
while (true) {
|
|
1762
|
-
if (this.match(TokenType.PLUS) || this.matchValue('plus')) {
|
|
1983
|
+
if (this.match(TokenType.PLUS) || this.matchValue('plus') || this.matchValue('addition')) {
|
|
1763
1984
|
const right = this.parseMultiplicative(lang)
|
|
1764
1985
|
left = { type: 'BinaryExpression', operator: '+', left, right }
|
|
1765
|
-
} else if (this.match(TokenType.MINUS) || this.matchValue('moins')) {
|
|
1986
|
+
} else if (this.match(TokenType.MINUS) || this.matchValue('moins') || this.matchValue('soustraction')) {
|
|
1766
1987
|
const right = this.parseMultiplicative(lang)
|
|
1767
1988
|
left = { type: 'BinaryExpression', operator: '-', left, right }
|
|
1768
1989
|
} else {
|
|
@@ -1777,10 +1998,10 @@ class EtherParser {
|
|
|
1777
1998
|
let left = this.parseUnary(lang)
|
|
1778
1999
|
|
|
1779
2000
|
while (true) {
|
|
1780
|
-
if (this.match(TokenType.STAR) || this.matchValue('fois') || this.matchValue('multiplie')) {
|
|
2001
|
+
if (this.match(TokenType.STAR) || this.matchValue('fois') || this.matchValue('multiplie') || this.matchValue('multiplication')) {
|
|
1781
2002
|
const right = this.parseUnary(lang)
|
|
1782
2003
|
left = { type: 'BinaryExpression', operator: '*', left, right }
|
|
1783
|
-
} else if (this.match(TokenType.SLASH) || this.matchValue('divise')) {
|
|
2004
|
+
} else if (this.match(TokenType.SLASH) || this.matchValue('divise') || this.matchValue('division')) {
|
|
1784
2005
|
const right = this.parseUnary(lang)
|
|
1785
2006
|
left = { type: 'BinaryExpression', operator: '/', left, right }
|
|
1786
2007
|
} else if (this.match(TokenType.PERCENT) || this.matchValue('modulo')) {
|
|
@@ -1877,8 +2098,19 @@ class EtherParser {
|
|
|
1877
2098
|
return { type: 'Literal', value: undefined }
|
|
1878
2099
|
}
|
|
1879
2100
|
|
|
2101
|
+
const translated = this.translateJSIdentifier(token.value)
|
|
1880
2102
|
this.advance()
|
|
1881
|
-
|
|
2103
|
+
|
|
2104
|
+
if (translated && translated.includes('.')) {
|
|
2105
|
+
const parts = translated.split('.')
|
|
2106
|
+
let expr = { type: 'Identifier', name: parts[0] }
|
|
2107
|
+
for (let i = 1; i < parts.length; i++) {
|
|
2108
|
+
expr = { type: 'MemberExpression', object: expr, property: parts[i] }
|
|
2109
|
+
}
|
|
2110
|
+
return expr
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
return { type: 'Identifier', name: translated || token.value }
|
|
1882
2114
|
}
|
|
1883
2115
|
|
|
1884
2116
|
if (token.type === TokenType.LBRACKET) {
|