@designliquido/delegua 0.0.1 → 0.1.2

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.
Files changed (153) hide show
  1. package/README.md +14 -7
  2. package/bin/delegua.cmd +1 -0
  3. package/bin/package.json +51 -0
  4. package/index.js +25 -12
  5. package/index.js.map +1 -0
  6. package/package.json +51 -37
  7. package/src/ambiente.js +49 -0
  8. package/src/ambiente.js.map +1 -0
  9. package/src/avaliador-sintatico/dialetos/egua-classico.js +635 -0
  10. package/src/avaliador-sintatico/dialetos/egua-classico.js.map +1 -0
  11. package/src/avaliador-sintatico/dialetos/index.js +14 -0
  12. package/src/avaliador-sintatico/dialetos/index.js.map +1 -0
  13. package/src/avaliador-sintatico/index.js +635 -0
  14. package/src/avaliador-sintatico/index.js.map +1 -0
  15. package/src/avaliador-sintatico/parser-error.js +27 -0
  16. package/src/avaliador-sintatico/parser-error.js.map +1 -0
  17. package/src/bibliotecas/bibliotecaGlobal.js +97 -0
  18. package/src/bibliotecas/bibliotecaGlobal.js.map +1 -0
  19. package/src/bibliotecas/importarBiblioteca.js +32 -0
  20. package/src/bibliotecas/importarBiblioteca.js.map +1 -0
  21. package/src/construtos/assign-subscript.js +35 -0
  22. package/src/construtos/assign-subscript.js.map +1 -0
  23. package/src/construtos/atribuir.js +34 -0
  24. package/src/construtos/atribuir.js.map +1 -0
  25. package/src/construtos/binario.js +35 -0
  26. package/src/construtos/binario.js.map +1 -0
  27. package/src/construtos/call.js +35 -0
  28. package/src/construtos/call.js.map +1 -0
  29. package/src/construtos/conjunto.js +35 -0
  30. package/src/construtos/conjunto.js.map +1 -0
  31. package/src/construtos/dicionario.js +34 -0
  32. package/src/construtos/dicionario.js.map +1 -0
  33. package/src/construtos/expr.js +11 -0
  34. package/src/construtos/expr.js.map +1 -0
  35. package/src/construtos/funcao.js +34 -0
  36. package/src/construtos/funcao.js.map +1 -0
  37. package/src/construtos/get.js +34 -0
  38. package/src/construtos/get.js.map +1 -0
  39. package/src/construtos/grouping.js +33 -0
  40. package/src/construtos/grouping.js.map +1 -0
  41. package/src/construtos/index.js +31 -0
  42. package/src/construtos/index.js.map +1 -0
  43. package/src/construtos/isto.js +33 -0
  44. package/src/construtos/isto.js.map +1 -0
  45. package/src/construtos/literal.js +33 -0
  46. package/src/construtos/literal.js.map +1 -0
  47. package/src/construtos/logical.js +35 -0
  48. package/src/construtos/logical.js.map +1 -0
  49. package/src/construtos/subscript.js +35 -0
  50. package/src/construtos/subscript.js.map +1 -0
  51. package/src/construtos/super.js +34 -0
  52. package/src/construtos/super.js.map +1 -0
  53. package/src/construtos/unario.js +34 -0
  54. package/src/construtos/unario.js.map +1 -0
  55. package/src/construtos/variavel.js +33 -0
  56. package/src/construtos/variavel.js.map +1 -0
  57. package/src/construtos/vetor.js +33 -0
  58. package/src/construtos/vetor.js.map +1 -0
  59. package/src/declaracoes/index.js +249 -0
  60. package/src/declaracoes/index.js.map +1 -0
  61. package/src/delegua.js +132 -0
  62. package/src/delegua.js.map +1 -0
  63. package/src/estruturas/callable.js +16 -0
  64. package/src/estruturas/callable.js.map +1 -0
  65. package/src/estruturas/classe.js +57 -0
  66. package/src/estruturas/classe.js.map +1 -0
  67. package/src/estruturas/funcao-padrao.js +38 -0
  68. package/src/estruturas/funcao-padrao.js.map +1 -0
  69. package/src/estruturas/funcao.js +81 -0
  70. package/src/estruturas/funcao.js.map +1 -0
  71. package/src/estruturas/index.js +19 -0
  72. package/src/estruturas/index.js.map +1 -0
  73. package/src/estruturas/instancia.js +28 -0
  74. package/src/estruturas/instancia.js.map +1 -0
  75. package/src/estruturas/modulo.js +15 -0
  76. package/src/estruturas/modulo.js.map +1 -0
  77. package/src/excecoes/break-exception.js +27 -0
  78. package/src/excecoes/break-exception.js.map +1 -0
  79. package/src/excecoes/continue-exception.js +27 -0
  80. package/src/excecoes/continue-exception.js.map +1 -0
  81. package/src/excecoes/erro-em-tempo-de-execucao.js +31 -0
  82. package/src/excecoes/erro-em-tempo-de-execucao.js.map +1 -0
  83. package/src/excecoes/index.js +17 -0
  84. package/src/excecoes/index.js.map +1 -0
  85. package/src/excecoes/return-exception.js +30 -0
  86. package/src/excecoes/return-exception.js.map +1 -0
  87. package/src/interfaces/avaliador-sintatico-interface.js +3 -0
  88. package/src/interfaces/avaliador-sintatico-interface.js.map +1 -0
  89. package/src/interfaces/index.js +19 -0
  90. package/src/interfaces/index.js.map +1 -0
  91. package/src/interfaces/interpretador-interface.js +3 -0
  92. package/src/interfaces/interpretador-interface.js.map +1 -0
  93. package/src/interfaces/lexador-interface.js +3 -0
  94. package/src/interfaces/lexador-interface.js.map +1 -0
  95. package/src/interfaces/pilha-interface.js +3 -0
  96. package/src/interfaces/pilha-interface.js.map +1 -0
  97. package/src/interfaces/resolvedor-interface.js +3 -0
  98. package/src/interfaces/resolvedor-interface.js.map +1 -0
  99. package/src/interfaces/simbolo-interface.js +3 -0
  100. package/src/interfaces/simbolo-interface.js.map +1 -0
  101. package/src/interpretador/dialetos/egua-classico.js +665 -0
  102. package/src/interpretador/dialetos/egua-classico.js.map +1 -0
  103. package/src/interpretador/dialetos/index.js +14 -0
  104. package/src/interpretador/dialetos/index.js.map +1 -0
  105. package/src/interpretador/index.js +665 -0
  106. package/src/interpretador/index.js.map +1 -0
  107. package/src/lexador/dialetos/egua-classico.js +287 -0
  108. package/src/lexador/dialetos/egua-classico.js.map +1 -0
  109. package/src/lexador/dialetos/index.js +14 -0
  110. package/src/lexador/dialetos/index.js.map +1 -0
  111. package/src/lexador/index.js +287 -0
  112. package/src/lexador/index.js.map +1 -0
  113. package/src/resolvedor/Pilha.js +27 -0
  114. package/src/resolvedor/Pilha.js.map +1 -0
  115. package/src/resolvedor/ResolverError.js +29 -0
  116. package/src/resolvedor/ResolverError.js.map +1 -0
  117. package/src/resolvedor/dialetos/egua-classico.js +331 -0
  118. package/src/resolvedor/dialetos/egua-classico.js.map +1 -0
  119. package/src/resolvedor/dialetos/index.js +14 -0
  120. package/src/resolvedor/dialetos/index.js.map +1 -0
  121. package/src/resolvedor/index.js +331 -0
  122. package/src/resolvedor/index.js.map +1 -0
  123. package/src/tiposDeSimbolos.js +69 -0
  124. package/src/tiposDeSimbolos.js.map +1 -0
  125. package/src/web.js +65 -69
  126. package/src/web.js.map +1 -0
  127. package/.vscode/launch.json +0 -29
  128. package/.vscode/settings.json +0 -3
  129. package/LICENSE +0 -21
  130. package/babel.config.js +0 -1
  131. package/index.html +0 -43
  132. package/src/egua.js +0 -102
  133. package/src/environment.js +0 -53
  134. package/src/errors.js +0 -17
  135. package/src/expr.js +0 -228
  136. package/src/interpreter.js +0 -798
  137. package/src/lexer.js +0 -315
  138. package/src/lib/__tests__/eguamat.test.js +0 -101
  139. package/src/lib/eguamat.js +0 -725
  140. package/src/lib/globalLib.js +0 -171
  141. package/src/lib/importStdlib.js +0 -41
  142. package/src/lib/tempo.js +0 -50
  143. package/src/parser.js +0 -826
  144. package/src/resolver.js +0 -425
  145. package/src/stmt.js +0 -215
  146. package/src/structures/callable.js +0 -5
  147. package/src/structures/class.js +0 -43
  148. package/src/structures/function.js +0 -62
  149. package/src/structures/instance.js +0 -27
  150. package/src/structures/module.js +0 -9
  151. package/src/structures/standardFn.js +0 -18
  152. package/src/tokenTypes.js +0 -67
  153. package/testes/testes.egua +0 -631
