vladx 1.1.1 → 1.2.3

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.
@@ -0,0 +1,320 @@
1
+ # 🇮🇹 Documentazione Ufficiale VladX
2
+
3
+ Benvenuti nella documentazione ufficiale di **VladX**, un linguaggio di programmazione moderno con **sintassi italiana**. VladX è progettato per essere leggibile, intuitivo e completo, ideale per chi vuole programmare in modo naturale senza rinunciare alla potenza di un linguaggio moderno.
4
+
5
+ ---
6
+
7
+ ## 📑 Indice
8
+
9
+ 1. [Installazione](#-installazione)
10
+ 2. [Guida Rapida CLI](#-guida-rapida-cli)
11
+ 3. [Sintassi di Base](#-sintassi-di-base)
12
+ 4. [Tipi di Dati](#-tipi-di-dati)
13
+ 5. [Operatori](#-operatori)
14
+ 6. [Controllo del Flusso](#-controllo-del-flusso)
15
+ 7. [Funzioni](#-funzioni)
16
+ 8. [Moduli](#-moduli)
17
+ 9. [Libreria Standard (StdLib)](#-libreria-standard-stdlib)
18
+ 10. [Funzioni Globali](#-funzioni-globali)
19
+ 11. [Metodi di Array e Oggetti](#-metodi-di-array-e-oggetti)
20
+ 12. [VladPM (Package Manager)](#-vladpm-package-manager)
21
+ 13. [Esempi Completi](#-esempi-completi)
22
+
23
+ ---
24
+
25
+ ## 🚀 Installazione
26
+
27
+ Puoi installare VladX sul tuo sistema in due modi:
28
+
29
+ ### Tramite NPM (Consigliato)
30
+ Se hai Node.js installato, puoi installare VladX globalmente con un semplice comando:
31
+ ```bash
32
+ npm install -g vladx
33
+ ```
34
+
35
+ ### Tramite Script Bash
36
+ Puoi utilizzare lo script di installazione incluso nel repository:
37
+ ```bash
38
+ chmod +x install.sh
39
+ ./install.sh
40
+ ```
41
+
42
+ ---
43
+
44
+ ## 🛠 Guida Rapida CLI
45
+
46
+ Il comando principale è `vladx`.
47
+
48
+ - **REPL Interattivo**: Digita semplicemente `vladx` per entrare nella console interattiva.
49
+ - **Esecuzione Script**: `vladx mio_programma.vx`
50
+ - **Analisi AST**: `vladx ast mio_programma.vx` (mostra la struttura interna del codice).
51
+ - **Lexing**: `vladx lex mio_programma.vx` (mostra i token analizzati).
52
+
53
+ ---
54
+
55
+ ## 📝 Sintassi di Base
56
+
57
+ ### Commenti
58
+ ```javascript
59
+ // Questo è un commento su riga singola
60
+ /* Questo è un commento
61
+ multilinea */
62
+ ```
63
+
64
+ ### Variabili e Costanti
65
+ In VladX, le variabili vengono dichiarate con la parola chiave `variabile` e le costanti con `costante`.
66
+
67
+ ```javascript
68
+ variabile nome = "Vlad";
69
+ nome = "VladX"; // Ok, è una variabile
70
+
71
+ costante VERSIONE = 1.2;
72
+ // VERSIONE = 1.3; // Errore! Non puoi riassegnare una costante
73
+ ```
74
+
75
+ ---
76
+
77
+ ## 💎 Tipi di Dati
78
+
79
+ VladX supporta i seguenti tipi di dati fondamentali:
80
+
81
+ | Tipo | Esempio |
82
+ | :--- | :--- |
83
+ | **Numero** | `10`, `3.14`, `-5` |
84
+ | **Stringa** | `"Ciao Mondo"`, `'Esempio'` |
85
+ | **Booleano** | `vero`, `falso` |
86
+ | **Nullo** | `nullo` |
87
+ | **Array** | `[1, 2, 3, "test"]` |
88
+ | **Oggetto** | `{ nome: "Vlad", eta: 20 }` |
89
+
90
+ ---
91
+
92
+ ## ⚡ Operatori
93
+
94
+ ### Aritmetici
95
+ Supporto completo per le operazioni matematiche:
96
+ - `+` (Addizione / Concatenazione stringhe)
97
+ - `-` (Sottrazione)
98
+ - `*` (Moltiplicazione)
99
+ - `/` (Divisione)
100
+ - `%` (Resto della divisione)
101
+ - `++` / `--` (Incremento e decremento)
102
+
103
+ ### Confronto
104
+ - `==` / `===` (Uguaglianza)
105
+ - `!=` / `!==` (Diversità)
106
+ - `<` / `>` (Minore / Maggiore)
107
+ - `<=` / `>=` (Minore o uguale / Maggiore o uguale)
108
+
109
+ ### Logici
110
+ - `e` (AND logico)
111
+ - `o` (OR logico)
112
+ - `non` (NOT logico)
113
+
114
+ ---
115
+
116
+ ## 🔄 Controllo del Flusso
117
+
118
+ ### Condizionali (se / altrimenti)
119
+ ```javascript
120
+ variabile voto = 8;
121
+
122
+ se (voto >= 6) {
123
+ stampa("Promosso!");
124
+ } altrimenti {
125
+ stampa("Bocciato!");
126
+ }
127
+ ```
128
+
129
+ ### Ciclo Mentre (mentre)
130
+ ```javascript
131
+ variabile contatore = 0;
132
+ mentre (contatore < 5) {
133
+ stampa("Conteggio: " + contatore);
134
+ contatore++;
135
+ }
136
+ ```
137
+
138
+ ### Ciclo Per (per)
139
+ ```javascript
140
+ per (variabile i = 0; i < 3; i++) {
141
+ stampa("Giro numero " + i);
142
+ }
143
+ ```
144
+
145
+ ### Gestione Errori (prova / cattura / finalmente)
146
+ VladX include un sistema robusto per gestire le eccezioni:
147
+ ```javascript
148
+ prova {
149
+ lancia "Qualcosa è andato storto!";
150
+ } cattura (errore) {
151
+ stampa("Errore catturato: " + errore);
152
+ } finalmente {
153
+ stampa("Esecuzione terminata.");
154
+ }
155
+ ```
156
+
157
+ ---
158
+
159
+ ## 📦 Funzioni
160
+
161
+ ### Dichiarazione Funzione
162
+ ```javascript
163
+ funzione saluta(nome) {
164
+ ritorna "Ciao, " + nome + "!";
165
+ }
166
+
167
+ stampa(saluta("Amico"));
168
+ ```
169
+
170
+ ### Arrow Functions
171
+ Sintassi compatta per funzioni rapide:
172
+ ```javascript
173
+ costante quadrato = (n) => n * n;
174
+ stampa(quadrato(4)); // 16
175
+ ```
176
+
177
+ ---
178
+
179
+ ## 🧩 Moduli
180
+
181
+ VladX permette di organizzare il codice in più file.
182
+
183
+ **file: `matematica.vx`**
184
+ ```javascript
185
+ esporta costante PI = 3.14;
186
+ esporta funzione doppia(n) { ritorna n * 2; }
187
+ ```
188
+
189
+ **file: `app.vx`**
190
+ ```javascript
191
+ importa { PI, doppia } da "./matematica.vx";
192
+
193
+ stampa("Il doppio di PI è: " + doppia(PI));
194
+ ```
195
+
196
+ ---
197
+
198
+ ## 📚 Libreria Standard (StdLib)
199
+
200
+ La libreria standard offre strumenti potenti pronti all'uso.
201
+
202
+ ### 📁 Archivio (File System)
203
+ Gestisci i file in modo semplice.
204
+ - `Archivio.leggi(percorso)`: Legge il contenuto di un file.
205
+ - `Archivio.scrivi(percorso, dati)`: Scrive dati in un file.
206
+ - `Archivio.esiste(percorso)`: Verifica se un file esiste.
207
+ - `Archivio.elimina(percorso)`: Rimuove un file.
208
+
209
+ ### 💻 Sistema (OS)
210
+ Interagisci con il sistema operativo.
211
+ - `Sistema.esegui(comando)`: Esegue un comando shell e restituisce l'output.
212
+ - `Sistema.argomenti`: Array degli argomenti passati da riga di comando.
213
+ - `Sistema.piattaforma`: Stringa che indica l'OS (es. "linux", "darwin").
214
+ - `Sistema.cartellaCorrente()`: Percorso della directory attuale.
215
+ - `Sistema.esci(codice)`: Termina il programma.
216
+
217
+ ### 🌐 Rete (HTTP)
218
+ Includi capacità di rete nei tuoi script.
219
+ - `Rete.chiama(url)`: Esegue una richiesta HTTP GET (utilizza curl internamente).
220
+ - `Rete.server(porta, gestore)`: Avvia un server web sulla porta specificata.
221
+
222
+ ```javascript
223
+ funzione mioGestore(richiesta) {
224
+ ritorna {
225
+ stato: 200,
226
+ corpo: "Ciao dal server VladX!",
227
+ intestazioni: { "Content-Type": "text/plain" }
228
+ };
229
+ }
230
+
231
+ Rete.server(8080, mioGestore);
232
+ ```
233
+
234
+ ---
235
+
236
+ ## 🌍 Funzioni Globali
237
+
238
+ Funzioni sempre disponibili senza importazioni:
239
+ - `stampa(valore)`: Mostra un valore nella console.
240
+ - `aspetta(ms)`: Sospende l'esecuzione per il numero specificato di millisecondi.
241
+ - `lunghezza(valore)`: Restituisce la lunghezza di una stringa o array.
242
+ - `tipo(valore)`: Restituisce il tipo del valore (es. "number", "string").
243
+ - `numero(valore)`: Converte in numero.
244
+ - `stringa(valore)`: Converte in stringa.
245
+ - `array(valore)`: Verifica se il valore è un array.
246
+
247
+ ---
248
+
249
+ ## 📊 Metodi di Array e Oggetti
250
+
251
+ ### Array
252
+ Gli array supportano metodi dinamici:
253
+ ```javascript
254
+ variabile lista = [1, 2];
255
+ lista.aggiungi(3); // lista è [1, 2, 3]
256
+ variabile rimosso = lista.rimuovi(); // rimosso = 3, lista è [1, 2]
257
+ stampa(lista.lunghezza); // 2
258
+ ```
259
+
260
+ ### Oggetti
261
+ Accesso alle proprietà tramite punto o parentesi quadre:
262
+ ```javascript
263
+ variabile auto = { marca: "Fiat", modello: "500" };
264
+ stampa(auto.marca); // "Fiat"
265
+ auto.anno = 2022;
266
+ ```
267
+
268
+ ---
269
+
270
+ ## 📦 VladPM (Package Manager)
271
+
272
+ VladPM è lo strumento per gestire le dipendenze e i progetti VladX.
273
+
274
+ - `vladpm init`: Crea un nuovo file `vladx.json` nel progetto.
275
+ - `vladpm install <pacchetto>`: Installa un pacchetto dal registry.
276
+ - `vladpm publish`: Pubblica il progetto nel registry VladX.
277
+ - `vladpm start`: Esegue lo script `start` definito in `vladx.json`.
278
+ - `vladpm run <nome>`: Esegue uno script personalizzato.
279
+
280
+ ---
281
+
282
+ ## 🌟 Esempi Completi
283
+
284
+ #### Fibonacci
285
+ ```javascript
286
+ funzione fibonacci(n) {
287
+ se (n <= 1) {
288
+ ritorna n;
289
+ }
290
+ ritorna fibonacci(n - 1) + fibonacci(n - 2);
291
+ }
292
+
293
+ per (variabile i = 0; i < 10; i++) {
294
+ stampa(fibonacci(i));
295
+ }
296
+ ```
297
+
298
+ #### Client HTTP API
299
+ ```javascript
300
+ variabile risposta = Rete.chiama("https://api.github.com/users/octocat");
301
+ stampa("Nome utente: " + risposta.name);
302
+ stampa("Bio: " + risposta.bio);
303
+ ```
304
+
305
+ #### Generatore di File
306
+ ```javascript
307
+ costante NOME_FILE = "test.txt";
308
+
309
+ se (non Archivio.esiste(NOME_FILE)) {
310
+ Archivio.scrivi(NOME_FILE, "Contenuto generato automaticamente da VladX");
311
+ stampa("File creato con successo!");
312
+ } altrimenti {
313
+ stampa("Il file esiste già. Contenuto:");
314
+ stampa(Archivio.leggi(NOME_FILE));
315
+ }
316
+ ```
317
+
318
+ ---
319
+
320
+ Creato con ❤️ dal team di **VladX**.
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # 🇮🇹 VladX
2
+
3
+ **VladX** è un linguaggio di programmazione moderno con **sintassi italiana**, progettato per essere potente, leggibile e completo. Include un interprete robusto, una libreria standard (StdLib) estesa e un package manager dedicato (**VladPM**).
4
+
5
+ ---
6
+
7
+ ## 🚀 Installazione
8
+
9
+ Puoi installare VladX in due modi:
10
+
11
+ ### Metodo 1: NPM (Consigliato)
12
+ Se hai Node.js installato:
13
+ ```bash
14
+ npm install -g vladx
15
+ ```
16
+
17
+ ### Metodo 2: Script di installazione
18
+ ```bash
19
+ chmod +x install.sh
20
+ ./install.sh
21
+ ```
22
+
23
+ ---
24
+
25
+ ## 🛠️ Utilizzo CLI
26
+
27
+ - `vladx` - Avvia il REPL interattivo.
28
+ - `vladx programma.vx` - Esegue un file VladX.
29
+ - `vladx ast programma.vx` - Mostra l'Abstract Syntax Tree.
30
+ - `vladx lex programma.vx` - Mostra i token analizzati.
31
+
32
+ ---
33
+
34
+ ## 📝 Sintassi in breve
35
+
36
+ ### Variabili e Costanti
37
+ ```javascript
38
+ variabile nome = "Vlad";
39
+ costante PI = 3.14;
40
+ ```
41
+
42
+ ### Controllo del Flusso
43
+ ```javascript
44
+ se (x > 10) {
45
+ stampa("Maggiore di 10");
46
+ } altrimenti {
47
+ stampa("Minore o uguale a 10");
48
+ }
49
+
50
+ per (variabile i = 0; i < 5; i++) {
51
+ stampa(i);
52
+ }
53
+
54
+ mentre (condizione) { ... }
55
+ ```
56
+
57
+ ### Funzioni e Arrow Functions
58
+ ```javascript
59
+ funzione saluta(nome) {
60
+ ritorna "Ciao, " + nome;
61
+ }
62
+
63
+ costante somma = (a, b) => a + b;
64
+ ```
65
+
66
+ ### Gestione Errori (Try/Catch)
67
+ ```javascript
68
+ prova {
69
+ lancia "Ops!";
70
+ } cattura (err) {
71
+ stampa("Errore: " + err);
72
+ } finalmente {
73
+ stampa("Fine.");
74
+ }
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 📦 Sistema Moduli
80
+
81
+ Dividi il tuo codice in più file:
82
+
83
+ ```javascript
84
+ // math.vx
85
+ esporta costante PI = 3.14;
86
+ esporta funzione doppia(n) { ritorna n * 2; }
87
+
88
+ // app.vx
89
+ importa { PI, doppia } da "./math.vx";
90
+ stampa(doppia(PI));
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 📚 Libreria Standard (StdLib)
96
+
97
+ VladX include moduli nativi potenti:
98
+
99
+ - **`Archivio`**: `leggi`, `scrivi`, `esiste`, `elimina`.
100
+ - **`Sistema`**: `esegui` (shell), `argomenti`, `piattaforma`, `esci`.
101
+ - **`Rete`**: `chiama` (HTTP GET), `server` (Crea server web).
102
+
103
+ ---
104
+
105
+ ## 📦 VladPM (Package Manager)
106
+
107
+ VladPM è il gestore di pacchetti ufficiale per VladX.
108
+
109
+ - `vladpm init` - Inizializza un nuovo progetto (`vladx.json`).
110
+ - `vladpm install <nome>` - Installa un pacchetto dal registry.
111
+ - `vladpm publish` - Pubblica il tuo pacchetto.
112
+ - `vladpm start` / `vladpm run <script>` - Esegue gli script definiti nel progetto.
113
+
114
+ ---
115
+
116
+ ## 🌟 Esempi
117
+
118
+ Trovi molti esempi nella cartella `examples/`:
119
+ - `test_eccezioni.vx` - Test try/catch.
120
+ - `test_stdlib_fs.vx` - Test File System.
121
+ - `test_stdlib_rete.vx` - Test HTTP e Server.
122
+ - `moduli/` - Esempio di sistema a moduli.
123
+
124
+ ---
125
+
126
+ Creato con ❤️ per la comunità italiana.
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Test Eccezioni VladX
3
+ */
4
+
5
+ stampa("--- Inizio Test Eccezioni ---");
6
+
7
+ prova {
8
+ stampa("1. Provo a fare qualcosa...");
9
+ lancia "Ops! Qualcosa è andato storto.";
10
+ stampa("Questo non dovrebbe apparire.");
11
+ } cattura (errore) {
12
+ stampa("2. Catturato errore: " + errore);
13
+ } finalmente {
14
+ stampa("3. Questo viene eseguito sempre (finalmente).");
15
+ }
16
+
17
+ stampa("");
18
+
19
+ prova {
20
+ stampa("4. Provo divisione per zero (errore runtime)...");
21
+ variabile x = 10 / 0; // In JS è Infinity, non lancia errore. Proviamo qualcosa che lancia errore.
22
+ stampa("Risultato: " + x);
23
+
24
+ // Forza errore runtime reale (chiamata a non funzione)
25
+ variabile nonFunzione = 10;
26
+ nonFunzione();
27
+ } cattura (err) {
28
+ stampa("5. Catturato errore runtime: " + err);
29
+ } finalmente {
30
+ stampa("6. Fine secondo blocco prova.");
31
+ }
32
+
33
+ stampa("--- Fine Test Eccezioni ---");
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Test Archivio e Sistema
3
+ */
4
+
5
+ stampa("--- Test Sistema ---");
6
+ stampa("Piattaforma: " + Sistema.piattaforma);
7
+ stampa("Cartella Corrente: " + Sistema.cartellaCorrente());
8
+
9
+ stampa("\n--- Test Archivio ---");
10
+ costante fileTest = "test_stdlib.txt";
11
+ costante contenuto = "Questo è un test della StdLib di VladX!";
12
+
13
+ stampa("Scrittura file...");
14
+ Archivio.scrivi(fileTest, contenuto);
15
+
16
+ se (Archivio.esiste(fileTest)) {
17
+ stampa("File creato con successo.");
18
+ costante letto = Archivio.leggi(fileTest);
19
+ stampa("Contenuto letto: " + letto);
20
+
21
+ se (letto == contenuto) {
22
+ stampa("VERIFICA: I contenuti corrispondono.");
23
+ } altrimenti {
24
+ stampa("ERRORE: I contenuti NON corrispondono!");
25
+ }
26
+
27
+ stampa("Eliminazione file...");
28
+ Archivio.elimina(fileTest);
29
+
30
+ se (!Archivio.esiste(fileTest)) {
31
+ stampa("File eliminato con successo.");
32
+ }
33
+ } altrimenti {
34
+ stampa("ERRORE: Il file non è stato creato!");
35
+ }
36
+
37
+ stampa("\n--- Esecuzione comando shell ---");
38
+ prova {
39
+ costante output = Sistema.esegui("ls -l bin/vladx");
40
+ stampa("Output ls: " + output);
41
+ } cattura (err) {
42
+ stampa("Errore esecuzione: " + err);
43
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Test Rete VladX
3
+ */
4
+
5
+ stampa("--- Test Rete.chiama ---");
6
+ prova {
7
+ // Chiamata a JSONPlaceholder per test
8
+ stampa("Eseguo chiamata a JSONPlaceholder...");
9
+ costante post = Rete.chiama("https://jsonplaceholder.typicode.com/posts/1");
10
+
11
+ stampa("Risposta ricevuta!");
12
+ stampa("Titolo: " + post.title);
13
+ stampa("ID: " + post.id);
14
+ } cattura (err) {
15
+ stampa("Errore chiamata: " + err);
16
+ }
17
+
18
+ stampa("\n--- Test Rete.server ---");
19
+ // Creiamo un server che risponde con JSON
20
+ funzione mioGestore(req) {
21
+ stampa("Richiesta ricevuta: " + req.metodo + " " + req.url);
22
+
23
+ ritorna {
24
+ stato: 200,
25
+ intestazioni: { "Content-Type": "application/json" },
26
+ corpo: {
27
+ messaggio: "Ciao dal Server VladX!",
28
+ percorso: req.url,
29
+ metodo: req.metodo
30
+ }
31
+ };
32
+ }
33
+
34
+ // Avviamo il server sulla porta 8080
35
+ // Nota: In questo ambiente il server rimarrà attivo finché non terminiamo lo script.
36
+ // Per il test automatico, lo avviamo e poi usiamo Sistema.esegui per testarlo se possibile,
37
+ // ma Sistema.esegui è sincrono, quindi dovremmo usare un altro approccio se volessimo testarlo automatizzato qui.
38
+ // Per ora lo avviamo semplicemente per conferma visiva.
39
+
40
+ stampa("Avvio server su porta 8080...");
41
+ Rete.server(8080, mioGestore);
42
+
43
+ // Mock test: visto che non possiamo fare chiamate asincrone facilmente nel test suite qui,
44
+ // il test si ferma qui o continua se il server non blocca (http.listen non blocca in Node).
45
+ stampa("Server avviato. Test completato.");
46
+ Sistema.esci(0);
package/install.sh ADDED
@@ -0,0 +1,42 @@
1
+ #!/bin/bash
2
+
3
+ # VladX & VladPM Global Installer
4
+ # 🇮🇹 Script di installazione completa per VladX
5
+
6
+ set -e
7
+
8
+ echo "🚀 Inizio installazione VladX..."
9
+
10
+ # 1. Installazione NVM if not present
11
+ if [ -z "$NVM_DIR" ]; then
12
+ echo "📦 Installazione NVM (Node Version Manager)..."
13
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
14
+
15
+ # Load nvm for current session
16
+ export NVM_DIR="$HOME/.nvm"
17
+ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
18
+ [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
19
+ else
20
+ echo "✅ NVM già installato."
21
+ fi
22
+
23
+ # 2. Installazione Node.js (Ultima versione)
24
+ echo "🌐 Installazione dell'ultima versione di Node.js..."
25
+ nvm install node
26
+ nvm use node
27
+
28
+ # 3. Installazione VladX
29
+ echo "🛠️ Installazione globale di VladX e VladPM dal registry NPM..."
30
+
31
+ npm install -g vladx
32
+
33
+ echo ""
34
+ echo "✅ Installazione completata con successo!"
35
+ echo "Node.js: $(node -v)"
36
+ echo "NPM: $(npm -v)"
37
+ echo ""
38
+ echo "Puoi ora usare i comandi:"
39
+ echo " vladx"
40
+ echo " vladpm"
41
+ echo ""
42
+ echo "🇮🇹 Buona programmazione con VladX!"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vladx",
3
- "version": "1.1.1",
3
+ "version": "1.2.3",
4
4
  "description": "VladX - Linguaggio di programmazione con sintassi italiana",
5
5
  "main": "src/index.js",
6
6
  "type": "commonjs",
@@ -0,0 +1,4 @@
1
+ stampa("Ciao dal programma 1!");
2
+ costante saluti = { matteo: "Ciao!", vlad: "Ehilà!" };
3
+ stampa("Matteo dice: " + saluti.matteo);
4
+ stampa("Vlad dice: " + saluti.vlad);
@@ -0,0 +1,5 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "requires": true,
4
+ "dependencies": {}
5
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "1",
3
+ "version": "1.2.0",
4
+ "description": "",
5
+ "main": "index.vx",
6
+ "scripts": {
7
+ "start": "vladx index.vx",
8
+ "test": "vladx test.vx"
9
+ },
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "MIT",
13
+ "dependencies": {}
14
+ }
@@ -118,6 +118,9 @@ class ArrowFunc {
118
118
 
119
119
  const fs = require('fs');
120
120
  const path = require('path');
121
+ const http = require('http');
122
+ const https = require('https');
123
+ const { execSync } = require('child_process');
121
124
  const { Lexer } = require('../lexer/lexer.js');
122
125
  const { Parser } = require('../parser/parser.js');
123
126
 
@@ -155,6 +158,113 @@ class Interpreter {
155
158
  this.globals.define('array', {
156
159
  call: (_, args) => Array.isArray(args[0])
157
160
  });
161
+
162
+ this.globals.define('aspetta', {
163
+ call: (_, args) => {
164
+ const ms = args[0];
165
+ if (typeof ms === 'number') {
166
+ const start = Date.now();
167
+ while (Date.now() - start < ms);
168
+ }
169
+ return null;
170
+ }
171
+ });
172
+
173
+ this._registerStdLib();
174
+ }
175
+
176
+ _registerStdLib() {
177
+ // --- ARCHIVIO (File System) ---
178
+ const Archivio = {
179
+ leggi: {
180
+ call: (_, args) => fs.readFileSync(path.resolve(this.currentPath, '..', args[0]), 'utf8')
181
+ },
182
+ scrivi: {
183
+ call: (_, args) => {
184
+ fs.writeFileSync(path.resolve(this.currentPath, '..', args[0]), args[1]);
185
+ return true;
186
+ }
187
+ },
188
+ esiste: {
189
+ call: (_, args) => fs.existsSync(path.resolve(this.currentPath, '..', args[0]))
190
+ },
191
+ elimina: {
192
+ call: (_, args) => {
193
+ fs.unlinkSync(path.resolve(this.currentPath, '..', args[0]));
194
+ return true;
195
+ }
196
+ }
197
+ };
198
+ this.globals.define('Archivio', Archivio);
199
+
200
+ // --- SISTEMA (Process/OS) ---
201
+ const Sistema = {
202
+ esegui: {
203
+ call: (_, args) => execSync(args[0], { encoding: 'utf8' })
204
+ },
205
+ argomenti: process.argv.slice(2),
206
+ esci: {
207
+ call: (_, args) => process.exit(args[0] || 0)
208
+ },
209
+ piattaforma: process.platform,
210
+ cartellaCorrente: {
211
+ call: () => process.cwd()
212
+ }
213
+ };
214
+ this.globals.define('Sistema', Sistema);
215
+
216
+ // --- RETE (HTTP) ---
217
+ const Rete = {
218
+ chiama: {
219
+ call: (_, args) => {
220
+ const url = args[0];
221
+ try {
222
+ const output = execSync(`curl -sL "${url}"`, { encoding: 'utf8' });
223
+ try {
224
+ return JSON.parse(output);
225
+ } catch (e) {
226
+ return output;
227
+ }
228
+ } catch (err) {
229
+ throw new Error(`Errore chiamata HTTP: ${err.message}`);
230
+ }
231
+ }
232
+ },
233
+ server: {
234
+ call: (_, args) => {
235
+ const porta = args[0] || 3000;
236
+ const gestore = args[1]; // Una funzione VladX
237
+
238
+ const server = http.createServer(async (req, res) => {
239
+ if (gestore && gestore.call) {
240
+ // Creiamo un oggetto richiesta per VladX
241
+ const richiesta = {
242
+ metodo: req.method,
243
+ url: req.url,
244
+ intestazioni: req.headers
245
+ };
246
+
247
+ try {
248
+ const risposta = await gestore.call(this, [richiesta]);
249
+ res.writeHead(risposta.stato || 200, risposta.intestazioni || { 'Content-Type': 'text/plain' });
250
+ res.end(typeof risposta.corpo === 'object' ? JSON.stringify(risposta.corpo) : String(risposta.corpo));
251
+ } catch (e) {
252
+ res.writeHead(500);
253
+ res.end("Errore Server VladX: " + e.message);
254
+ }
255
+ } else {
256
+ res.writeHead(200);
257
+ res.end("Server VladX attivo sulla porta " + porta);
258
+ }
259
+ });
260
+
261
+ server.listen(porta);
262
+ console.log(`Server VladX in ascolto sulla porta ${porta}`);
263
+ return true;
264
+ }
265
+ }
266
+ };
267
+ this.globals.define('Rete', Rete);
158
268
  }
159
269
 
160
270
  interpret(program) {
@@ -192,6 +302,10 @@ class Interpreter {
192
302
  throw new BreakSignal();
193
303
  case 'ContinueStatement':
194
304
  throw new ContinueSignal();
305
+ case 'TryStatement':
306
+ return this.executeTryStatement(node);
307
+ case 'ThrowStatement':
308
+ return this.executeThrowStatement(node);
195
309
  case 'ExportNamedDeclaration':
196
310
  return this.executeExportNamedDeclaration(node);
197
311
  case 'ImportDeclaration':
@@ -273,6 +387,43 @@ class Interpreter {
273
387
  }
274
388
  }
275
389
 
390
+ executeTryStatement(node) {
391
+ try {
392
+ this.execute(node.block);
393
+ } catch (error) {
394
+ // Se è un ReturnValue o Break/Continue Signal, non catturarlo qui
395
+ if (error instanceof ReturnValue || error instanceof BreakSignal || error instanceof ContinueSignal) {
396
+ throw error;
397
+ }
398
+
399
+ if (node.handler) {
400
+ const catchEnv = new Environment(this.environment);
401
+ // Il valore errore può essere quello lanciato da LANCIA o un errore JS
402
+ const errorValue = error instanceof Error ? error.message : error;
403
+ catchEnv.define(node.handler.param, errorValue);
404
+
405
+ const previousEnv = this.environment;
406
+ this.environment = catchEnv;
407
+ try {
408
+ this.execute(node.handler.body);
409
+ } finally {
410
+ this.environment = previousEnv;
411
+ }
412
+ } else if (!node.finalizer) {
413
+ throw error;
414
+ }
415
+ } finally {
416
+ if (node.finalizer) {
417
+ this.execute(node.finalizer);
418
+ }
419
+ }
420
+ }
421
+
422
+ executeThrowStatement(node) {
423
+ const value = this.evaluate(node.argument);
424
+ throw value;
425
+ }
426
+
276
427
  executeExportNamedDeclaration(node) {
277
428
  this.execute(node.declaration);
278
429
  const name = node.declaration.name;
package/src/parser/ast.js CHANGED
@@ -104,6 +104,30 @@ class PrintStatement extends ASTNode {
104
104
  }
105
105
  }
106
106
 
107
+ class TryStatement extends ASTNode {
108
+ constructor(block, handler, finalizer = null) {
109
+ super('TryStatement');
110
+ this.block = block;
111
+ this.handler = handler;
112
+ this.finalizer = finalizer;
113
+ }
114
+ }
115
+
116
+ class CatchClause extends ASTNode {
117
+ constructor(param, body) {
118
+ super('CatchClause');
119
+ this.param = param;
120
+ this.body = body;
121
+ }
122
+ }
123
+
124
+ class ThrowStatement extends ASTNode {
125
+ constructor(argument) {
126
+ super('ThrowStatement');
127
+ this.argument = argument;
128
+ }
129
+ }
130
+
107
131
  // === Espressioni ===
108
132
  class Identifier extends ASTNode {
109
133
  constructor(name) {
@@ -269,6 +293,9 @@ module.exports = {
269
293
  ContinueStatement,
270
294
  ExpressionStatement,
271
295
  PrintStatement,
296
+ TryStatement,
297
+ CatchClause,
298
+ ThrowStatement,
272
299
  ExportNamedDeclaration,
273
300
  ImportDeclaration,
274
301
  ImportSpecifier,
@@ -146,6 +146,8 @@ class Parser {
146
146
  if (this.match(TokenType.INTERROMPI)) return this.breakStatement();
147
147
  if (this.match(TokenType.CONTINUA)) return this.continueStatement();
148
148
  if (this.match(TokenType.STAMPA)) return this.printStatement();
149
+ if (this.match(TokenType.PROVA)) return this.tryStatement();
150
+ if (this.match(TokenType.LANCIA)) return this.throwStatement();
149
151
  if (this.match(TokenType.GRAFFA_APERTA)) return this.blockStatement();
150
152
  return this.expressionStatement();
151
153
  }
@@ -242,6 +244,39 @@ class Parser {
242
244
  return new AST.PrintStatement(argument);
243
245
  }
244
246
 
247
+ tryStatement() {
248
+ this.consume(TokenType.GRAFFA_APERTA, 'Atteso "{" dopo "prova"');
249
+ const block = this.blockStatement();
250
+
251
+ let handler = null;
252
+ if (this.match(TokenType.CATTURA)) {
253
+ this.consume(TokenType.PARENTESI_APERTA, 'Atteso "(" dopo "cattura"');
254
+ const param = this.consume(TokenType.IDENTIFICATORE, 'Nome variabile errore atteso').value;
255
+ this.consume(TokenType.PARENTESI_CHIUSA, 'Atteso ")" dopo nome variabile');
256
+ this.consume(TokenType.GRAFFA_APERTA, 'Atteso "{" dopo clausola "cattura"');
257
+ const body = this.blockStatement();
258
+ handler = new AST.CatchClause(param, body);
259
+ }
260
+
261
+ let finalizer = null;
262
+ if (this.match(TokenType.FINALMENTE)) {
263
+ this.consume(TokenType.GRAFFA_APERTA, 'Atteso "{" dopo "finalmente"');
264
+ finalizer = this.blockStatement();
265
+ }
266
+
267
+ if (!handler && !finalizer) {
268
+ throw new ParserError('Atteso "cattura" o "finalmente" dopo blocco "prova"', this.peek());
269
+ }
270
+
271
+ return new AST.TryStatement(block, handler, finalizer);
272
+ }
273
+
274
+ throwStatement() {
275
+ const argument = this.expression();
276
+ this.match(TokenType.PUNTO_VIRGOLA);
277
+ return new AST.ThrowStatement(argument);
278
+ }
279
+
245
280
  expressionStatement() {
246
281
  const expr = this.expression();
247
282
  this.match(TokenType.PUNTO_VIRGOLA);
@@ -478,7 +513,12 @@ class Parser {
478
513
  const properties = [];
479
514
  if (!this.check(TokenType.GRAFFA_CHIUSA)) {
480
515
  do {
481
- const key = this.consume(TokenType.IDENTIFICATORE, 'Nome proprietà atteso').value;
516
+ let key;
517
+ if (this.match(TokenType.IDENTIFICATORE, TokenType.STRINGA)) {
518
+ key = this.previous().value;
519
+ } else {
520
+ throw new ParserError('Nome proprietà o stringa atteso', this.peek());
521
+ }
482
522
  this.consume(TokenType.DUE_PUNTI, 'Atteso ":" dopo nome proprietà');
483
523
  const value = this.expression();
484
524
  properties.push(new AST.Property(key, value));
package/src/pm/cli.js CHANGED
@@ -11,6 +11,7 @@ const uninstall = require('./commands/uninstall.js');
11
11
  const search = require('./commands/search.js');
12
12
  const list = require('./commands/list.js');
13
13
  const config = require('./commands/config.js');
14
+ const runCmd = require('./commands/run.js');
14
15
 
15
16
  const VERSION = '1.0.0';
16
17
 
@@ -40,6 +41,10 @@ ${colorize('Uso:', 'cyan')}
40
41
  vladpm uninstall <pkg> Rimuove un pacchetto
41
42
  vladpm search <query> Cerca pacchetti
42
43
  vladpm list Lista pacchetti installati
44
+ vladpm run <script> Esegue uno script definito in vladx.json
45
+ vladpm start Scorciatoia per "vladpm run start"
46
+ vladpm test Scorciatoia per "vladpm run test"
47
+ vladpm dev Scorciatoia per "vladpm run dev"
43
48
  vladpm --help, -h Mostra questo aiuto
44
49
  vladpm --version, -v Mostra la versione
45
50
 
@@ -116,6 +121,22 @@ async function run(args) {
116
121
  await config.execute(args.slice(1));
117
122
  break;
118
123
 
124
+ case 'run':
125
+ await runCmd.execute(args.slice(1));
126
+ break;
127
+
128
+ case 'start':
129
+ await runCmd.execute(['start', ...args.slice(1)]);
130
+ break;
131
+
132
+ case 'test':
133
+ await runCmd.execute(['test', ...args.slice(1)]);
134
+ break;
135
+
136
+ case 'dev':
137
+ await runCmd.execute(['dev', ...args.slice(1)]);
138
+ break;
139
+
119
140
  default:
120
141
  console.error(colorize(`✗ Comando sconosciuto: ${command}`, 'red'));
121
142
  console.log('Usa "vladpm --help" per vedere i comandi disponibili.');
@@ -0,0 +1,77 @@
1
+ /**
2
+ * VladPM - run command
3
+ * Esegue script definiti in vladx.json
4
+ */
5
+
6
+ const { execSync } = require('child_process');
7
+ const { getVladxJson } = require('../utils/config.js');
8
+
9
+ const COLORS = {
10
+ reset: '\x1b[0m',
11
+ bright: '\x1b[1m',
12
+ red: '\x1b[31m',
13
+ green: '\x1b[32m',
14
+ yellow: '\x1b[33m',
15
+ cyan: '\x1b[36m'
16
+ };
17
+
18
+ function colorize(text, color) {
19
+ return `${COLORS[color]}${text}${COLORS.reset}`;
20
+ }
21
+
22
+ async function execute(args) {
23
+ if (args.length === 0) {
24
+ console.error(colorize('✗ Errore: Specificare il nome dello script da eseguire.', 'red'));
25
+ console.log('Uso: vladpm run <script>');
26
+ showScripts();
27
+ process.exit(1);
28
+ }
29
+
30
+ const scriptName = args[0];
31
+ const vladxJson = getVladxJson();
32
+
33
+ if (!vladxJson) {
34
+ console.error(colorize('✗ Errore: vladx.json non trovato.', 'red'));
35
+ process.exit(1);
36
+ }
37
+
38
+ const scripts = vladxJson.scripts || {};
39
+ const command = scripts[scriptName];
40
+
41
+ if (!command) {
42
+ console.error(colorize(`✗ Errore: Script "${scriptName}" non trovato in vladx.json.`, 'red'));
43
+ showScripts(scripts);
44
+ process.exit(1);
45
+ }
46
+
47
+ console.log(`\n> ${vladxJson.name}@${vladxJson.version} ${scriptName}`);
48
+ console.log(`> ${command}\n`);
49
+
50
+ try {
51
+ // Aggiungiamo il path della bin di vladx locale all'ambiente se necessario
52
+ // Ma per ora assumiamo che vladx sia nel path o eseguito tramite node
53
+
54
+ execSync(command, {
55
+ stdio: 'inherit',
56
+ env: { ...process.env, PATH: `${process.env.PATH}:${process.cwd()}/node_modules/.bin` }
57
+ });
58
+ } catch (error) {
59
+ process.exit(error.status || 1);
60
+ }
61
+ }
62
+
63
+ function showScripts(scripts) {
64
+ if (!scripts) {
65
+ const vladxJson = getVladxJson();
66
+ scripts = vladxJson ? vladxJson.scripts : null;
67
+ }
68
+
69
+ if (scripts && Object.keys(scripts).length > 0) {
70
+ console.log('\nScript disponibili:');
71
+ for (const name of Object.keys(scripts)) {
72
+ console.log(` - ${colorize(name, 'cyan')}: ${scripts[name]}`);
73
+ }
74
+ }
75
+ }
76
+
77
+ module.exports = { execute };