ether-code 0.8.3 → 0.8.4

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.8.3'
9
+ const VERSION = '0.8.4'
10
10
 
11
11
  const COLORS = {
12
12
  reset: '\x1b[0m',
@@ -101,6 +101,8 @@ class PHPGenerator {
101
101
 
102
102
  const generators = {
103
103
  'Program': () => this.generateProgram(node),
104
+ 'DeclareStatement': () => this.generateDeclareStatement(node),
105
+ 'NamespaceDeclaration': () => this.generateNamespaceDeclaration(node),
104
106
  'FunctionDeclaration': () => this.generateFunctionDeclaration(node),
105
107
  'ClassDeclaration': () => this.generateClassDeclaration(node),
106
108
  'InterfaceDeclaration': () => this.generateInterfaceDeclaration(node),
@@ -110,6 +112,7 @@ class PHPGenerator {
110
112
  'PropertyDeclaration': () => this.generatePropertyDeclaration(node),
111
113
  'VariableDeclaration': () => this.generateVariableDeclaration(node),
112
114
  'ConstantDeclaration': () => this.generateConstantDeclaration(node),
115
+ 'DefineDeclaration': () => this.generateDefineDeclaration(node),
113
116
  'IfStatement': () => this.generateIfStatement(node),
114
117
  'ForStatement': () => this.generateForStatement(node),
115
118
  'ForEachStatement': () => this.generateForEachStatement(node),
@@ -176,6 +179,33 @@ class PHPGenerator {
176
179
  }
177
180
  }
178
181
 
182
+ generateDeclareStatement(node) {
183
+ const directives = (node.directives || []).map(d => {
184
+ const name = this.safeString(d.name)
185
+ const value = this.generateNode(d.value)
186
+ return `${name}=${value}`
187
+ }).join(', ')
188
+
189
+ this.writeLine(`declare(${directives});`)
190
+ this.writeLine('')
191
+ }
192
+
193
+ generateNamespaceDeclaration(node) {
194
+ const name = this.safeString(node.name)
195
+ this.writeLine(`namespace ${name};`)
196
+ this.writeLine('')
197
+
198
+ if (node.body) {
199
+ this.generateNode(node.body)
200
+ }
201
+ }
202
+
203
+ generateDefineDeclaration(node) {
204
+ const name = this.safeString(node.name)
205
+ const value = this.generateNode(node.value)
206
+ this.writeLine(`define('${name}', ${value});`)
207
+ }
208
+
179
209
  generateFunctionDeclaration(node) {
180
210
  const name = this.safeString(node.name || node.id?.name || 'anonymous')
181
211
  const translatedName = this.translate(name)
@@ -465,7 +495,7 @@ class PHPGenerator {
465
495
  generateVariableDeclaration(node) {
466
496
  for (const decl of node.declarations || [node]) {
467
497
  const name = this.safeString(decl.name || decl.id?.name || decl.id)
468
- const varName = '$' + this.translate(name)
498
+ const varName = '$' + name
469
499
 
470
500
  if (decl.init !== undefined) {
471
501
  const value = this.generateNode(decl.init)
@@ -640,7 +670,8 @@ class PHPGenerator {
640
670
  }
641
671
 
642
672
  generateEchoStatement(node) {
643
- const args = (node.arguments || [node.argument]).filter(Boolean).map(a => this.generateNode(a)).join(', ')
673
+ const exprs = node.expressions || node.arguments || [node.argument]
674
+ const args = exprs.filter(Boolean).map(a => this.generateNode(a)).join(', ')
644
675
  this.writeLine(`echo ${args};`)
645
676
  }
646
677
 
@@ -656,10 +687,19 @@ class PHPGenerator {
656
687
  }
657
688
 
658
689
  generateUseStatement(node) {
659
- const name = this.safeString(node.name || node.source)
660
- const alias = node.alias ? ' as ' + node.alias : ''
661
- const type = node.type === 'function' ? 'function ' : (node.type === 'const' ? 'const ' : '')
662
- this.writeLine(`use ${type}${name}${alias};`)
690
+ const typePrefix = node.useType === 'function' ? 'function ' : (node.useType === 'const' ? 'const ' : '')
691
+
692
+ if (node.imports && node.imports.length > 0) {
693
+ for (const imp of node.imports) {
694
+ const path = this.safeString(imp.path)
695
+ const alias = imp.alias ? ' as ' + imp.alias : ''
696
+ this.writeLine(`use ${typePrefix}${path}${alias};`)
697
+ }
698
+ } else {
699
+ const name = this.safeString(node.name || node.source)
700
+ const alias = node.alias ? ' as ' + node.alias : ''
701
+ this.writeLine(`use ${typePrefix}${name}${alias};`)
702
+ }
663
703
  }
664
704
 
665
705
  generateIncludeStatement(node) {
@@ -878,43 +918,41 @@ class PHPGenerator {
878
918
  if (!node) return '$var'
879
919
 
880
920
  const name = this.safeString(node.name || node.id?.name || node)
881
- const translated = this.translate(name)
882
- const translatedStr = String(translated)
921
+ const nameStr = String(name)
883
922
 
884
- if (translatedStr.startsWith('$')) return translatedStr
885
- return '$' + translatedStr
923
+ if (nameStr.startsWith('$')) return nameStr
924
+ return '$' + nameStr
886
925
  }
887
926
 
888
927
  generateIdentifier(node) {
889
928
  if (!node) return '$var'
890
929
 
891
930
  const name = this.safeString(node.name || node.id?.name || node)
892
- const translated = this.translate(name)
893
- const translatedStr = String(translated)
931
+ const nameStr = String(name)
894
932
 
895
- if (translatedStr.startsWith('$')) return translatedStr
933
+ if (nameStr.startsWith('$')) return nameStr
896
934
 
897
935
  const keywords = [
898
936
  'true', 'false', 'null',
899
937
  'self', 'parent', 'static',
900
938
  'this', '$this'
901
939
  ]
902
- if (keywords.includes(translatedStr.toLowerCase())) {
903
- if (translatedStr.toLowerCase() === 'this') return '$this'
904
- return translatedStr
940
+ if (keywords.includes(nameStr.toLowerCase())) {
941
+ if (nameStr.toLowerCase() === 'this') return '$this'
942
+ return nameStr
905
943
  }
906
944
 
907
- if (/^[A-Z]/.test(translatedStr)) return translatedStr
945
+ if (/^[A-Z]/.test(nameStr)) return nameStr
908
946
 
909
- if (translatedStr.includes('(') || translatedStr.includes('::')) return translatedStr
947
+ if (nameStr.includes('(') || nameStr.includes('::')) return nameStr
910
948
 
911
949
  const superglobals = ['_GET', '_POST', '_SERVER', '_SESSION', '_COOKIE', '_FILES', '_REQUEST', '_ENV', 'GLOBALS']
912
- const upper = translatedStr.toUpperCase()
913
- if (superglobals.includes(translatedStr) || superglobals.includes(upper)) {
950
+ const upper = nameStr.toUpperCase()
951
+ if (superglobals.includes(nameStr) || superglobals.includes(upper)) {
914
952
  return '$' + upper
915
953
  }
916
954
 
917
- return '$' + translatedStr
955
+ return '$' + nameStr
918
956
  }
919
957
 
920
958
  generateLiteral(node) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ether-code",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "description": "Ether - Le langage intentionnel",
5
5
  "main": "cli/compiler.js",
6
6
  "bin": {
@@ -278,6 +278,10 @@ class EtherParserPHP extends EtherParserBase {
278
278
 
279
279
  const value = token.value != null ? this.normalizeAccents(String(token.value).toLowerCase()) : ''
280
280
 
281
+ if (this.isDeclare(value)) {
282
+ return this.parseDeclare(lang)
283
+ }
284
+
281
285
  if (this.isNamespace(value)) {
282
286
  return this.parseNamespace(lang)
283
287
  }
@@ -371,7 +375,17 @@ class EtherParserPHP extends EtherParserBase {
371
375
  }
372
376
 
373
377
  isNamespace(value) {
374
- return ['namespace', 'espace de noms'].includes(value)
378
+ if (value === 'namespace') return true
379
+ if (value === 'espace') {
380
+ const next1 = this.peek(1)
381
+ const next2 = this.peek(2)
382
+ if (next1 && next2) {
383
+ const val1 = this.normalizeAccents(String(next1.value).toLowerCase())
384
+ const val2 = this.normalizeAccents(String(next2.value).toLowerCase())
385
+ if (val1 === 'de' && val2 === 'noms') return true
386
+ }
387
+ }
388
+ return false
375
389
  }
376
390
 
377
391
  isUse(value) {
@@ -469,8 +483,54 @@ class EtherParserPHP extends EtherParserBase {
469
483
  return value === 'match'
470
484
  }
471
485
 
472
- parseNamespace(lang) {
486
+ isDeclare(value) {
487
+ return ['declare', 'declarer', 'déclarer'].includes(value)
488
+ }
489
+
490
+ parseDeclare(lang) {
473
491
  this.advance()
492
+
493
+ const directives = []
494
+
495
+ if (this.match(TokenType.LPAREN)) {
496
+ do {
497
+ const nameToken = this.current()
498
+ const name = nameToken ? this.safeStr(nameToken.value) : ''
499
+ this.advance()
500
+
501
+ this.match(TokenType.EQUALS)
502
+
503
+ const value = this.parseExpression(lang)
504
+ directives.push({ name, value })
505
+ } while (this.match(TokenType.COMMA))
506
+
507
+ this.match(TokenType.RPAREN)
508
+ } else {
509
+ const nameToken = this.current()
510
+ const name = nameToken ? this.safeStr(nameToken.value) : ''
511
+ this.advance()
512
+
513
+ this.match(TokenType.EQUALS)
514
+
515
+ const value = this.parseExpression(lang)
516
+ directives.push({ name, value })
517
+ }
518
+
519
+ return {
520
+ type: 'DeclareStatement',
521
+ directives: directives
522
+ }
523
+ }
524
+
525
+ parseNamespace(lang) {
526
+ const first = this.advance()
527
+ const firstVal = this.normalizeAccents(String(first.value).toLowerCase())
528
+
529
+ if (firstVal === 'espace') {
530
+ this.advance()
531
+ this.advance()
532
+ }
533
+
474
534
  const name = this.parseNamespacePath(lang)
475
535
  this.skipNewlines()
476
536