package/src/parser.js DELETED
@@ -1,826 +0,0 @@
1
- const tokenTypes = require("./tokenTypes.js");
2
- const Expr = require("./expr.js");
3
- const Stmt = require("./stmt.js");
4
-
5
- class ParserError extends Error { }
6
-
7
- /**
8
- * O avaliador sintático (Parser) é responsável por transformar tokens do Lexador em estruturas de alto nível.
9
- * Essas estruturas de alto nível são as partes que executam lógica de programação de fato.
10
- */
11
- module.exports = class Parser {
12
- constructor(simbolos, Egua) {
13
- this.simbolos = simbolos;
14
- this.Egua = Egua;
15
-
16
- this.atual = 0;
17
- this.ciclos = 0;
18
- }
19
-
20
- sincronizar() {
21
- this.avancar();
22
-
23
- while (!this.isAtEnd()) {
24
- if (this.voltar().type === tokenTypes.SEMICOLON) return;
25
-
26
- switch (this.peek().tipo) {
27
- case tokenTypes.CLASSE:
28
- case tokenTypes.FUNCAO:
29
- case tokenTypes.VAR:
30
- case tokenTypes.PARA:
31
- case tokenTypes.SE:
32
- case tokenTypes.ENQUANTO:
33
- case tokenTypes.ESCREVA:
34
- case tokenTypes.RETORNA:
35
- return;
36
- }
37
-
38
- this.avancar();
39
- }
40
- }
41
-
42
- error(token, errorMessage) {
43
- this.Egua.error(token, errorMessage);
44
- return new ParserError();
45
- }
46
-
47
- consumir(tipo, errorMessage) {
48
- if (this.verificar(tipo)) return this.avancar();
49
- else throw this.error(this.peek(), errorMessage);
50
- }
51
-
52
- verificar(tipo) {
53
- if (this.isAtEnd()) return false;
54
- return this.peek().tipo === tipo;
55
- }
56
-
57
- verificarProximo(tipo) {
58
- if (this.isAtEnd()) return false;
59
- return this.simbolos[this.atual + 1].tipo === tipo;
60
- }
61
-
62
- peek() {
63
- return this.simbolos[this.atual];
64
- }
65
-
66
- voltar() {
67
- return this.simbolos[this.atual - 1];
68
- }
69
-
70
- seek(posicao) {
71
- return this.simbolos[this.atual + posicao];
72
- }
73
-
74
- isAtEnd() {
75
- return this.peek().tipo === tokenTypes.EOF;
76
- }
77
-
78
- avancar() {
79
- if (!this.isAtEnd()) this.atual += 1;
80
- return this.voltar();
81
- }
82
-
83
- match(...args) {
84
- for (let i = 0; i < args.length; i++) {
85
- const tipoAtual = args[i];
86
- if (this.verificar(tipoAtual)) {
87
- this.avancar();
88
- return true;
89
- }
90
- }
91
-
92
- return false;
93
- }
94
-
95
- primario() {
96
- if (this.match(tokenTypes.SUPER)) {
97
- const palavraChave = this.voltar();
98
- this.consumir(tokenTypes.DOT, "Esperado '.' após 'super'.");
99
- const metodo = this.consumir(
100
- tokenTypes.IDENTIFIER,
101
- "Esperado nome do método da superclasse."
102
- );
103
- return new Expr.Super(palavraChave, metodo);
104
- }
105
- if (this.match(tokenTypes.LEFT_SQUARE_BRACKET)) {
106
- const valores = [];
107
- if (this.match(tokenTypes.RIGHT_SQUARE_BRACKET)) {
108
- return new Expr.Array([]);
109
- }
110
- while (!this.match(tokenTypes.RIGHT_SQUARE_BRACKET)) {
111
- const valor = this.atribuir();
112
- valores.push(valor);
113
- if (this.peek().tipo !== tokenTypes.RIGHT_SQUARE_BRACKET) {
114
- this.consumir(
115
- tokenTypes.COMMA,
116
- "Esperado vírgula antes da próxima expressão."
117
- );
118
- }
119
- }
120
- return new Expr.Array(valores);
121
- }
122
- if (this.match(tokenTypes.LEFT_BRACE)) {
123
- const chaves = [];
124
- const valores = [];
125
- if (this.match(tokenTypes.RIGHT_BRACE)) {
126
- return new Expr.Dictionary([], []);
127
- }
128
- while (!this.match(tokenTypes.RIGHT_BRACE)) {
129
- let chave = this.atribuir();
130
- this.consumir(
131
- tokenTypes.COLON,
132
- "Esperado ':' entre chave e valor."
133
- );
134
- let valor = this.atribuir();
135
-
136
- chaves.push(chave);
137
- valores.push(valor);
138
-
139
- if (this.peek().tipo !== tokenTypes.RIGHT_BRACE) {
140
- this.consumir(
141
- tokenTypes.COMMA,
142
- "Esperado vírgula antes da próxima expressão."
143
- );
144
- }
145
- }
146
- return new Expr.Dictionary(chaves, valores);
147
- }
148
- if (this.match(tokenTypes.FUNCAO)) return this.corpoDaFuncao("funcao");
149
- if (this.match(tokenTypes.FALSO)) return new Expr.Literal(false);
150
- if (this.match(tokenTypes.VERDADEIRO)) return new Expr.Literal(true);
151
- if (this.match(tokenTypes.NULO)) return new Expr.Literal(null);
152
- if (this.match(tokenTypes.ISTO)) return new Expr.Isto(this.voltar());
153
- if (this.match(tokenTypes.NUMBER, tokenTypes.STRING)) {
154
- return new Expr.Literal(this.voltar().literal);
155
- }
156
- if (this.match(tokenTypes.IDENTIFIER)) {
157
- return new Expr.Variable(this.voltar());
158
- }
159
- if (this.match(tokenTypes.LEFT_PAREN)) {
160
- let expr = this.expression();
161
- this.consumir(tokenTypes.RIGHT_PAREN, "Esperado ')' após a expressão.");
162
- return new Expr.Grouping(expr);
163
- }
164
- if (this.match(tokenTypes.IMPORTAR)) return this.importStatement();
165
-
166
- throw this.error(this.peek(), "Esperado expressão.");
167
- }
168
-
169
- finalizarChamada(callee) {
170
- const argumentos = [];
171
- if (!this.verificar(tokenTypes.RIGHT_PAREN)) {
172
- do {
173
- if (argumentos.length >= 255) {
174
- error(this.peek(), "Não pode haver mais de 255 argumentos.");
175
- }
176
- argumentos.push(this.expression());
177
- } while (this.match(tokenTypes.COMMA));
178
- }
179
-
180
- const parenteseDireito = this.consumir(
181
- tokenTypes.RIGHT_PAREN,
182
- "Esperado ')' após os argumentos."
183
- );
184
-
185
- return new Expr.Call(callee, parenteseDireito, argumentos);
186
- }
187
-
188
- chamar() {
189
- let expr = this.primario();
190
-
191
- while (true) {
192
- if (this.match(tokenTypes.LEFT_PAREN)) {
193
- expr = this.finalizarChamada(expr);
194
- } else if (this.match(tokenTypes.DOT)) {
195
- let name = this.consumir(
196
- tokenTypes.IDENTIFIER,
197
- "Esperado nome do método após '.'."
198
- );
199
- expr = new Expr.Get(expr, name);
200
- } else if (this.match(tokenTypes.LEFT_SQUARE_BRACKET)) {
201
- let index = this.expression();
202
- let closeBracket = this.consumir(
203
- tokenTypes.RIGHT_SQUARE_BRACKET,
204
- "Esperado ']' após escrita de index."
205
- );
206
- expr = new Expr.Subscript(expr, index, closeBracket);
207
- } else {
208
- break;
209
- }
210
- }
211
-
212
- return expr;
213
- }
214
-
215
- unario() {
216
- if (this.match(tokenTypes.BANG, tokenTypes.MINUS, tokenTypes.BIT_NOT)) {
217
- const operador = this.voltar();
218
- const direito = this.unario();
219
- return new Expr.Unary(operador, direito);
220
- }
221
-
222
- return this.chamar();
223
- }
224
-
225
- exponent() {
226
- let expr = this.unario();
227
-
228
- while (this.match(tokenTypes.STAR_STAR)) {
229
- const operador = this.voltar();
230
- const direito = this.unario();
231
- expr = new Expr.Binary(expr, operador, direito);
232
- }
233
-
234
- return expr;
235
- }
236
-
237
- multiplicar() {
238
- let expr = this.exponent();
239
-
240
- while (this.match(tokenTypes.SLASH, tokenTypes.STAR, tokenTypes.MODULUS)) {
241
- const operador = this.voltar();
242
- const direito = this.exponent();
243
- expr = new Expr.Binary(expr, operador, direito);
244
- }
245
-
246
- return expr;
247
- }
248
-
249
- adicionar() {
250
- let expr = this.multiplicar();
251
-
252
- while (this.match(tokenTypes.MINUS, tokenTypes.PLUS)) {
253
- const operador = this.voltar();
254
- const direito = this.multiplicar();
255
- expr = new Expr.Binary(expr, operador, direito);
256
- }
257
-
258
- return expr;
259
- }
260
-
261
- bitFill() {
262
- let expr = this.adicionar();
263
-
264
- while (this.match(tokenTypes.LESSER_LESSER, tokenTypes.GREATER_GREATER)) {
265
- const operador = this.voltar();
266
- const direito = this.adicionar();
267
- expr = new Expr.Binary(expr, operador, direito);
268
- }
269
-
270
- return expr;
271
- }
272
-
273
- bitE() {
274
- let expr = this.bitFill();
275
-
276
- while (this.match(tokenTypes.BIT_AND)) {
277
- const operador = this.voltar();
278
- const direito = this.bitFill();
279
- expr = new Expr.Binary(expr, operador, direito);
280
- }
281
-
282
- return expr;
283
- }
284
-
285
- bitOu() {
286
- let expr = this.bitE();
287
-
288
- while (this.match(tokenTypes.BIT_OR, tokenTypes.BIT_XOR)) {
289
- const operador = this.voltar();
290
- const direito = this.bitE();
291
- expr = new Expr.Binary(expr, operador, direito);
292
- }
293
-
294
- return expr;
295
- }
296
-
297
- comparar() {
298
- let expr = this.bitOu();
299
-
300
- while (
301
- this.match(
302
- tokenTypes.GREATER,
303
- tokenTypes.GREATER_EQUAL,
304
- tokenTypes.LESS,
305
- tokenTypes.LESS_EQUAL
306
- )
307
- ) {
308
- const operador = this.voltar();
309
- const direito = this.bitOu();
310
- expr = new Expr.Binary(expr, operador, direito);
311
- }
312
-
313
- return expr;
314
- }
315
-
316
- equality() {
317
- let expr = this.comparar();
318
-
319
- while (this.match(tokenTypes.BANG_EQUAL, tokenTypes.EQUAL_EQUAL)) {
320
- const operador = this.voltar();
321
- const direito = this.comparar();
322
- expr = new Expr.Binary(expr, operador, direito);
323
- }
324
-
325
- return expr;
326
- }
327
-
328
- em() {
329
- let expr = this.equality();
330
-
331
- while (this.match(tokenTypes.EM)) {
332
- const operador = this.voltar();
333
- const direito = this.equality();
334
- expr = new Expr.Logical(expr, operador, direito);
335
- }
336
-
337
- return expr;
338
- }
339
-
340
- e() {
341
- let expr = this.em();
342
-
343
- while (this.match(tokenTypes.E)) {
344
- const operador = this.voltar();
345
- const direito = this.em();
346
- expr = new Expr.Logical(expr, operador, direito);
347
- }
348
-
349
- return expr;
350
- }
351
-
352
- ou() {
353
- let expr = this.e();
354
-
355
- while (this.match(tokenTypes.OU)) {
356
- const operador = this.voltar();
357
- const direito = this.e();
358
- expr = new Expr.Logical(expr, operador, direito);
359
- }
360
-
361
- return expr;
362
- }
363
-
364
- atribuir() {
365
- const expr = this.ou();
366
-
367
- if (this.match(tokenTypes.EQUAL) || this.match(tokenTypes.MAIS_IGUAL)) {
368
- const igual = this.voltar();
369
- const valor = this.atribuir();
370
-
371
- if (expr instanceof Expr.Variable) {
372
- const nome = expr.name;
373
- return new Expr.Assign(nome, valor);
374
- } else if (expr instanceof Expr.Get) {
375
- const get = expr;
376
- return new Expr.Set(get.object, get.name, valor);
377
- } else if (expr instanceof Expr.Subscript) {
378
- return new Expr.Assignsubscript(expr.callee, expr.index, valor);
379
- }
380
- this.error(igual, "Tarefa de atribuição inválida");
381
- }
382
-
383
- return expr;
384
- }
385
-
386
- expression() {
387
- return this.atribuir();
388
- }
389
-
390
- declaracaoMostrar() {
391
- this.consumir(
392
- tokenTypes.LEFT_PAREN,
393
- "Esperado '(' antes dos valores em escreva."
394
- );
395
-
396
- const valor = this.expression();
397
-
398
- this.consumir(
399
- tokenTypes.RIGHT_PAREN,
400
- "Esperado ')' após os valores em escreva."
401
- );
402
- this.consumir(tokenTypes.SEMICOLON, "Esperado ';' após o valor.");
403
-
404
- return new Stmt.Escreva(valor);
405
- }
406
-
407
- expressionStatement() {
408
- const expr = this.expression();
409
- this.consumir(tokenTypes.SEMICOLON, "Esperado ';' após expressão.");
410
- return new Stmt.Expression(expr);
411
- }
412
-
413
- block() {
414
- const declaracoes = [];
415
-
416
- while (!this.verificar(tokenTypes.RIGHT_BRACE) && !this.isAtEnd()) {
417
- declaracoes.push(this.declaracao());
418
- }
419
-
420
- this.consumir(tokenTypes.RIGHT_BRACE, "Esperado '}' após o bloco.");
421
- return declaracoes;
422
- }
423
-
424
- declaracaoSe() {
425
- this.consumir(tokenTypes.LEFT_PAREN, "Esperado '(' após 'se'.");
426
- const condicao = this.expression();
427
- this.consumir(tokenTypes.RIGHT_PAREN, "Esperado ')' após condição do se.");
428
-
429
- const thenBranch = this.statement();
430
-
431
- const elifBranches = [];
432
- while (this.match(tokenTypes.SENAOSE)) {
433
- this.consumir(tokenTypes.LEFT_PAREN, "Esperado '(' após 'senaose'.");
434
- let elifCondition = this.expression();
435
- this.consumir(
436
- tokenTypes.RIGHT_PAREN,
437
- "Esperado ')' apóes codição do 'senaose."
438
- );
439
-
440
- const branch = this.statement();
441
-
442
- elifBranches.push({
443
- condition: elifCondition,
444
- branch
445
- });
446
- }
447
-
448
- let elseBranch = null;
449
- if (this.match(tokenTypes.SENAO)) {
450
- elseBranch = this.statement();
451
- }
452
-
453
- return new Stmt.Se(condicao, thenBranch, elifBranches, elseBranch);
454
- }
455
-
456
- whileStatement() {
457
- try {
458
- this.ciclos += 1;
459
-
460
- this.consumir(tokenTypes.LEFT_PAREN, "Esperado '(' após 'enquanto'.");
461
- const condicao = this.expression();
462
- this.consumir(tokenTypes.RIGHT_PAREN, "Esperado ')' após condicional.");
463
- const corpo = this.statement();
464
-
465
- return new Stmt.Enquanto(condicao, corpo);
466
- } finally {
467
- this.ciclos -= 1;
468
- }
469
- }
470
-
471
- forStatement() {
472
- try {
473
- this.ciclos += 1;
474
-
475
- this.consumir(tokenTypes.LEFT_PAREN, "Esperado '(' após 'para'.");
476
-
477
- let initializer;
478
- if (this.match(tokenTypes.SEMICOLON)) {
479
- initializer = null;
480
- } else if (this.match(tokenTypes.VAR)) {
481
- initializer = this.declaracaoDeVariavel();
482
- } else {
483
- initializer = this.expressionStatement();
484
- }
485
-
486
- let condition = null;
487
- if (!this.verificar(tokenTypes.SEMICOLON)) {
488
- condition = this.expression();
489
- }
490
-
491
- this.consumir(
492
- tokenTypes.SEMICOLON,
493
- "Esperado ';' após valores da condicional"
494
- );
495
-
496
- let incrementar = null;
497
- if (!this.verificar(tokenTypes.RIGHT_PAREN)) {
498
- incrementar = this.expression();
499
- }
500
-
501
- this.consumir(tokenTypes.RIGHT_PAREN, "Esperado ')' após cláusulas");
502
-
503
- const corpo = this.statement();
504
-
505
- return new Stmt.Para(initializer, condition, incrementar, corpo);
506
- } finally {
507
- this.ciclos -= 1;
508
- }
509
- }
510
-
511
- breakStatement() {
512
- if (this.ciclos < 1) {
513
- this.error(this.voltar(), "'pausa' deve estar dentro de um loop.");
514
- }
515
-
516
- this.consumir(tokenTypes.SEMICOLON, "Esperado ';' após 'pausa'.");
517
- return new Stmt.Pausa();
518
- }
519
-
520
- declaracaoContinue() {
521
- if (this.ciclos < 1) {
522
- this.error(this.voltar(), "'continua' precisa estar em um laço de repetição.");
523
- }
524
-
525
- this.consumir(tokenTypes.SEMICOLON, "Esperado ';' após 'continua'.");
526
- return new Stmt.Continua();
527
- }
528
-
529
- declaracaoRetorna() {
530
- const palavraChave = this.voltar();
531
- let valor = null;
532
-
533
- if (!this.verificar(tokenTypes.SEMICOLON)) {
534
- valor = this.expression();
535
- }
536
-
537
- this.consumir(tokenTypes.SEMICOLON, "Esperado ';' após o retorno.");
538
- return new Stmt.Retorna(palavraChave, valor);
539
- }
540
-
541
- declaracaoEscolha() {
542
- try {
543
- this.ciclos += 1;
544
-
545
- this.consumir(
546
- tokenTypes.LEFT_PAREN,
547
- "Esperado '{' após 'escolha'."
548
- );
549
- let condition = this.expression();
550
- this.consumir(
551
- tokenTypes.RIGHT_PAREN,
552
- "Esperado '}' após a condição de 'escolha'."
553
- );
554
- this.consumir(
555
- tokenTypes.LEFT_BRACE,
556
- "Esperado '{' antes do escopo do 'escolha'."
557
- );
558
-
559
- const branches = [];
560
- let defaultBranch = null;
561
- while (!this.match(tokenTypes.RIGHT_BRACE) && !this.isAtEnd()) {
562
- if (this.match(tokenTypes.CASO)) {
563
- let branchConditions = [this.expression()];
564
- this.consumir(
565
- tokenTypes.COLON,
566
- "Esperado ':' após o 'caso'."
567
- );
568
-
569
- while (this.verificar(tokenTypes.CASO)) {
570
- this.consumir(tokenTypes.CASO, null);
571
- branchConditions.push(this.expression());
572
- this.consumir(
573
- tokenTypes.COLON,
574
- "Esperado ':' após declaração do 'caso'."
575
- );
576
- }
577
-
578
- const stmts = [];
579
- do {
580
- stmts.push(this.statement());
581
- } while (
582
- !this.verificar(tokenTypes.CASO) &&
583
- !this.verificar(tokenTypes.PADRAO) &&
584
- !this.verificar(tokenTypes.RIGHT_BRACE)
585
- );
586
-
587
- branches.push({
588
- conditions: branchConditions,
589
- stmts
590
- });
591
- } else if (this.match(tokenTypes.PADRAO)) {
592
- if (defaultBranch !== null)
593
- throw new ParserError(
594
- "Você só pode ter um 'padrao' em cada declaração de 'escolha'."
595
- );
596
-
597
- this.consumir(
598
- tokenTypes.COLON,
599
- "Esperado ':' após declaração do 'padrao'."
600
- );
601
-
602
- const stmts = [];
603
- do {
604
- stmts.push(this.statement());
605
- } while (
606
- !this.verificar(tokenTypes.CASO) &&
607
- !this.verificar(tokenTypes.PADRAO) &&
608
- !this.verificar(tokenTypes.RIGHT_BRACE)
609
- );
610
-
611
- defaultBranch = {
612
- stmts
613
- };
614
- }
615
- }
616
-
617
- return new Stmt.Escolha(condition, branches, defaultBranch);
618
- } finally {
619
- this.ciclos -= 1;
620
- }
621
- }
622
-
623
- importStatement() {
624
- this.consumir(tokenTypes.LEFT_PAREN, "Esperado '(' após declaração.");
625
-
626
- const caminho = this.expression();
627
-
628
- let closeBracket = this.consumir(
629
- tokenTypes.RIGHT_PAREN,
630
- "Esperado ')' após declaração."
631
- );
632
-
633
- return new Stmt.Importar(caminho, closeBracket);
634
- }
635
-
636
- tryStatement() {
637
- this.consumir(tokenTypes.LEFT_BRACE, "Esperado '{' após a declaração 'tente'.");
638
-
639
- let tryBlock = this.block();
640
-
641
- let catchBlock = null;
642
- if (this.match(tokenTypes.PEGUE)) {
643
- this.consumir(
644
- tokenTypes.LEFT_BRACE,
645
- "Esperado '{' após a declaração 'pegue'."
646
- );
647
-
648
- catchBlock = this.block();
649
- }
650
-
651
- let elseBlock = null;
652
- if (this.match(tokenTypes.SENAO)) {
653
- this.consumir(
654
- tokenTypes.LEFT_BRACE,
655
- "Esperado '{' após a declaração 'pegue'."
656
- );
657
-
658
- elseBlock = this.block();
659
- }
660
-
661
- let finallyBlock = null;
662
- if (this.match(tokenTypes.FINALMENTE)) {
663
- this.consumir(
664
- tokenTypes.LEFT_BRACE,
665
- "Esperado '{' após a declaração 'pegue'."
666
- );
667
-
668
- finallyBlock = this.block();
669
- }
670
-
671
- return new Stmt.Tente(tryBlock, catchBlock, elseBlock, finallyBlock);
672
- }
673
-
674
- doStatement() {
675
- try {
676
- this.ciclos += 1;
677
-
678
- const doBranch = this.statement();
679
-
680
- this.consumir(
681
- tokenTypes.ENQUANTO,
682
- "Esperado declaração do 'enquanto' após o escopo do 'fazer'."
683
- );
684
- this.consumir(
685
- tokenTypes.LEFT_PAREN,
686
- "Esperado '(' após declaração 'enquanto'."
687
- );
688
-
689
- const whileCondition = this.expression();
690
-
691
- this.consumir(
692
- tokenTypes.RIGHT_PAREN,
693
- "Esperado ')' após declaração do 'enquanto'."
694
- );
695
-
696
- return new Stmt.Fazer(doBranch, whileCondition);
697
- } finally {
698
- this.ciclos -= 1;
699
- }
700
- }
701
-
702
- statement() {
703
- if (this.match(tokenTypes.FAZER)) return this.doStatement();
704
- if (this.match(tokenTypes.TENTE)) return this.tryStatement();
705
- if (this.match(tokenTypes.ESCOLHA)) return this.declaracaoEscolha();
706
- if (this.match(tokenTypes.RETORNA)) return this.declaracaoRetorna();
707
- if (this.match(tokenTypes.CONTINUA)) return this.declaracaoContinue();
708
- if (this.match(tokenTypes.PAUSA)) return this.breakStatement();
709
- if (this.match(tokenTypes.PARA)) return this.forStatement();
710
- if (this.match(tokenTypes.ENQUANTO)) return this.whileStatement();
711
- if (this.match(tokenTypes.SE)) return this.declaracaoSe();
712
- if (this.match(tokenTypes.ESCREVA)) return this.declaracaoMostrar();
713
- if (this.match(tokenTypes.LEFT_BRACE)) return new Stmt.Block(this.block());
714
-
715
- return this.expressionStatement();
716
- }
717
-
718
- declaracaoDeVariavel() {
719
- let name = this.consumir(tokenTypes.IDENTIFIER, "Esperado nome de variável.");
720
- let initializer = null;
721
- if (this.match(tokenTypes.EQUAL) || this.match(tokenTypes.MAIS_IGUAL)) {
722
- initializer = this.expression();
723
- }
724
-
725
- this.consumir(
726
- tokenTypes.SEMICOLON,
727
- "Esperado ';' após a declaração da variável."
728
- );
729
- return new Stmt.Var(name, initializer);
730
- }
731
-
732
- funcao(kind) {
733
- const nome = this.consumir(tokenTypes.IDENTIFIER, `Esperado nome ${kind}.`);
734
- return new Stmt.Funcao(nome, this.corpoDaFuncao(kind));
735
- }
736
-
737
- corpoDaFuncao(kind) {
738
- this.consumir(tokenTypes.LEFT_PAREN, `Esperado '(' após o nome ${kind}.`);
739
-
740
- let parametros = [];
741
- if (!this.verificar(tokenTypes.RIGHT_PAREN)) {
742
- do {
743
- if (parametros.length >= 255) {
744
- this.error(this.peek(), "Não pode haver mais de 255 parâmetros");
745
- }
746
-
747
- let paramObj = {};
748
-
749
- if (this.peek().tipo === tokenTypes.STAR) {
750
- this.consumir(tokenTypes.STAR, null);
751
- paramObj["type"] = "wildcard";
752
- } else {
753
- paramObj["type"] = "standard";
754
- }
755
-
756
- paramObj['name'] = this.consumir(
757
- tokenTypes.IDENTIFIER,
758
- "Esperado nome do parâmetro."
759
- );
760
-
761
- if (this.match(tokenTypes.EQUAL)) {
762
- paramObj["default"] = this.primario();
763
- }
764
-
765
- parametros.push(paramObj);
766
-
767
- if (paramObj["type"] === "wildcard") break;
768
- } while (this.match(tokenTypes.COMMA));
769
- }
770
-
771
- this.consumir(tokenTypes.RIGHT_PAREN, "Esperado ')' após parâmetros.");
772
- this.consumir(tokenTypes.LEFT_BRACE, `Esperado '{' antes do escopo do ${kind}.`);
773
-
774
- const corpo = this.block();
775
-
776
- return new Expr.Funcao(parametros, corpo);
777
- }
778
-
779
- declaracaoDeClasse() {
780
- const nome = this.consumir(tokenTypes.IDENTIFIER, "Esperado nome da classe.");
781
-
782
- let superClasse = null;
783
- if (this.match(tokenTypes.HERDA)) {
784
- this.consumir(tokenTypes.IDENTIFIER, "Esperado nome da superclasse.");
785
- superClasse = new Expr.Variable(this.voltar());
786
- }
787
-
788
- this.consumir(tokenTypes.LEFT_BRACE, "Esperado '{' antes do escopo da classe.");
789
-
790
- const metodos = [];
791
- while (!this.verificar(tokenTypes.RIGHT_BRACE) && !this.isAtEnd()) {
792
- metodos.push(this.funcao("método"));
793
- }
794
-
795
- this.consumir(tokenTypes.RIGHT_BRACE, "Esperado '}' após o escopo da classe.");
796
- return new Stmt.Classe(nome, superClasse, metodos);
797
- }
798
-
799
- declaracao() {
800
- try {
801
- if (
802
- this.verificar(tokenTypes.FUNCAO) &&
803
- this.verificarProximo(tokenTypes.IDENTIFIER)
804
- ) {
805
- this.consumir(tokenTypes.FUNCAO, null);
806
- return this.funcao("funcao");
807
- }
808
- if (this.match(tokenTypes.VAR)) return this.declaracaoDeVariavel();
809
- if (this.match(tokenTypes.CLASSE)) return this.declaracaoDeClasse();
810
-
811
- return this.statement();
812
- } catch (error) {
813
- this.sincronizar();
814
- return null;
815
- }
816
- }
817
-
818
- analisar() {
819
- const declaracoes = [];
820
- while (!this.isAtEnd()) {
821
- declaracoes.push(this.declaracao());
822
- }
823
-
824
- return declaracoes
825
- }
826
- };