vladx 1.0.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/bin/vladpm +9 -0
- package/bin/vladx +10 -0
- package/examples/esempio.vx +79 -0
- package/package.json +23 -0
- package/src/cli/cli.js +191 -0
- package/src/index.js +32 -0
- package/src/interpreter/interpreter.js +455 -0
- package/src/lexer/lexer.js +284 -0
- package/src/lexer/tokens.js +116 -0
- package/src/parser/ast.js +265 -0
- package/src/parser/parser.js +476 -0
- package/src/pm/cli.js +130 -0
- package/src/pm/commands/config.js +76 -0
- package/src/pm/commands/init.js +129 -0
- package/src/pm/commands/install.js +185 -0
- package/src/pm/commands/list.js +70 -0
- package/src/pm/commands/login.js +124 -0
- package/src/pm/commands/publish.js +115 -0
- package/src/pm/commands/search.js +55 -0
- package/src/pm/commands/uninstall.js +68 -0
- package/src/pm/utils/api.js +135 -0
- package/src/pm/utils/config.js +117 -0
- package/src/repl/repl.js +179 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VladX Lexer
|
|
3
|
+
* Tokenizzatore per il linguaggio VladX
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { TokenType, KEYWORDS } = require('./tokens.js');
|
|
7
|
+
|
|
8
|
+
class Token {
|
|
9
|
+
constructor(type, value, line, column) {
|
|
10
|
+
this.type = type;
|
|
11
|
+
this.value = value;
|
|
12
|
+
this.line = line;
|
|
13
|
+
this.column = column;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
toString() {
|
|
17
|
+
return `Token(${this.type}, "${this.value}", riga:${this.line}, col:${this.column})`;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class Lexer {
|
|
22
|
+
constructor(source) {
|
|
23
|
+
this.source = source;
|
|
24
|
+
this.tokens = [];
|
|
25
|
+
this.current = 0;
|
|
26
|
+
this.line = 1;
|
|
27
|
+
this.column = 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
peek() {
|
|
31
|
+
if (this.isAtEnd()) return '\0';
|
|
32
|
+
return this.source[this.current];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
peekNext() {
|
|
36
|
+
if (this.current + 1 >= this.source.length) return '\0';
|
|
37
|
+
return this.source[this.current + 1];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
advance() {
|
|
41
|
+
const char = this.source[this.current];
|
|
42
|
+
this.current++;
|
|
43
|
+
if (char === '\n') {
|
|
44
|
+
this.line++;
|
|
45
|
+
this.column = 1;
|
|
46
|
+
} else {
|
|
47
|
+
this.column++;
|
|
48
|
+
}
|
|
49
|
+
return char;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
isAtEnd() {
|
|
53
|
+
return this.current >= this.source.length;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
match(expected) {
|
|
57
|
+
if (this.isAtEnd()) return false;
|
|
58
|
+
if (this.source[this.current] !== expected) return false;
|
|
59
|
+
this.advance();
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
addToken(type, value) {
|
|
64
|
+
this.tokens.push(new Token(type, value, this.line, this.column));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
skipWhitespaceAndComments() {
|
|
68
|
+
while (!this.isAtEnd()) {
|
|
69
|
+
const char = this.peek();
|
|
70
|
+
|
|
71
|
+
if (char === ' ' || char === '\t' || char === '\r' || char === '\n') {
|
|
72
|
+
this.advance();
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (char === '/' && this.peekNext() === '/') {
|
|
77
|
+
while (this.peek() !== '\n' && !this.isAtEnd()) {
|
|
78
|
+
this.advance();
|
|
79
|
+
}
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (char === '/' && this.peekNext() === '*') {
|
|
84
|
+
this.advance();
|
|
85
|
+
this.advance();
|
|
86
|
+
while (!this.isAtEnd()) {
|
|
87
|
+
if (this.peek() === '*' && this.peekNext() === '/') {
|
|
88
|
+
this.advance();
|
|
89
|
+
this.advance();
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
this.advance();
|
|
93
|
+
}
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
readNumber() {
|
|
102
|
+
const startColumn = this.column;
|
|
103
|
+
let value = '';
|
|
104
|
+
|
|
105
|
+
while (this.isDigit(this.peek())) {
|
|
106
|
+
value += this.advance();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (this.peek() === '.' && this.isDigit(this.peekNext())) {
|
|
110
|
+
value += this.advance();
|
|
111
|
+
while (this.isDigit(this.peek())) {
|
|
112
|
+
value += this.advance();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.tokens.push(new Token(TokenType.NUMERO, parseFloat(value), this.line, startColumn));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
readString(quote) {
|
|
120
|
+
const startColumn = this.column;
|
|
121
|
+
const startLine = this.line;
|
|
122
|
+
this.advance();
|
|
123
|
+
let value = '';
|
|
124
|
+
|
|
125
|
+
while (!this.isAtEnd() && this.peek() !== quote) {
|
|
126
|
+
if (this.peek() === '\\' && !this.isAtEnd()) {
|
|
127
|
+
this.advance();
|
|
128
|
+
const escaped = this.peek();
|
|
129
|
+
switch (escaped) {
|
|
130
|
+
case 'n': value += '\n'; break;
|
|
131
|
+
case 't': value += '\t'; break;
|
|
132
|
+
case 'r': value += '\r'; break;
|
|
133
|
+
case '\\': value += '\\'; break;
|
|
134
|
+
case '"': value += '"'; break;
|
|
135
|
+
case "'": value += "'"; break;
|
|
136
|
+
default: value += escaped;
|
|
137
|
+
}
|
|
138
|
+
this.advance();
|
|
139
|
+
} else {
|
|
140
|
+
value += this.advance();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (this.isAtEnd()) {
|
|
145
|
+
throw new Error(`Stringa non terminata alla riga ${startLine}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
this.advance();
|
|
149
|
+
this.tokens.push(new Token(TokenType.STRINGA, value, startLine, startColumn));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
readIdentifier() {
|
|
153
|
+
const startColumn = this.column;
|
|
154
|
+
let value = '';
|
|
155
|
+
|
|
156
|
+
while (this.isAlphaNumeric(this.peek())) {
|
|
157
|
+
value += this.advance();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const type = KEYWORDS[value.toLowerCase()] || TokenType.IDENTIFICATORE;
|
|
161
|
+
this.tokens.push(new Token(type, value, this.line, startColumn));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
isDigit(char) {
|
|
165
|
+
return char >= '0' && char <= '9';
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
isAlpha(char) {
|
|
169
|
+
return (char >= 'a' && char <= 'z') ||
|
|
170
|
+
(char >= 'A' && char <= 'Z') ||
|
|
171
|
+
char === '_' ||
|
|
172
|
+
'àèéìòùÀÈÉÌÒÙ'.includes(char);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
isAlphaNumeric(char) {
|
|
176
|
+
return this.isAlpha(char) || this.isDigit(char);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
scanToken() {
|
|
180
|
+
const char = this.advance();
|
|
181
|
+
|
|
182
|
+
switch (char) {
|
|
183
|
+
case '(': this.addToken(TokenType.PARENTESI_APERTA, '('); break;
|
|
184
|
+
case ')': this.addToken(TokenType.PARENTESI_CHIUSA, ')'); break;
|
|
185
|
+
case '{': this.addToken(TokenType.GRAFFA_APERTA, '{'); break;
|
|
186
|
+
case '}': this.addToken(TokenType.GRAFFA_CHIUSA, '}'); break;
|
|
187
|
+
case '[': this.addToken(TokenType.QUADRA_APERTA, '['); break;
|
|
188
|
+
case ']': this.addToken(TokenType.QUADRA_CHIUSA, ']'); break;
|
|
189
|
+
case ',': this.addToken(TokenType.VIRGOLA, ','); break;
|
|
190
|
+
case ';': this.addToken(TokenType.PUNTO_VIRGOLA, ';'); break;
|
|
191
|
+
case '.': this.addToken(TokenType.PUNTO, '.'); break;
|
|
192
|
+
case ':': this.addToken(TokenType.DUE_PUNTI, ':'); break;
|
|
193
|
+
case '?': this.addToken(TokenType.PUNTO_INTERROGATIVO, '?'); break;
|
|
194
|
+
|
|
195
|
+
case '+':
|
|
196
|
+
if (this.match('+')) this.addToken(TokenType.INCREMENTA, '++');
|
|
197
|
+
else if (this.match('=')) this.addToken(TokenType.PIU_ASSEGNA, '+=');
|
|
198
|
+
else this.addToken(TokenType.PIU, '+');
|
|
199
|
+
break;
|
|
200
|
+
|
|
201
|
+
case '-':
|
|
202
|
+
if (this.match('-')) this.addToken(TokenType.DECREMENTA, '--');
|
|
203
|
+
else if (this.match('=')) this.addToken(TokenType.MENO_ASSEGNA, '-=');
|
|
204
|
+
else this.addToken(TokenType.MENO, '-');
|
|
205
|
+
break;
|
|
206
|
+
|
|
207
|
+
case '*': this.addToken(TokenType.MOLTIPLICA, '*'); break;
|
|
208
|
+
case '/': this.addToken(TokenType.DIVIDI, '/'); break;
|
|
209
|
+
case '%': this.addToken(TokenType.MODULO, '%'); break;
|
|
210
|
+
|
|
211
|
+
case '=':
|
|
212
|
+
if (this.match('=')) {
|
|
213
|
+
if (this.match('=')) this.addToken(TokenType.UGUALE_STRETTO, '===');
|
|
214
|
+
else this.addToken(TokenType.UGUALE, '==');
|
|
215
|
+
} else if (this.match('>')) {
|
|
216
|
+
this.addToken(TokenType.FRECCIA, '=>');
|
|
217
|
+
} else {
|
|
218
|
+
this.addToken(TokenType.ASSEGNA, '=');
|
|
219
|
+
}
|
|
220
|
+
break;
|
|
221
|
+
|
|
222
|
+
case '!':
|
|
223
|
+
if (this.match('=')) {
|
|
224
|
+
if (this.match('=')) this.addToken(TokenType.DIVERSO_STRETTO, '!==');
|
|
225
|
+
else this.addToken(TokenType.DIVERSO, '!=');
|
|
226
|
+
} else {
|
|
227
|
+
this.addToken(TokenType.NON, '!');
|
|
228
|
+
}
|
|
229
|
+
break;
|
|
230
|
+
|
|
231
|
+
case '<':
|
|
232
|
+
if (this.match('=')) this.addToken(TokenType.MINORE_UGUALE, '<=');
|
|
233
|
+
else this.addToken(TokenType.MINORE, '<');
|
|
234
|
+
break;
|
|
235
|
+
|
|
236
|
+
case '>':
|
|
237
|
+
if (this.match('=')) this.addToken(TokenType.MAGGIORE_UGUALE, '>=');
|
|
238
|
+
else this.addToken(TokenType.MAGGIORE, '>');
|
|
239
|
+
break;
|
|
240
|
+
|
|
241
|
+
case '&':
|
|
242
|
+
if (this.match('&')) this.addToken(TokenType.AND, '&&');
|
|
243
|
+
break;
|
|
244
|
+
|
|
245
|
+
case '|':
|
|
246
|
+
if (this.match('|')) this.addToken(TokenType.OR, '||');
|
|
247
|
+
break;
|
|
248
|
+
|
|
249
|
+
case '"':
|
|
250
|
+
case "'":
|
|
251
|
+
this.current--;
|
|
252
|
+
this.column--;
|
|
253
|
+
this.readString(char);
|
|
254
|
+
break;
|
|
255
|
+
|
|
256
|
+
default:
|
|
257
|
+
if (this.isDigit(char)) {
|
|
258
|
+
this.current--;
|
|
259
|
+
this.column--;
|
|
260
|
+
this.readNumber();
|
|
261
|
+
} else if (this.isAlpha(char)) {
|
|
262
|
+
this.current--;
|
|
263
|
+
this.column--;
|
|
264
|
+
this.readIdentifier();
|
|
265
|
+
} else {
|
|
266
|
+
this.addToken(TokenType.SCONOSCIUTO, char);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
tokenize() {
|
|
272
|
+
while (!this.isAtEnd()) {
|
|
273
|
+
this.skipWhitespaceAndComments();
|
|
274
|
+
if (!this.isAtEnd()) {
|
|
275
|
+
this.scanToken();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
this.tokens.push(new Token(TokenType.FINE, '', this.line, this.column));
|
|
280
|
+
return this.tokens;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
module.exports = { Lexer, Token };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VladX - Token Types
|
|
3
|
+
* Definizione dei tipi di token e keyword italiane
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const TokenType = {
|
|
7
|
+
// Literals
|
|
8
|
+
NUMERO: 'NUMERO',
|
|
9
|
+
STRINGA: 'STRINGA',
|
|
10
|
+
IDENTIFICATORE: 'IDENTIFICATORE',
|
|
11
|
+
|
|
12
|
+
// Keywords
|
|
13
|
+
VARIABILE: 'VARIABILE',
|
|
14
|
+
COSTANTE: 'COSTANTE',
|
|
15
|
+
FUNZIONE: 'FUNZIONE',
|
|
16
|
+
SE: 'SE',
|
|
17
|
+
ALTRIMENTI: 'ALTRIMENTI',
|
|
18
|
+
MENTRE: 'MENTRE',
|
|
19
|
+
PER: 'PER',
|
|
20
|
+
RITORNA: 'RITORNA',
|
|
21
|
+
VERO: 'VERO',
|
|
22
|
+
FALSO: 'FALSO',
|
|
23
|
+
NULLO: 'NULLO',
|
|
24
|
+
E: 'E',
|
|
25
|
+
O: 'O',
|
|
26
|
+
NON: 'NON',
|
|
27
|
+
STAMPA: 'STAMPA',
|
|
28
|
+
CLASSE: 'CLASSE',
|
|
29
|
+
NUOVO: 'NUOVO',
|
|
30
|
+
QUESTO: 'QUESTO',
|
|
31
|
+
IMPORTA: 'IMPORTA',
|
|
32
|
+
ESPORTA: 'ESPORTA',
|
|
33
|
+
DA: 'DA',
|
|
34
|
+
PROVA: 'PROVA',
|
|
35
|
+
CATTURA: 'CATTURA',
|
|
36
|
+
FINALMENTE: 'FINALMENTE',
|
|
37
|
+
LANCIA: 'LANCIA',
|
|
38
|
+
ASINCRONO: 'ASINCRONO',
|
|
39
|
+
ATTENDI: 'ATTENDI',
|
|
40
|
+
INTERROMPI: 'INTERROMPI',
|
|
41
|
+
CONTINUA: 'CONTINUA',
|
|
42
|
+
|
|
43
|
+
// Operators
|
|
44
|
+
PIU: 'PIU',
|
|
45
|
+
MENO: 'MENO',
|
|
46
|
+
MOLTIPLICA: 'MOLTIPLICA',
|
|
47
|
+
DIVIDI: 'DIVIDI',
|
|
48
|
+
MODULO: 'MODULO',
|
|
49
|
+
ASSEGNA: 'ASSEGNA',
|
|
50
|
+
UGUALE: 'UGUALE',
|
|
51
|
+
UGUALE_STRETTO: 'UGUALE_STRETTO',
|
|
52
|
+
DIVERSO: 'DIVERSO',
|
|
53
|
+
DIVERSO_STRETTO: 'DIVERSO_STRETTO',
|
|
54
|
+
MINORE: 'MINORE',
|
|
55
|
+
MAGGIORE: 'MAGGIORE',
|
|
56
|
+
MINORE_UGUALE: 'MINORE_UGUALE',
|
|
57
|
+
MAGGIORE_UGUALE: 'MAGGIORE_UGUALE',
|
|
58
|
+
PIU_ASSEGNA: 'PIU_ASSEGNA',
|
|
59
|
+
MENO_ASSEGNA: 'MENO_ASSEGNA',
|
|
60
|
+
INCREMENTA: 'INCREMENTA',
|
|
61
|
+
DECREMENTA: 'DECREMENTA',
|
|
62
|
+
FRECCIA: 'FRECCIA',
|
|
63
|
+
AND: 'AND',
|
|
64
|
+
OR: 'OR',
|
|
65
|
+
|
|
66
|
+
// Delimiters
|
|
67
|
+
PARENTESI_APERTA: 'PARENTESI_APERTA',
|
|
68
|
+
PARENTESI_CHIUSA: 'PARENTESI_CHIUSA',
|
|
69
|
+
GRAFFA_APERTA: 'GRAFFA_APERTA',
|
|
70
|
+
GRAFFA_CHIUSA: 'GRAFFA_CHIUSA',
|
|
71
|
+
QUADRA_APERTA: 'QUADRA_APERTA',
|
|
72
|
+
QUADRA_CHIUSA: 'QUADRA_CHIUSA',
|
|
73
|
+
VIRGOLA: 'VIRGOLA',
|
|
74
|
+
PUNTO_VIRGOLA: 'PUNTO_VIRGOLA',
|
|
75
|
+
PUNTO: 'PUNTO',
|
|
76
|
+
DUE_PUNTI: 'DUE_PUNTI',
|
|
77
|
+
PUNTO_INTERROGATIVO: 'PUNTO_INTERROGATIVO',
|
|
78
|
+
|
|
79
|
+
// Special
|
|
80
|
+
FINE: 'FINE',
|
|
81
|
+
SCONOSCIUTO: 'SCONOSCIUTO'
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const KEYWORDS = {
|
|
85
|
+
'variabile': TokenType.VARIABILE,
|
|
86
|
+
'costante': TokenType.COSTANTE,
|
|
87
|
+
'funzione': TokenType.FUNZIONE,
|
|
88
|
+
'se': TokenType.SE,
|
|
89
|
+
'altrimenti': TokenType.ALTRIMENTI,
|
|
90
|
+
'mentre': TokenType.MENTRE,
|
|
91
|
+
'per': TokenType.PER,
|
|
92
|
+
'ritorna': TokenType.RITORNA,
|
|
93
|
+
'vero': TokenType.VERO,
|
|
94
|
+
'falso': TokenType.FALSO,
|
|
95
|
+
'nullo': TokenType.NULLO,
|
|
96
|
+
'e': TokenType.E,
|
|
97
|
+
'o': TokenType.O,
|
|
98
|
+
'non': TokenType.NON,
|
|
99
|
+
'stampa': TokenType.STAMPA,
|
|
100
|
+
'classe': TokenType.CLASSE,
|
|
101
|
+
'nuovo': TokenType.NUOVO,
|
|
102
|
+
'questo': TokenType.QUESTO,
|
|
103
|
+
'importa': TokenType.IMPORTA,
|
|
104
|
+
'esporta': TokenType.ESPORTA,
|
|
105
|
+
'da': TokenType.DA,
|
|
106
|
+
'prova': TokenType.PROVA,
|
|
107
|
+
'cattura': TokenType.CATTURA,
|
|
108
|
+
'finalmente': TokenType.FINALMENTE,
|
|
109
|
+
'lancia': TokenType.LANCIA,
|
|
110
|
+
'asincrono': TokenType.ASINCRONO,
|
|
111
|
+
'attendi': TokenType.ATTENDI,
|
|
112
|
+
'interrompi': TokenType.INTERROMPI,
|
|
113
|
+
'continua': TokenType.CONTINUA
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
module.exports = { TokenType, KEYWORDS };
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VladX AST Node Types
|
|
3
|
+
* Definizioni dei nodi dell'Abstract Syntax Tree
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class ASTNode {
|
|
7
|
+
constructor(type) {
|
|
8
|
+
this.type = type;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// === Programma ===
|
|
13
|
+
class Program extends ASTNode {
|
|
14
|
+
constructor(body) {
|
|
15
|
+
super('Program');
|
|
16
|
+
this.body = body;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// === Dichiarazioni ===
|
|
21
|
+
class VariableDeclaration extends ASTNode {
|
|
22
|
+
constructor(name, value, isConstant = false) {
|
|
23
|
+
super('VariableDeclaration');
|
|
24
|
+
this.name = name;
|
|
25
|
+
this.value = value;
|
|
26
|
+
this.isConstant = isConstant;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
class FunctionDeclaration extends ASTNode {
|
|
31
|
+
constructor(name, params, body) {
|
|
32
|
+
super('FunctionDeclaration');
|
|
33
|
+
this.name = name;
|
|
34
|
+
this.params = params;
|
|
35
|
+
this.body = body;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// === Statements ===
|
|
40
|
+
class BlockStatement extends ASTNode {
|
|
41
|
+
constructor(body) {
|
|
42
|
+
super('BlockStatement');
|
|
43
|
+
this.body = body;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
class IfStatement extends ASTNode {
|
|
48
|
+
constructor(condition, consequent, alternate = null) {
|
|
49
|
+
super('IfStatement');
|
|
50
|
+
this.condition = condition;
|
|
51
|
+
this.consequent = consequent;
|
|
52
|
+
this.alternate = alternate;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
class WhileStatement extends ASTNode {
|
|
57
|
+
constructor(condition, body) {
|
|
58
|
+
super('WhileStatement');
|
|
59
|
+
this.condition = condition;
|
|
60
|
+
this.body = body;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
class ForStatement extends ASTNode {
|
|
65
|
+
constructor(init, condition, update, body) {
|
|
66
|
+
super('ForStatement');
|
|
67
|
+
this.init = init;
|
|
68
|
+
this.condition = condition;
|
|
69
|
+
this.update = update;
|
|
70
|
+
this.body = body;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
class ReturnStatement extends ASTNode {
|
|
75
|
+
constructor(argument) {
|
|
76
|
+
super('ReturnStatement');
|
|
77
|
+
this.argument = argument;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
class BreakStatement extends ASTNode {
|
|
82
|
+
constructor() {
|
|
83
|
+
super('BreakStatement');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
class ContinueStatement extends ASTNode {
|
|
88
|
+
constructor() {
|
|
89
|
+
super('ContinueStatement');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
class ExpressionStatement extends ASTNode {
|
|
94
|
+
constructor(expression) {
|
|
95
|
+
super('ExpressionStatement');
|
|
96
|
+
this.expression = expression;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
class PrintStatement extends ASTNode {
|
|
101
|
+
constructor(argument) {
|
|
102
|
+
super('PrintStatement');
|
|
103
|
+
this.argument = argument;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// === Espressioni ===
|
|
108
|
+
class Identifier extends ASTNode {
|
|
109
|
+
constructor(name) {
|
|
110
|
+
super('Identifier');
|
|
111
|
+
this.name = name;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
class NumericLiteral extends ASTNode {
|
|
116
|
+
constructor(value) {
|
|
117
|
+
super('NumericLiteral');
|
|
118
|
+
this.value = value;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
class StringLiteral extends ASTNode {
|
|
123
|
+
constructor(value) {
|
|
124
|
+
super('StringLiteral');
|
|
125
|
+
this.value = value;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
class BooleanLiteral extends ASTNode {
|
|
130
|
+
constructor(value) {
|
|
131
|
+
super('BooleanLiteral');
|
|
132
|
+
this.value = value;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
class NullLiteral extends ASTNode {
|
|
137
|
+
constructor() {
|
|
138
|
+
super('NullLiteral');
|
|
139
|
+
this.value = null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
class ArrayLiteral extends ASTNode {
|
|
144
|
+
constructor(elements) {
|
|
145
|
+
super('ArrayLiteral');
|
|
146
|
+
this.elements = elements;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
class ObjectLiteral extends ASTNode {
|
|
151
|
+
constructor(properties) {
|
|
152
|
+
super('ObjectLiteral');
|
|
153
|
+
this.properties = properties;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
class Property extends ASTNode {
|
|
158
|
+
constructor(key, value) {
|
|
159
|
+
super('Property');
|
|
160
|
+
this.key = key;
|
|
161
|
+
this.value = value;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
class BinaryExpression extends ASTNode {
|
|
166
|
+
constructor(operator, left, right) {
|
|
167
|
+
super('BinaryExpression');
|
|
168
|
+
this.operator = operator;
|
|
169
|
+
this.left = left;
|
|
170
|
+
this.right = right;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
class UnaryExpression extends ASTNode {
|
|
175
|
+
constructor(operator, argument, prefix = true) {
|
|
176
|
+
super('UnaryExpression');
|
|
177
|
+
this.operator = operator;
|
|
178
|
+
this.argument = argument;
|
|
179
|
+
this.prefix = prefix;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
class AssignmentExpression extends ASTNode {
|
|
184
|
+
constructor(operator, left, right) {
|
|
185
|
+
super('AssignmentExpression');
|
|
186
|
+
this.operator = operator;
|
|
187
|
+
this.left = left;
|
|
188
|
+
this.right = right;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
class CallExpression extends ASTNode {
|
|
193
|
+
constructor(callee, args) {
|
|
194
|
+
super('CallExpression');
|
|
195
|
+
this.callee = callee;
|
|
196
|
+
this.arguments = args;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
class MemberExpression extends ASTNode {
|
|
201
|
+
constructor(object, property, computed = false) {
|
|
202
|
+
super('MemberExpression');
|
|
203
|
+
this.object = object;
|
|
204
|
+
this.property = property;
|
|
205
|
+
this.computed = computed;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
class ArrowFunction extends ASTNode {
|
|
210
|
+
constructor(params, body) {
|
|
211
|
+
super('ArrowFunction');
|
|
212
|
+
this.params = params;
|
|
213
|
+
this.body = body;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
class UpdateExpression extends ASTNode {
|
|
218
|
+
constructor(operator, argument, prefix = false) {
|
|
219
|
+
super('UpdateExpression');
|
|
220
|
+
this.operator = operator;
|
|
221
|
+
this.argument = argument;
|
|
222
|
+
this.prefix = prefix;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
class LogicalExpression extends ASTNode {
|
|
227
|
+
constructor(operator, left, right) {
|
|
228
|
+
super('LogicalExpression');
|
|
229
|
+
this.operator = operator;
|
|
230
|
+
this.left = left;
|
|
231
|
+
this.right = right;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
module.exports = {
|
|
236
|
+
ASTNode,
|
|
237
|
+
Program,
|
|
238
|
+
VariableDeclaration,
|
|
239
|
+
FunctionDeclaration,
|
|
240
|
+
BlockStatement,
|
|
241
|
+
IfStatement,
|
|
242
|
+
WhileStatement,
|
|
243
|
+
ForStatement,
|
|
244
|
+
ReturnStatement,
|
|
245
|
+
BreakStatement,
|
|
246
|
+
ContinueStatement,
|
|
247
|
+
ExpressionStatement,
|
|
248
|
+
PrintStatement,
|
|
249
|
+
Identifier,
|
|
250
|
+
NumericLiteral,
|
|
251
|
+
StringLiteral,
|
|
252
|
+
BooleanLiteral,
|
|
253
|
+
NullLiteral,
|
|
254
|
+
ArrayLiteral,
|
|
255
|
+
ObjectLiteral,
|
|
256
|
+
Property,
|
|
257
|
+
BinaryExpression,
|
|
258
|
+
UnaryExpression,
|
|
259
|
+
AssignmentExpression,
|
|
260
|
+
CallExpression,
|
|
261
|
+
MemberExpression,
|
|
262
|
+
ArrowFunction,
|
|
263
|
+
UpdateExpression,
|
|
264
|
+
LogicalExpression
|
|
265
|
+
};
|