ether-code 0.6.8 → 0.7.0

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 CHANGED
@@ -6,7 +6,7 @@ const http = require('http')
6
6
  const { EtherCompiler } = require('./compiler')
7
7
  const { Watcher } = require('./watcher')
8
8
 
9
- const VERSION = '0.6.8'
9
+ const VERSION = '0.7.0'
10
10
 
11
11
  const COLORS = {
12
12
  reset: '\x1b[0m',
@@ -21,15 +21,15 @@ const COLORS = {
21
21
  }
22
22
 
23
23
  const MIME_TYPES = {
24
- '.html': 'text/html',
25
- '.css': 'text/css',
26
- '.js': 'application/javascript',
27
- '.json': 'application/json',
24
+ '.html': 'text/html; charset=utf-8',
25
+ '.css': 'text/css; charset=utf-8',
26
+ '.js': 'application/javascript; charset=utf-8',
27
+ '.json': 'application/json; charset=utf-8',
28
28
  '.png': 'image/png',
29
29
  '.jpg': 'image/jpeg',
30
30
  '.jpeg': 'image/jpeg',
31
31
  '.gif': 'image/gif',
32
- '.svg': 'image/svg+xml',
32
+ '.svg': 'image/svg+xml; charset=utf-8',
33
33
  '.ico': 'image/x-icon',
34
34
  '.woff': 'font/woff',
35
35
  '.woff2': 'font/woff2',
@@ -496,7 +496,7 @@ function startServer(outDir, publicDir, port) {
496
496
  const ext = path.extname(filePath).toLowerCase()
497
497
  const mime = MIME_TYPES[ext] || 'application/octet-stream'
498
498
 
499
- fs.readFile(filePath, function(err, content) {
499
+ fs.readFile(filePath, 'utf-8', function(err, content) {
500
500
  if (err) {
501
501
  res.writeHead(500)
502
502
  res.end('Erreur: ' + err.message)
@@ -504,17 +504,15 @@ function startServer(outDir, publicDir, port) {
504
504
  }
505
505
 
506
506
  if (ext === '.html') {
507
- let html = content.toString()
508
- if (html.indexOf('</body>') !== -1) {
509
- html = html.replace('</body>', liveReloadScript + '</body>')
507
+ if (content.indexOf('</body>') !== -1) {
508
+ content = content.replace('</body>', liveReloadScript + '</body>')
510
509
  } else {
511
- html = html + liveReloadScript
510
+ content = content + liveReloadScript
512
511
  }
513
- content = html
514
512
  }
515
513
 
516
514
  res.writeHead(200, { 'Content-Type': mime })
517
- res.end(content)
515
+ res.end(content, 'utf-8')
518
516
  })
519
517
  })
520
518
 
@@ -557,8 +555,8 @@ function cmdInit() {
557
555
  if (!fs.existsSync(imagesDir)) fs.mkdirSync(imagesDir, { recursive: true })
558
556
  if (!fs.existsSync(videosDir)) fs.mkdirSync(videosDir, { recursive: true })
559
557
 
560
- fs.writeFileSync(path.join(imagesDir, 'logo.svg'), LOGO_SVG)
561
- fs.writeFileSync(path.join(publicDir, 'favicon.svg'), FAVICON_SVG)
558
+ fs.writeFileSync(path.join(imagesDir, 'logo.svg'), LOGO_SVG, 'utf-8')
559
+ fs.writeFileSync(path.join(publicDir, 'favicon.svg'), FAVICON_SVG, 'utf-8')
562
560
 
563
561
  const configContent = 'module.exports = {\n src: "src",\n out: "dist",\n public: "public",\n port: 3000,\n lang: "fr"\n}\n'
564
562
 
@@ -675,11 +673,11 @@ console.log("Ether v0.3.8 ready!")
675
673
 
676
674
  const packageContent = '{\n "name": "mon-projet-ether",\n "version": "1.0.0",\n "scripts": {\n "dev": "ether dev",\n "build": "ether build"\n }\n}\n'
677
675
 
678
- fs.writeFileSync(path.join(projectDir, 'ether.config.js'), configContent)
679
- fs.writeFileSync(path.join(srcDir, 'index.eth'), indexContent)
680
- fs.writeFileSync(path.join(srcDir, 'styles.eth'), STYLES_ETH)
681
- fs.writeFileSync(path.join(srcDir, 'app.eth'), appContent)
682
- fs.writeFileSync(path.join(projectDir, 'package.json'), packageContent)
676
+ fs.writeFileSync(path.join(projectDir, 'ether.config.js'), configContent, 'utf-8')
677
+ fs.writeFileSync(path.join(srcDir, 'index.eth'), indexContent, 'utf-8')
678
+ fs.writeFileSync(path.join(srcDir, 'styles.eth'), STYLES_ETH, 'utf-8')
679
+ fs.writeFileSync(path.join(srcDir, 'app.eth'), appContent, 'utf-8')
680
+ fs.writeFileSync(path.join(projectDir, 'package.json'), packageContent, 'utf-8')
683
681
 
684
682
  logSuccess('Projet initialise!')
685
683
  console.log('')
@@ -745,7 +743,7 @@ function cmdBuild(options) {
745
743
  fs.mkdirSync(outDirPath, { recursive: true })
746
744
  }
747
745
 
748
- fs.writeFileSync(outPath, output.content)
746
+ fs.writeFileSync(outPath, output.content, 'utf-8')
749
747
 
750
748
  if (options.verbose) {
751
749
  logSuccess(relativePath + ' -> ' + output.path)
@@ -825,7 +823,7 @@ function cmdDev(options) {
825
823
  fs.mkdirSync(outDirPath, { recursive: true })
826
824
  }
827
825
 
828
- fs.writeFileSync(outPath, output.content)
826
+ fs.writeFileSync(outPath, output.content, 'utf-8')
829
827
  logSuccess('-> ' + output.path)
830
828
  }
831
829
  }
@@ -814,7 +814,7 @@ class JSGenerator {
814
814
  word
815
815
  }
816
816
 
817
- translate(word) {
817
+ translate(word, isMethod = false) {
818
818
  const lower = word.toLowerCase()
819
819
 
820
820
  if (this.keywordMap[lower]) {
@@ -823,13 +823,17 @@ class JSGenerator {
823
823
  if (this.operatorMap[lower]) {
824
824
  return this.operatorMap[lower]
825
825
  }
826
- if (this.methodMap[lower]) {
826
+ if (isMethod && this.methodMap[lower]) {
827
827
  return this.methodMap[lower]
828
828
  }
829
829
 
830
830
  return word
831
831
  }
832
832
 
833
+ translateMethod(word) {
834
+ return this.translate(word, true)
835
+ }
836
+
833
837
  translateOperator(op) {
834
838
  const lower = op.toLowerCase()
835
839
  return this.operatorMap[lower] || op
@@ -953,8 +957,10 @@ class JSGenerator {
953
957
  return this.generateSpreadElement(node)
954
958
  case 'RestElement':
955
959
  return this.generateRestElement(node)
960
+ case 'Parameter':
961
+ return this.generateParam(node)
956
962
  case 'Identifier':
957
- return this.translate(node.name)
963
+ return node.name
958
964
  case 'PrivateIdentifier':
959
965
  return this.generatePrivateIdentifier(node)
960
966
  case 'Literal':
@@ -1013,12 +1019,20 @@ class JSGenerator {
1013
1019
  }
1014
1020
  kind = kindTranslations[kind.toLowerCase()] || this.translate(kind)
1015
1021
 
1016
- const declarations = node.declarations || []
1017
-
1018
- for (const decl of declarations) {
1019
- const name = this.generateNode(decl.id || decl.name)
1020
- if (decl.init) {
1021
- const init = this.generateNode(decl.init)
1022
+ if (node.declarations && node.declarations.length > 0) {
1023
+ for (const decl of node.declarations) {
1024
+ const name = this.generateNode(decl.id || decl.name)
1025
+ if (decl.init) {
1026
+ const init = this.generateNode(decl.init)
1027
+ this.writeLine(`${kind} ${name} = ${init};`)
1028
+ } else {
1029
+ this.writeLine(`${kind} ${name};`)
1030
+ }
1031
+ }
1032
+ } else if (node.name) {
1033
+ const name = typeof node.name === 'string' ? node.name : this.generateNode(node.name)
1034
+ if (node.init) {
1035
+ const init = this.generateNode(node.init)
1022
1036
  this.writeLine(`${kind} ${name} = ${init};`)
1023
1037
  } else {
1024
1038
  this.writeLine(`${kind} ${name};`)
@@ -1029,8 +1043,8 @@ class JSGenerator {
1029
1043
  generateFunctionDeclaration(node) {
1030
1044
  const async = node.async ? 'async ' : ''
1031
1045
  const generator = node.generator ? '*' : ''
1032
- const name = node.id ? this.translate(node.id.name || node.id) : ''
1033
- const params = (node.params || []).map(p => this.generateNode(p)).join(', ')
1046
+ const name = node.name || (node.id ? (node.id.name || node.id) : '')
1047
+ const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
1034
1048
 
1035
1049
  this.writeLine(`${async}function${generator} ${name}(${params}) {`)
1036
1050
  this.indent++
@@ -1043,8 +1057,8 @@ class JSGenerator {
1043
1057
  generateFunctionExpression(node) {
1044
1058
  const async = node.async ? 'async ' : ''
1045
1059
  const generator = node.generator ? '*' : ''
1046
- const name = node.id ? this.translate(node.id.name || node.id) : ''
1047
- const params = (node.params || []).map(p => this.generateNode(p)).join(', ')
1060
+ const name = node.name || (node.id ? (node.id.name || node.id) : '')
1061
+ const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
1048
1062
 
1049
1063
  let body = ''
1050
1064
  const savedOutput = this.output
@@ -1058,6 +1072,26 @@ class JSGenerator {
1058
1072
  return `${async}function${generator} ${name}(${params}) {\n${body}\n${this.getIndent()}}`
1059
1073
  }
1060
1074
 
1075
+ generateParam(param) {
1076
+ if (!param) return ''
1077
+ if (typeof param === 'string') return param
1078
+ if (param.type === 'Identifier') return param.name
1079
+ if (param.type === 'Parameter') {
1080
+ let result = param.name
1081
+ if (param.default) {
1082
+ result += ' = ' + this.generateNode(param.default)
1083
+ }
1084
+ return result
1085
+ }
1086
+ if (param.type === 'RestElement') {
1087
+ return '...' + this.generateParam(param.argument)
1088
+ }
1089
+ if (param.type === 'AssignmentPattern') {
1090
+ return this.generateNode(param.left) + ' = ' + this.generateNode(param.right)
1091
+ }
1092
+ return param.name || this.generateNode(param)
1093
+ }
1094
+
1061
1095
  generateClassDeclaration(node) {
1062
1096
  const name = node.id ? (node.id.name || node.id) : ''
1063
1097
  const extend = node.superClass ? ` extends ${this.generateNode(node.superClass)}` : ''
@@ -1172,7 +1206,7 @@ class JSGenerator {
1172
1206
  }
1173
1207
 
1174
1208
  generateIfStatement(node) {
1175
- const test = this.generateNode(node.test)
1209
+ const test = this.generateNode(node.test || node.condition)
1176
1210
  this.writeLine(`if (${test}) {`)
1177
1211
  this.indent++
1178
1212
  this.generateNode(node.consequent)
@@ -1180,8 +1214,46 @@ class JSGenerator {
1180
1214
 
1181
1215
  if (node.alternate) {
1182
1216
  if (node.alternate.type === 'IfStatement') {
1183
- this.output = this.output.trimEnd() + ' else '
1184
- this.generateIfStatement(node.alternate)
1217
+ const altTest = this.generateNode(node.alternate.test || node.alternate.condition)
1218
+ this.writeLine(`} else if (${altTest}) {`)
1219
+ this.indent++
1220
+ this.generateNode(node.alternate.consequent)
1221
+ this.indent--
1222
+ if (node.alternate.alternate) {
1223
+ if (node.alternate.alternate.type === 'IfStatement') {
1224
+ this.generateElseIfChain(node.alternate.alternate)
1225
+ } else {
1226
+ this.writeLine('} else {')
1227
+ this.indent++
1228
+ this.generateNode(node.alternate.alternate)
1229
+ this.indent--
1230
+ this.writeLine('}')
1231
+ }
1232
+ } else {
1233
+ this.writeLine('}')
1234
+ }
1235
+ } else {
1236
+ this.writeLine('} else {')
1237
+ this.indent++
1238
+ this.generateNode(node.alternate)
1239
+ this.indent--
1240
+ this.writeLine('}')
1241
+ }
1242
+ } else {
1243
+ this.writeLine('}')
1244
+ }
1245
+ }
1246
+
1247
+ generateElseIfChain(node) {
1248
+ const test = this.generateNode(node.test || node.condition)
1249
+ this.writeLine(`} else if (${test}) {`)
1250
+ this.indent++
1251
+ this.generateNode(node.consequent)
1252
+ this.indent--
1253
+
1254
+ if (node.alternate) {
1255
+ if (node.alternate.type === 'IfStatement') {
1256
+ this.generateElseIfChain(node.alternate)
1185
1257
  } else {
1186
1258
  this.writeLine('} else {')
1187
1259
  this.indent++
@@ -1195,15 +1267,44 @@ class JSGenerator {
1195
1267
  }
1196
1268
 
1197
1269
  generateForStatement(node) {
1270
+ if (node.iterable || node.variable) {
1271
+ const varName = node.variable || 'item'
1272
+ const iterable = this.generateNode(node.iterable)
1273
+ this.writeLine(`for (const ${varName} of ${iterable}) {`)
1274
+ this.indent++
1275
+ this.generateNode(node.body)
1276
+ this.indent--
1277
+ this.writeLine('}')
1278
+ return
1279
+ }
1280
+
1281
+ if (node.start !== undefined && node.end !== undefined) {
1282
+ const varName = node.variable || 'i'
1283
+ const start = this.generateNode(node.start)
1284
+ const end = this.generateNode(node.end)
1285
+ const step = node.step ? this.generateNode(node.step) : '1'
1286
+ this.writeLine(`for (let ${varName} = ${start}; ${varName} < ${end}; ${varName} += ${step}) {`)
1287
+ this.indent++
1288
+ this.generateNode(node.body)
1289
+ this.indent--
1290
+ this.writeLine('}')
1291
+ return
1292
+ }
1293
+
1198
1294
  let init = ''
1199
1295
  if (node.init) {
1200
1296
  if (node.init.type === 'VariableDeclaration') {
1201
1297
  const kind = this.translate(node.init.kind || 'let')
1202
- const decls = node.init.declarations.map(d => {
1203
- const name = this.generateNode(d.id)
1204
- return d.init ? `${name} = ${this.generateNode(d.init)}` : name
1205
- }).join(', ')
1206
- init = `${kind} ${decls}`
1298
+ if (node.init.declarations && node.init.declarations.length > 0) {
1299
+ const decls = node.init.declarations.map(d => {
1300
+ const name = this.generateNode(d.id || d.name)
1301
+ return d.init ? `${name} = ${this.generateNode(d.init)}` : name
1302
+ }).join(', ')
1303
+ init = `${kind} ${decls}`
1304
+ } else if (node.init.name) {
1305
+ const name = node.init.name
1306
+ init = node.init.init ? `${kind} ${name} = ${this.generateNode(node.init.init)}` : `${kind} ${name}`
1307
+ }
1207
1308
  } else {
1208
1309
  init = this.generateNode(node.init)
1209
1310
  }
@@ -1221,14 +1322,26 @@ class JSGenerator {
1221
1322
  generateForOfStatement(node) {
1222
1323
  this.pushContext('loop')
1223
1324
  let left
1224
- if (node.left.type === 'VariableDeclaration') {
1225
- const kind = this.translate(node.left.kind || 'const')
1226
- const name = this.generateNode(node.left.declarations[0].id)
1227
- left = `${kind} ${name}`
1325
+ if (node.left) {
1326
+ if (node.left.type === 'VariableDeclaration') {
1327
+ const kind = this.translate(node.left.kind || 'const')
1328
+ if (node.left.declarations && node.left.declarations.length > 0) {
1329
+ const name = this.generateNode(node.left.declarations[0].id || node.left.declarations[0].name)
1330
+ left = `${kind} ${name}`
1331
+ } else if (node.left.name) {
1332
+ left = `${kind} ${node.left.name}`
1333
+ } else {
1334
+ left = `${kind} item`
1335
+ }
1336
+ } else {
1337
+ left = this.generateNode(node.left)
1338
+ }
1339
+ } else if (node.variable) {
1340
+ left = `const ${node.variable}`
1228
1341
  } else {
1229
- left = this.generateNode(node.left)
1342
+ left = 'const item'
1230
1343
  }
1231
- const right = this.generateNode(node.right)
1344
+ const right = this.generateNode(node.right || node.iterable)
1232
1345
 
1233
1346
  this.writeLine(`for (${left} of ${right}) {`)
1234
1347
  this.indent++
@@ -1241,14 +1354,26 @@ class JSGenerator {
1241
1354
  generateForInStatement(node) {
1242
1355
  this.pushContext('loop')
1243
1356
  let left
1244
- if (node.left.type === 'VariableDeclaration') {
1245
- const kind = this.translate(node.left.kind || 'const')
1246
- const name = this.generateNode(node.left.declarations[0].id)
1247
- left = `${kind} ${name}`
1357
+ if (node.left) {
1358
+ if (node.left.type === 'VariableDeclaration') {
1359
+ const kind = this.translate(node.left.kind || 'const')
1360
+ if (node.left.declarations && node.left.declarations.length > 0) {
1361
+ const name = this.generateNode(node.left.declarations[0].id || node.left.declarations[0].name)
1362
+ left = `${kind} ${name}`
1363
+ } else if (node.left.name) {
1364
+ left = `${kind} ${node.left.name}`
1365
+ } else {
1366
+ left = `${kind} key`
1367
+ }
1368
+ } else {
1369
+ left = this.generateNode(node.left)
1370
+ }
1371
+ } else if (node.variable) {
1372
+ left = `const ${node.variable}`
1248
1373
  } else {
1249
- left = this.generateNode(node.left)
1374
+ left = 'const key'
1250
1375
  }
1251
- const right = this.generateNode(node.right)
1376
+ const right = this.generateNode(node.right || node.iterable)
1252
1377
 
1253
1378
  this.writeLine(`for (${left} in ${right}) {`)
1254
1379
  this.indent++
@@ -1550,7 +1675,7 @@ class JSGenerator {
1550
1675
  return `${object}[${property}]`
1551
1676
  }
1552
1677
 
1553
- const translatedProperty = this.translate(property)
1678
+ const translatedProperty = this.translateMethod(property)
1554
1679
 
1555
1680
  if (translatedProperty.includes('.')) {
1556
1681
  const parts = translatedProperty.split('.')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ether-code",
3
- "version": "0.6.8",
3
+ "version": "0.7.0",
4
4
  "description": "Ether - Le langage intentionnel",
5
5
  "main": "cli/compiler.js",
6
6
  "bin": {