@designliquido/delegua 1.17.0 → 1.17.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.
- package/analisador-semantico/analisador-semantico.d.ts.map +1 -1
- package/analisador-semantico/analisador-semantico.js +9 -3
- package/analisador-semantico/analisador-semantico.js.map +1 -1
- package/analisador-semantico/dialetos/analisador-semantico-pitugues.d.ts.map +1 -1
- package/analisador-semantico/dialetos/analisador-semantico-pitugues.js +9 -3
- package/analisador-semantico/dialetos/analisador-semantico-pitugues.js.map +1 -1
- package/avaliador-sintatico/avaliador-sintatico.d.ts.map +1 -1
- package/avaliador-sintatico/avaliador-sintatico.js +26 -0
- package/avaliador-sintatico/avaliador-sintatico.js.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts +7 -0
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js +33 -13
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-ipt.d.ts +68 -11
- package/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-ipt.d.ts.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-ipt.js +433 -62
- package/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-ipt.js.map +1 -1
- package/bibliotecas/dialetos/pitugues/biblioteca-global.d.ts +9 -0
- package/bibliotecas/dialetos/pitugues/biblioteca-global.d.ts.map +1 -1
- package/bibliotecas/dialetos/pitugues/biblioteca-global.js +30 -0
- package/bibliotecas/dialetos/pitugues/biblioteca-global.js.map +1 -1
- package/bibliotecas/dialetos/pitugues/primitivas-texto.d.ts.map +1 -1
- package/bibliotecas/dialetos/pitugues/primitivas-texto.js +112 -16
- package/bibliotecas/dialetos/pitugues/primitivas-texto.js.map +1 -1
- package/bibliotecas/primitivas-dicionario.d.ts.map +1 -1
- package/bibliotecas/primitivas-dicionario.js +31 -0
- package/bibliotecas/primitivas-dicionario.js.map +1 -1
- package/bin/package.json +2 -2
- package/estilizador/quebrador-linha.d.ts.map +1 -1
- package/estilizador/quebrador-linha.js +13 -0
- package/estilizador/quebrador-linha.js.map +1 -1
- package/estilizador/regras/index.d.ts +1 -0
- package/estilizador/regras/index.d.ts.map +1 -1
- package/estilizador/regras/index.js +1 -0
- package/estilizador/regras/index.js.map +1 -1
- package/estilizador/regras/regra-convencao-nomenclatura.d.ts +3 -0
- package/estilizador/regras/regra-convencao-nomenclatura.d.ts.map +1 -1
- package/estilizador/regras/regra-convencao-nomenclatura.js +34 -14
- package/estilizador/regras/regra-convencao-nomenclatura.js.map +1 -1
- package/estilizador/regras/regra-explicitar-tipos-parametros.d.ts +16 -0
- package/estilizador/regras/regra-explicitar-tipos-parametros.d.ts.map +1 -0
- package/estilizador/regras/regra-explicitar-tipos-parametros.js +50 -0
- package/estilizador/regras/regra-explicitar-tipos-parametros.js.map +1 -0
- package/formatadores/formatador-delegua.d.ts +1 -0
- package/formatadores/formatador-delegua.d.ts.map +1 -1
- package/formatadores/formatador-delegua.js +9 -3
- package/formatadores/formatador-delegua.js.map +1 -1
- package/interpretador/dialetos/egua-classico/interpretador-egua-classico.d.ts +1 -1
- package/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.d.ts +60 -107
- package/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.d.ts.map +1 -1
- package/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.js +435 -336
- package/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.js.map +1 -1
- package/interpretador/interpretador-base.d.ts.map +1 -1
- package/interpretador/interpretador-base.js +16 -2
- package/interpretador/interpretador-base.js.map +1 -1
- package/lexador/dialetos/lexador-portugol-ipt.d.ts.map +1 -1
- package/lexador/dialetos/lexador-portugol-ipt.js +71 -19
- package/lexador/dialetos/lexador-portugol-ipt.js.map +1 -1
- package/lexador/dialetos/palavras-reservadas/portugol-ipt.d.ts +34 -6
- package/lexador/dialetos/palavras-reservadas/portugol-ipt.d.ts.map +1 -1
- package/lexador/dialetos/palavras-reservadas/portugol-ipt.js +44 -6
- package/lexador/dialetos/palavras-reservadas/portugol-ipt.js.map +1 -1
- package/package.json +2 -2
- package/tipos-de-simbolos/portugol-ipt.d.ts +43 -19
- package/tipos-de-simbolos/portugol-ipt.d.ts.map +1 -1
- package/tipos-de-simbolos/portugol-ipt.js +59 -19
- package/tipos-de-simbolos/portugol-ipt.js.map +1 -1
- package/tradutores/tradutor-portugol-ipt.d.ts +34 -12
- package/tradutores/tradutor-portugol-ipt.d.ts.map +1 -1
- package/tradutores/tradutor-portugol-ipt.js +309 -19
- package/tradutores/tradutor-portugol-ipt.js.map +1 -1
- package/umd/delegua.js +1501 -522
|
@@ -4,6 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.InterpretadorPortugolIpt = void 0;
|
|
7
|
+
const construtos_1 = require("../../../construtos");
|
|
8
|
+
const declaracoes_1 = require("../../../declaracoes");
|
|
7
9
|
const espaco_memoria_1 = require("../../espaco-memoria");
|
|
8
10
|
const estruturas_1 = require("../../estruturas");
|
|
9
11
|
const excecoes_1 = require("../../../excecoes");
|
|
@@ -34,145 +36,65 @@ class InterpretadorPortugolIpt {
|
|
|
34
36
|
};
|
|
35
37
|
this.pilhaEscoposExecucao.empilhar(escopoExecucao);
|
|
36
38
|
}
|
|
37
|
-
|
|
38
|
-
visitarExpressaoTuplaN(expressao) {
|
|
39
|
-
throw new Error('Método não implementado.');
|
|
40
|
-
}
|
|
41
|
-
/* istanbul ignore next */
|
|
42
|
-
visitarExpressaoAcessoIntervaloVariavel(expressao) {
|
|
43
|
-
throw new Error('Método não implementado.');
|
|
44
|
-
}
|
|
45
|
-
/* istanbul ignore next */
|
|
46
|
-
visitarDeclaracaoTextoDocumentacao(declaracao) {
|
|
47
|
-
throw new Error('Método não implementado.');
|
|
48
|
-
}
|
|
49
|
-
/* istanbul ignore next */
|
|
50
|
-
visitarExpressaoSeparador(expressao) {
|
|
51
|
-
throw new Error('Método não implementado.');
|
|
52
|
-
}
|
|
53
|
-
/* istanbul ignore next */
|
|
54
|
-
visitarExpressaoComentario(expressao) {
|
|
55
|
-
throw new Error('Método não implementado.');
|
|
56
|
-
}
|
|
39
|
+
// ── Utilitários ─────────────────────────────────────────────────────────────
|
|
57
40
|
resolverValor(objeto) {
|
|
58
|
-
if (objeto === null || objeto === undefined)
|
|
41
|
+
if (objeto === null || objeto === undefined)
|
|
59
42
|
return objeto;
|
|
60
|
-
|
|
61
|
-
if (objeto.hasOwnProperty('valor')) {
|
|
43
|
+
if (objeto.hasOwnProperty('valor'))
|
|
62
44
|
return objeto.valor;
|
|
63
|
-
}
|
|
64
45
|
return objeto;
|
|
65
46
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
/* istanbul ignore next */
|
|
75
|
-
visitarExpressaoAcessoMetodo(expressao) {
|
|
76
|
-
throw new Error('Método não implementado.');
|
|
77
|
-
}
|
|
78
|
-
/* istanbul ignore next */
|
|
79
|
-
visitarExpressaoAcessoPropriedade(expressao) {
|
|
80
|
-
throw new Error('Método não implementado.');
|
|
81
|
-
}
|
|
82
|
-
visitarDeclaracaoComentario(declaracao) {
|
|
83
|
-
return Promise.resolve();
|
|
84
|
-
}
|
|
85
|
-
/* istanbul ignore next */
|
|
86
|
-
visitarDeclaracaoTendoComo(declaracao) {
|
|
87
|
-
throw new Error('Método não implementado.');
|
|
88
|
-
}
|
|
89
|
-
/* istanbul ignore next */
|
|
90
|
-
visitarDeclaracaoInicioAlgoritmo(declaracao) {
|
|
91
|
-
throw new Error('Método não implementado.');
|
|
92
|
-
}
|
|
93
|
-
/* istanbul ignore next */
|
|
94
|
-
visitarDeclaracaoCabecalhoPrograma(declaracao) {
|
|
95
|
-
throw new Error('Método não implementado.');
|
|
96
|
-
}
|
|
97
|
-
/* istanbul ignore next */
|
|
98
|
-
visitarExpressaoTupla(expressao) {
|
|
99
|
-
throw new Error('Método não implementado.');
|
|
100
|
-
}
|
|
101
|
-
/* istanbul ignore next */
|
|
102
|
-
visitarExpressaoAcessoElementoMatriz(expressao) {
|
|
103
|
-
throw new Error('Método não implementado.');
|
|
104
|
-
}
|
|
105
|
-
/* istanbul ignore next */
|
|
106
|
-
visitarExpressaoAtribuicaoPorIndicesMatriz(expressao) {
|
|
107
|
-
throw new Error('Método não implementado.');
|
|
108
|
-
}
|
|
109
|
-
/* istanbul ignore next */
|
|
110
|
-
visitarExpressaoExpressaoRegular(expressao) {
|
|
111
|
-
throw new Error('Método não implementado.');
|
|
47
|
+
eVerdadeiro(objeto) {
|
|
48
|
+
if (objeto === null)
|
|
49
|
+
return false;
|
|
50
|
+
if (typeof objeto === 'boolean')
|
|
51
|
+
return Boolean(objeto);
|
|
52
|
+
if (objeto.hasOwnProperty('valor'))
|
|
53
|
+
return Boolean(objeto.valor);
|
|
54
|
+
return true;
|
|
112
55
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
56
|
+
eIgual(esquerda, direita) {
|
|
57
|
+
if (esquerda === null && direita === null)
|
|
58
|
+
return true;
|
|
59
|
+
if (esquerda === null)
|
|
60
|
+
return false;
|
|
61
|
+
return esquerda === direita;
|
|
116
62
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
63
|
+
verificarOperandosNumeros(operador, direita, esquerda) {
|
|
64
|
+
const valorDireita = this.resolverValor(direita);
|
|
65
|
+
const valorEsquerda = this.resolverValor(esquerda);
|
|
66
|
+
const tipoDireita = direita?.tipo ?? (typeof valorDireita === 'number' ? 'número' : String(NaN));
|
|
67
|
+
const tipoEsquerda = esquerda?.tipo ?? (typeof valorEsquerda === 'number' ? 'número' : String(NaN));
|
|
68
|
+
const tiposNumericos = ['inteiro', 'numero', 'número', 'real'];
|
|
69
|
+
const eNumericoOuQualquer = (tipo, valor) => tiposNumericos.includes(tipo.toLowerCase()) ||
|
|
70
|
+
tipo === 'qualquer' && typeof valor === 'number';
|
|
71
|
+
if (eNumericoOuQualquer(tipoDireita, valorDireita) && eNumericoOuQualquer(tipoEsquerda, valorEsquerda))
|
|
72
|
+
return;
|
|
73
|
+
throw new excecoes_1.ErroEmTempoDeExecucao(operador, 'Operadores precisam ser números.', operador.linha);
|
|
120
74
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
75
|
+
paraTexto(objeto) {
|
|
76
|
+
if (objeto === null || objeto === undefined)
|
|
77
|
+
return 'nulo';
|
|
78
|
+
if (typeof objeto === 'boolean')
|
|
79
|
+
return objeto ? 'verdadeiro' : 'falso';
|
|
80
|
+
if (objeto instanceof Date) {
|
|
81
|
+
return Intl.DateTimeFormat('pt', { dateStyle: 'full', timeStyle: 'full' }).format(objeto);
|
|
82
|
+
}
|
|
83
|
+
if (Array.isArray(objeto))
|
|
84
|
+
return objeto;
|
|
85
|
+
if (objeto.valor instanceof estruturas_1.ObjetoPadrao)
|
|
86
|
+
return objeto.valor.paraTexto();
|
|
87
|
+
if (typeof objeto === 'object')
|
|
88
|
+
return JSON.stringify(objeto);
|
|
89
|
+
return objeto.toString();
|
|
124
90
|
}
|
|
91
|
+
// ── Expressões ──────────────────────────────────────────────────────────────
|
|
125
92
|
visitarExpressaoLiteral(expressao) {
|
|
126
93
|
return Promise.resolve(expressao.valor);
|
|
127
94
|
}
|
|
128
|
-
async avaliar(expressao) {
|
|
129
|
-
// Descomente o código abaixo quando precisar detectar expressões undefined ou nulas.
|
|
130
|
-
// Por algum motivo o depurador do VSCode não funciona direito aqui
|
|
131
|
-
// com breakpoint condicional.
|
|
132
|
-
/* if (expressao === null || expressao === undefined) {
|
|
133
|
-
console.log('Aqui');
|
|
134
|
-
} */
|
|
135
|
-
return await expressao.aceitar(this);
|
|
136
|
-
}
|
|
137
95
|
async visitarExpressaoAgrupamento(expressao) {
|
|
138
96
|
return await this.avaliar(expressao.expressao);
|
|
139
97
|
}
|
|
140
|
-
/* istanbul ignore next */
|
|
141
|
-
visitarExpressaoUnaria(expressao) {
|
|
142
|
-
throw new Error('Método não implementado');
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Verifica se operandos são números, que podem ser tanto variáveis puras do JavaScript
|
|
146
|
-
* (neste caso, `number`), ou podem ser variáveis de Delégua com inferência (`VariavelInterface`).
|
|
147
|
-
* @param operador O símbolo do operador.
|
|
148
|
-
* @param direita O operando direito.
|
|
149
|
-
* @param esquerda O operando esquerdo.
|
|
150
|
-
* @returns Se ambos os operandos são números ou não.
|
|
151
|
-
*/
|
|
152
|
-
verificarOperandosNumeros(operador, direita, esquerda) {
|
|
153
|
-
const tipoDireita = direita.tipo
|
|
154
|
-
? direita.tipo
|
|
155
|
-
: typeof direita === 'number'
|
|
156
|
-
? 'número'
|
|
157
|
-
: String(NaN);
|
|
158
|
-
const tipoEsquerda = esquerda.tipo
|
|
159
|
-
? esquerda.tipo
|
|
160
|
-
: typeof esquerda === 'number'
|
|
161
|
-
? 'número'
|
|
162
|
-
: String(NaN);
|
|
163
|
-
const tiposNumericos = ['inteiro', 'numero', 'número', 'real'];
|
|
164
|
-
if (tiposNumericos.includes(tipoDireita.toLowerCase()) &&
|
|
165
|
-
tiposNumericos.includes(tipoEsquerda.toLowerCase()))
|
|
166
|
-
return;
|
|
167
|
-
throw new excecoes_1.ErroEmTempoDeExecucao(operador, 'Operadores precisam ser números.', operador.linha);
|
|
168
|
-
}
|
|
169
|
-
eIgual(esquerda, direita) {
|
|
170
|
-
if (esquerda === null && direita === null)
|
|
171
|
-
return true;
|
|
172
|
-
if (esquerda === null)
|
|
173
|
-
return false;
|
|
174
|
-
return esquerda === direita;
|
|
175
|
-
}
|
|
176
98
|
async visitarExpressaoBinaria(expressao) {
|
|
177
99
|
try {
|
|
178
100
|
const esquerda = await this.avaliar(expressao.esquerda);
|
|
@@ -185,6 +107,9 @@ class InterpretadorPortugolIpt {
|
|
|
185
107
|
const tipoDireito = direita?.hasOwnProperty('tipo')
|
|
186
108
|
? direita.tipo
|
|
187
109
|
: (0, inferenciador_1.inferirTipoVariavel)(direita);
|
|
110
|
+
const tiposNumericos = ['inteiro', 'numero', 'número', 'real'];
|
|
111
|
+
const ambosNumericos = (tiposNumericos.includes(tipoEsquerdo) || tipoEsquerdo === 'qualquer' && typeof valorEsquerdo === 'number') &&
|
|
112
|
+
(tiposNumericos.includes(tipoDireito) || tipoDireito === 'qualquer' && typeof valorDireito === 'number');
|
|
188
113
|
switch (expressao.operador.tipo) {
|
|
189
114
|
case portugol_ipt_1.default.EXPONENCIACAO:
|
|
190
115
|
this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
|
|
@@ -205,12 +130,10 @@ class InterpretadorPortugolIpt {
|
|
|
205
130
|
this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
|
|
206
131
|
return Number(valorEsquerdo) - Number(valorDireito);
|
|
207
132
|
case portugol_ipt_1.default.ADICAO:
|
|
208
|
-
if (
|
|
133
|
+
if (ambosNumericos) {
|
|
209
134
|
return Number(valorEsquerdo) + Number(valorDireito);
|
|
210
135
|
}
|
|
211
|
-
|
|
212
|
-
return String(valorEsquerdo) + String(valorDireito);
|
|
213
|
-
}
|
|
136
|
+
return String(valorEsquerdo) + String(valorDireito);
|
|
214
137
|
case portugol_ipt_1.default.DIVISAO:
|
|
215
138
|
this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
|
|
216
139
|
return Number(valorEsquerdo) / Number(valorDireito);
|
|
@@ -219,15 +142,11 @@ class InterpretadorPortugolIpt {
|
|
|
219
142
|
return Math.floor(Number(valorEsquerdo) / Number(valorDireito));
|
|
220
143
|
case portugol_ipt_1.default.MULTIPLICACAO:
|
|
221
144
|
if (tipoEsquerdo === 'texto' || tipoDireito === 'texto') {
|
|
222
|
-
// Sem ambos os valores resolvem como texto, multiplica normal.
|
|
223
|
-
// Se apenas um resolve como texto, o outro repete o
|
|
224
|
-
// texto n vezes, sendo n o valor do outro.
|
|
225
145
|
if (tipoEsquerdo === 'texto' && tipoDireito === 'texto') {
|
|
226
146
|
return Number(valorEsquerdo) * Number(valorDireito);
|
|
227
147
|
}
|
|
228
|
-
if (tipoEsquerdo === 'texto')
|
|
148
|
+
if (tipoEsquerdo === 'texto')
|
|
229
149
|
return valorEsquerdo.repeat(Number(valorDireito));
|
|
230
|
-
}
|
|
231
150
|
return valorDireito.repeat(Number(valorEsquerdo));
|
|
232
151
|
}
|
|
233
152
|
return Number(valorEsquerdo) * Number(valorDireito);
|
|
@@ -244,125 +163,155 @@ class InterpretadorPortugolIpt {
|
|
|
244
163
|
return Promise.reject(erro);
|
|
245
164
|
}
|
|
246
165
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
166
|
+
async visitarExpressaoLogica(expressao) {
|
|
167
|
+
const esquerda = await this.avaliar(expressao.esquerda);
|
|
168
|
+
switch (expressao.operador.tipo) {
|
|
169
|
+
case portugol_ipt_1.default.OU:
|
|
170
|
+
if (this.eVerdadeiro(esquerda))
|
|
171
|
+
return true;
|
|
172
|
+
return this.eVerdadeiro(await this.avaliar(expressao.direita));
|
|
173
|
+
case portugol_ipt_1.default.XOU: {
|
|
174
|
+
const ve = this.eVerdadeiro(esquerda);
|
|
175
|
+
const vd = this.eVerdadeiro(await this.avaliar(expressao.direita));
|
|
176
|
+
return ve !== vd;
|
|
177
|
+
}
|
|
178
|
+
case portugol_ipt_1.default.E:
|
|
179
|
+
if (!this.eVerdadeiro(esquerda))
|
|
180
|
+
return false;
|
|
181
|
+
return this.eVerdadeiro(await this.avaliar(expressao.direita));
|
|
182
|
+
}
|
|
183
|
+
return await this.avaliar(expressao.direita);
|
|
184
|
+
}
|
|
185
|
+
async visitarExpressaoUnaria(expressao) {
|
|
186
|
+
const operando = await this.avaliar(expressao.operando);
|
|
187
|
+
const valor = this.resolverValor(operando);
|
|
188
|
+
switch (expressao.operador.tipo) {
|
|
189
|
+
case portugol_ipt_1.default.SUBTRACAO:
|
|
190
|
+
return -Number(valor);
|
|
191
|
+
case portugol_ipt_1.default.NEGACAO:
|
|
192
|
+
case portugol_ipt_1.default.NAO:
|
|
193
|
+
return !this.eVerdadeiro(valor);
|
|
194
|
+
}
|
|
195
|
+
throw new excecoes_1.ErroEmTempoDeExecucao(expressao.operador, `Operador unário desconhecido: ${expressao.operador.lexema}`, expressao.operador.linha);
|
|
254
196
|
}
|
|
255
|
-
|
|
256
|
-
|
|
197
|
+
async visitarExpressaoDeAtribuicao(expressao) {
|
|
198
|
+
const valor = await this.avaliar(expressao.valor);
|
|
199
|
+
const valorFinal = this.resolverValor(valor);
|
|
200
|
+
const alvo = expressao.alvo;
|
|
201
|
+
this.pilhaEscoposExecucao.atribuirVariavel(alvo.simbolo, valorFinal);
|
|
202
|
+
return valorFinal;
|
|
257
203
|
}
|
|
258
204
|
visitarExpressaoDeVariavel(expressao) {
|
|
259
|
-
return this.
|
|
260
|
-
}
|
|
261
|
-
async visitarDeclaracaoDeExpressao(declaracao) {
|
|
262
|
-
return declaracao.expressao.aceitar(this);
|
|
205
|
+
return this.pilhaEscoposExecucao.obterValorVariavel(expressao.simbolo);
|
|
263
206
|
}
|
|
264
|
-
/**
|
|
265
|
-
* Execução da leitura de valores da entrada configurada no
|
|
266
|
-
* início da aplicação.
|
|
267
|
-
* @param expressao Expressão do tipo Leia
|
|
268
|
-
* @returns Promise com o resultado da leitura.
|
|
269
|
-
*/
|
|
270
207
|
async visitarExpressaoLeia(expressao) {
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
if (typeof objeto === 'boolean')
|
|
284
|
-
return Boolean(objeto);
|
|
285
|
-
if (objeto.hasOwnProperty('valor')) {
|
|
286
|
-
return Boolean(objeto.valor);
|
|
287
|
-
}
|
|
288
|
-
return true;
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Executa uma expressão Se, que tem uma condição, pode ter um bloco
|
|
292
|
-
* Senão, e múltiplos blocos Senão-se.
|
|
293
|
-
* @param declaracao A declaração Se.
|
|
294
|
-
* @returns O resultado da avaliação do bloco cuja condição é verdadeira.
|
|
295
|
-
*/
|
|
296
|
-
async visitarDeclaracaoSe(declaracao) {
|
|
297
|
-
if (this.eVerdadeiro(await this.avaliar(declaracao.condicao))) {
|
|
298
|
-
return await this.executar(declaracao.caminhoEntao);
|
|
299
|
-
}
|
|
300
|
-
if (declaracao.caminhoSenao !== null) {
|
|
301
|
-
return await this.executar(declaracao.caminhoSenao);
|
|
208
|
+
for (const arg of expressao.argumentos) {
|
|
209
|
+
const resposta = await new Promise((resolve) => this.interfaceEntradaSaida.question('> ', (r) => resolve(r)));
|
|
210
|
+
// arg é um Expressao (declaração) envolvendo um Variavel
|
|
211
|
+
const construto = arg instanceof declaracoes_1.Expressao
|
|
212
|
+
? arg.expressao
|
|
213
|
+
: arg;
|
|
214
|
+
if (construto instanceof construtos_1.Variavel) {
|
|
215
|
+
const valorConvertido = typeof resposta === 'string' && !Number.isNaN(Number(resposta))
|
|
216
|
+
? Number(resposta)
|
|
217
|
+
: resposta;
|
|
218
|
+
this.pilhaEscoposExecucao.atribuirVariavel(construto.simbolo, valorConvertido);
|
|
219
|
+
}
|
|
302
220
|
}
|
|
303
221
|
return null;
|
|
304
222
|
}
|
|
305
|
-
/* istanbul ignore next */
|
|
306
|
-
visitarDeclaracaoPara(declaracao) {
|
|
307
|
-
return Promise.reject('Método não implementado');
|
|
308
|
-
}
|
|
309
|
-
/* istanbul ignore next */
|
|
310
|
-
visitarExpressaoFimPara(declaracao) {
|
|
311
|
-
throw new Error('Método não implementado');
|
|
312
|
-
}
|
|
313
|
-
/* istanbul ignore next */
|
|
314
|
-
visitarDeclaracaoFazer(declaracao) {
|
|
315
|
-
throw new Error('Método não implementado');
|
|
316
|
-
}
|
|
317
223
|
async visitarExpressaoFormatacaoEscrita(declaracao) {
|
|
318
|
-
let resultado = '';
|
|
319
224
|
const conteudo = await this.avaliar(declaracao.expressao);
|
|
320
225
|
const valorConteudo = this.resolverValor(conteudo);
|
|
321
|
-
const tipoConteudo = conteudo.hasOwnProperty('tipo')
|
|
322
|
-
|
|
323
|
-
: typeof conteudo;
|
|
324
|
-
resultado = valorConteudo;
|
|
226
|
+
const tipoConteudo = conteudo.hasOwnProperty('tipo') ? conteudo.tipo : typeof conteudo;
|
|
227
|
+
let resultado = valorConteudo;
|
|
325
228
|
if (['número', 'number'].includes(tipoConteudo) && declaracao.casasDecimais > 0) {
|
|
326
229
|
resultado = valorConteudo.toLocaleString('pt', {
|
|
327
230
|
maximumFractionDigits: declaracao.casasDecimais,
|
|
328
231
|
});
|
|
329
232
|
}
|
|
330
|
-
if (declaracao.espacos > 0)
|
|
233
|
+
if (declaracao.espacos > 0)
|
|
331
234
|
resultado += ' '.repeat(declaracao.espacos);
|
|
332
|
-
}
|
|
333
235
|
return resultado;
|
|
334
236
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
237
|
+
// ── Acesso a vetores ────────────────────────────────────────────────────────
|
|
238
|
+
async visitarExpressaoAcessoIndiceVariavel(expressao) {
|
|
239
|
+
const objetoAvaliado = await this.avaliar(expressao.entidadeChamada);
|
|
240
|
+
const indiceAvaliado = await this.avaliar(expressao.indice);
|
|
241
|
+
const objeto = this.resolverValor(objetoAvaliado);
|
|
242
|
+
const indice = this.resolverValor(indiceAvaliado);
|
|
243
|
+
if (Array.isArray(objeto)) {
|
|
244
|
+
if (indice < 0 || indice >= objeto.length) {
|
|
245
|
+
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Índice do vetor fora do intervalo.', expressao.linha));
|
|
246
|
+
}
|
|
247
|
+
return objeto[indice];
|
|
248
|
+
}
|
|
249
|
+
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Acesso por índice só é suportado em vetores.', expressao.linha));
|
|
250
|
+
}
|
|
251
|
+
async visitarExpressaoAtribuicaoPorIndice(expressao) {
|
|
252
|
+
const objetoAvaliado = await this.avaliar(expressao.objeto);
|
|
253
|
+
const indiceAvaliado = await this.avaliar(expressao.indice);
|
|
254
|
+
const valorAvaliado = await this.avaliar(expressao.valor);
|
|
255
|
+
const objeto = this.resolverValor(objetoAvaliado);
|
|
256
|
+
const indice = this.resolverValor(indiceAvaliado);
|
|
257
|
+
const valor = this.resolverValor(valorAvaliado);
|
|
258
|
+
if (Array.isArray(objeto)) {
|
|
259
|
+
objeto[indice] = valor;
|
|
260
|
+
return valor;
|
|
261
|
+
}
|
|
262
|
+
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(null, 'Atribuição por índice só é suportada em vetores.', expressao.linha));
|
|
350
263
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
formatoTexto += `${this.paraTexto(valor)} `;
|
|
264
|
+
// ── Chamadas de funções embutidas ───────────────────────────────────────────
|
|
265
|
+
async visitarExpressaoDeChamada(expressao) {
|
|
266
|
+
const callee = expressao.entidadeChamada;
|
|
267
|
+
if (!(callee instanceof construtos_1.Variavel)) {
|
|
268
|
+
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(null, 'Chamada de função inválida.', expressao.linha));
|
|
357
269
|
}
|
|
358
|
-
|
|
270
|
+
const nome = callee.simbolo.lexema.toUpperCase();
|
|
271
|
+
const args = [];
|
|
272
|
+
for (const arg of expressao.argumentos) {
|
|
273
|
+
args.push(this.resolverValor(await this.avaliar(arg)));
|
|
274
|
+
}
|
|
275
|
+
return this.chamarFuncaoEmbutida(nome, args, expressao.linha);
|
|
276
|
+
}
|
|
277
|
+
chamarFuncaoEmbutida(nome, args, linha) {
|
|
278
|
+
switch (nome) {
|
|
279
|
+
// ── 0 argumentos ──
|
|
280
|
+
case 'ALEATORIO': return Math.random();
|
|
281
|
+
// ── 1 argumento ──
|
|
282
|
+
case 'SEN': return Math.sin(args[0]);
|
|
283
|
+
case 'COS': return Math.cos(args[0]);
|
|
284
|
+
case 'TAN': return Math.tan(args[0]);
|
|
285
|
+
case 'CTG': return 1 / Math.tan(args[0]);
|
|
286
|
+
case 'ASEN': return Math.asin(args[0]);
|
|
287
|
+
case 'ACOS': return Math.acos(args[0]);
|
|
288
|
+
case 'ATAN': return Math.atan(args[0]);
|
|
289
|
+
case 'ACTG': return 1 / Math.atan(args[0]);
|
|
290
|
+
case 'SENH': return Math.sinh(args[0]);
|
|
291
|
+
case 'COSH': return Math.cosh(args[0]);
|
|
292
|
+
case 'TANH': return Math.tanh(args[0]);
|
|
293
|
+
case 'CTGH': return 1 / Math.tanh(args[0]);
|
|
294
|
+
case 'EXP': return Math.exp(args[0]);
|
|
295
|
+
case 'ABS': return Math.abs(args[0]);
|
|
296
|
+
case 'RAIZ': return Math.sqrt(args[0]);
|
|
297
|
+
case 'LOG': return Math.log10(args[0]);
|
|
298
|
+
case 'LN': return Math.log(args[0]);
|
|
299
|
+
case 'INT': return Math.trunc(args[0]);
|
|
300
|
+
case 'FRAC': return args[0] - Math.trunc(args[0]);
|
|
301
|
+
case 'ARRED': return Math.round(args[0]);
|
|
302
|
+
// ── 2 argumentos ──
|
|
303
|
+
case 'POTENCIA': return Math.pow(args[0], args[1]);
|
|
304
|
+
// ── Texto ──
|
|
305
|
+
case 'COMPRIMENTO': return String(args[0]).length;
|
|
306
|
+
case 'LETRA': return String(args[0]).charAt(Number(args[1]));
|
|
307
|
+
default:
|
|
308
|
+
throw new excecoes_1.ErroEmTempoDeExecucao(null, `Função embutida desconhecida: '${nome}'.`, linha);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// ── Declarações ─────────────────────────────────────────────────────────────
|
|
312
|
+
async visitarDeclaracaoDeExpressao(declaracao) {
|
|
313
|
+
return declaracao.expressao.aceitar(this);
|
|
359
314
|
}
|
|
360
|
-
/**
|
|
361
|
-
* Execução de uma escrita na saída configurada, que pode ser `console` (padrão) ou
|
|
362
|
-
* alguma função para escrever numa página Web.
|
|
363
|
-
* @param declaracao A declaração.
|
|
364
|
-
* @returns Sempre nulo, por convenção de visita.
|
|
365
|
-
*/
|
|
366
315
|
async visitarDeclaracaoEscreva(declaracao) {
|
|
367
316
|
try {
|
|
368
317
|
const formatoTexto = await this.avaliarArgumentosEscreva(declaracao.argumentos);
|
|
@@ -370,11 +319,7 @@ class InterpretadorPortugolIpt {
|
|
|
370
319
|
return null;
|
|
371
320
|
}
|
|
372
321
|
catch (erro) {
|
|
373
|
-
this.erros.push({
|
|
374
|
-
erroInterno: erro,
|
|
375
|
-
linha: declaracao.linha,
|
|
376
|
-
hashArquivo: declaracao.hashArquivo,
|
|
377
|
-
});
|
|
322
|
+
this.erros.push({ erroInterno: erro, linha: declaracao.linha, hashArquivo: declaracao.hashArquivo });
|
|
378
323
|
}
|
|
379
324
|
}
|
|
380
325
|
async visitarDeclaracaoEscrevaMesmaLinha(declaracao) {
|
|
@@ -384,157 +329,314 @@ class InterpretadorPortugolIpt {
|
|
|
384
329
|
return null;
|
|
385
330
|
}
|
|
386
331
|
catch (erro) {
|
|
387
|
-
this.erros.push({
|
|
388
|
-
erroInterno: erro,
|
|
389
|
-
linha: declaracao.linha,
|
|
390
|
-
hashArquivo: declaracao.hashArquivo,
|
|
391
|
-
});
|
|
332
|
+
this.erros.push({ erroInterno: erro, linha: declaracao.linha, hashArquivo: declaracao.hashArquivo });
|
|
392
333
|
}
|
|
393
334
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
335
|
+
async avaliarArgumentosEscreva(argumentos) {
|
|
336
|
+
let formatoTexto = '';
|
|
337
|
+
for (const argumento of argumentos) {
|
|
338
|
+
const resultado = await this.avaliar(argumento);
|
|
339
|
+
formatoTexto += `${this.paraTexto(this.resolverValor(resultado))} `;
|
|
340
|
+
}
|
|
341
|
+
return formatoTexto.trimEnd();
|
|
401
342
|
}
|
|
402
|
-
async
|
|
403
|
-
let
|
|
343
|
+
async visitarDeclaracaoVar(declaracao) {
|
|
344
|
+
let valorFinal = null;
|
|
404
345
|
if (declaracao.inicializador !== null) {
|
|
405
|
-
|
|
346
|
+
const avaliado = await this.avaliar(declaracao.inicializador);
|
|
347
|
+
if (avaliado !== null && avaliado !== undefined) {
|
|
348
|
+
valorFinal = this.resolverValor(avaliado);
|
|
349
|
+
}
|
|
406
350
|
}
|
|
351
|
+
this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, valorFinal, declaracao.tipo);
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
async visitarDeclaracaoConst(declaracao) {
|
|
407
355
|
let valorFinal = null;
|
|
408
|
-
if (
|
|
409
|
-
|
|
356
|
+
if (declaracao.inicializador !== null) {
|
|
357
|
+
const avaliado = await this.avaliar(declaracao.inicializador);
|
|
358
|
+
if (avaliado !== null && avaliado !== undefined) {
|
|
359
|
+
valorFinal = this.resolverValor(avaliado);
|
|
360
|
+
}
|
|
410
361
|
}
|
|
411
|
-
|
|
362
|
+
this.pilhaEscoposExecucao.definirConstante(declaracao.simbolo.lexema, valorFinal, declaracao.tipo);
|
|
363
|
+
return null;
|
|
412
364
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
365
|
+
async visitarDeclaracaoSe(declaracao) {
|
|
366
|
+
if (this.eVerdadeiro(await this.avaliar(declaracao.condicao))) {
|
|
367
|
+
return await this.executar(declaracao.caminhoEntao);
|
|
368
|
+
}
|
|
369
|
+
if (declaracao.caminhoSenao !== null) {
|
|
370
|
+
return await this.executar(declaracao.caminhoSenao);
|
|
371
|
+
}
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
async visitarDeclaracaoEnquanto(declaracao) {
|
|
375
|
+
while (this.eVerdadeiro(await this.avaliar(declaracao.condicao))) {
|
|
376
|
+
try {
|
|
377
|
+
const resultado = await this.executar(declaracao.corpo);
|
|
378
|
+
if (resultado instanceof quebras_1.SustarQuebra)
|
|
379
|
+
return null;
|
|
380
|
+
if (resultado instanceof quebras_1.ContinuarQuebra)
|
|
381
|
+
continue;
|
|
382
|
+
if (resultado instanceof quebras_1.Quebra)
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
catch (erro) {
|
|
386
|
+
this.erros.push({ erroInterno: erro, linha: declaracao.linha, hashArquivo: declaracao.hashArquivo });
|
|
387
|
+
return Promise.reject(erro);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
421
390
|
return null;
|
|
422
391
|
}
|
|
392
|
+
async visitarDeclaracaoPara(declaracao) {
|
|
393
|
+
const inicializador = Array.isArray(declaracao.inicializador)
|
|
394
|
+
? declaracao.inicializador[0]
|
|
395
|
+
: declaracao.inicializador;
|
|
396
|
+
if (inicializador)
|
|
397
|
+
await this.avaliar(inicializador);
|
|
398
|
+
while (true) {
|
|
399
|
+
if (declaracao.condicao && !this.eVerdadeiro(await this.avaliar(declaracao.condicao)))
|
|
400
|
+
break;
|
|
401
|
+
try {
|
|
402
|
+
const resultado = await this.executar(declaracao.corpo);
|
|
403
|
+
if (resultado instanceof quebras_1.SustarQuebra)
|
|
404
|
+
return null;
|
|
405
|
+
if (resultado instanceof quebras_1.ContinuarQuebra) { /* continua para incremento */ }
|
|
406
|
+
else if (resultado instanceof quebras_1.Quebra)
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
catch (erro) {
|
|
410
|
+
this.erros.push({ erroInterno: erro, linha: declaracao.linha, hashArquivo: declaracao.hashArquivo });
|
|
411
|
+
return Promise.reject(erro);
|
|
412
|
+
}
|
|
413
|
+
if (declaracao.incrementar)
|
|
414
|
+
await this.avaliar(declaracao.incrementar);
|
|
415
|
+
}
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
async visitarDeclaracaoFazer(declaracao) {
|
|
419
|
+
do {
|
|
420
|
+
try {
|
|
421
|
+
const resultado = await this.executar(declaracao.caminhoFazer);
|
|
422
|
+
if (resultado instanceof quebras_1.SustarQuebra)
|
|
423
|
+
return null;
|
|
424
|
+
if (resultado instanceof quebras_1.ContinuarQuebra)
|
|
425
|
+
continue;
|
|
426
|
+
if (resultado instanceof quebras_1.Quebra)
|
|
427
|
+
break;
|
|
428
|
+
}
|
|
429
|
+
catch (erro) {
|
|
430
|
+
this.erros.push({ erroInterno: erro, linha: declaracao.linha, hashArquivo: declaracao.hashArquivo });
|
|
431
|
+
return Promise.reject(erro);
|
|
432
|
+
}
|
|
433
|
+
} while (this.eVerdadeiro(await this.avaliar(declaracao.condicaoEnquanto)));
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
async visitarDeclaracaoEscolha(declaracao) {
|
|
437
|
+
const valorCondicao = this.resolverValor(await this.avaliar(declaracao.identificadorOuLiteral));
|
|
438
|
+
let encontrado = false;
|
|
439
|
+
for (const caminho of declaracao.caminhos) {
|
|
440
|
+
for (const condicao of caminho.condicoes) {
|
|
441
|
+
const valorCondicaoAvaliado = this.resolverValor(await this.avaliar(condicao));
|
|
442
|
+
if (valorCondicaoAvaliado === valorCondicao) {
|
|
443
|
+
encontrado = true;
|
|
444
|
+
await this.executarBloco(caminho.declaracoes);
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (encontrado)
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
if (!encontrado && declaracao.caminhoPadrao) {
|
|
452
|
+
await this.executarBloco(declaracao.caminhoPadrao.declaracoes);
|
|
453
|
+
}
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
visitarDeclaracaoComentario(declaracao) {
|
|
457
|
+
return Promise.resolve();
|
|
458
|
+
}
|
|
459
|
+
// ── Bloco e escopo ───────────────────────────────────────────────────────────
|
|
460
|
+
async executarBloco(declaracoes, ambiente) {
|
|
461
|
+
const escopoExecucao = {
|
|
462
|
+
declaracoes: declaracoes,
|
|
463
|
+
declaracaoAtual: 0,
|
|
464
|
+
espacoMemoria: ambiente || new espaco_memoria_1.EspacoMemoria(),
|
|
465
|
+
finalizado: false,
|
|
466
|
+
tipo: 'outro',
|
|
467
|
+
emLacoRepeticao: false,
|
|
468
|
+
};
|
|
469
|
+
this.pilhaEscoposExecucao.empilhar(escopoExecucao);
|
|
470
|
+
return await this.executarUltimoEscopo();
|
|
471
|
+
}
|
|
472
|
+
async visitarExpressaoBloco(declaracao) {
|
|
473
|
+
return await this.executarBloco(declaracao.declaracoes);
|
|
474
|
+
}
|
|
475
|
+
// ── Métodos obrigatórios da interface não usados em Portugol IPT ────────────
|
|
423
476
|
/* istanbul ignore next */
|
|
424
|
-
|
|
425
|
-
throw new Error('Método não implementado');
|
|
477
|
+
visitarExpressaoTuplaN(_expressao) {
|
|
478
|
+
throw new Error('Método não implementado.');
|
|
426
479
|
}
|
|
427
480
|
/* istanbul ignore next */
|
|
428
|
-
|
|
429
|
-
throw new Error('Método não implementado');
|
|
481
|
+
visitarExpressaoAcessoIntervaloVariavel(_expressao) {
|
|
482
|
+
throw new Error('Método não implementado.');
|
|
430
483
|
}
|
|
431
484
|
/* istanbul ignore next */
|
|
432
|
-
|
|
433
|
-
throw new Error('Método não implementado');
|
|
485
|
+
visitarDeclaracaoTextoDocumentacao(_declaracao) {
|
|
486
|
+
throw new Error('Método não implementado.');
|
|
434
487
|
}
|
|
435
488
|
/* istanbul ignore next */
|
|
436
|
-
|
|
437
|
-
throw new Error('Método não implementado');
|
|
489
|
+
visitarExpressaoSeparador(_expressao) {
|
|
490
|
+
throw new Error('Método não implementado.');
|
|
438
491
|
}
|
|
439
492
|
/* istanbul ignore next */
|
|
440
|
-
|
|
441
|
-
throw new Error('Método não implementado');
|
|
493
|
+
visitarExpressaoComentario(_expressao) {
|
|
494
|
+
throw new Error('Método não implementado.');
|
|
442
495
|
}
|
|
443
496
|
/* istanbul ignore next */
|
|
444
|
-
|
|
445
|
-
throw new Error('Método não implementado');
|
|
497
|
+
visitarExpressaoArgumentoReferenciaFuncao(_expressao) {
|
|
498
|
+
throw new Error('Método não implementado.');
|
|
446
499
|
}
|
|
447
500
|
/* istanbul ignore next */
|
|
448
|
-
|
|
449
|
-
throw new Error('Método não implementado');
|
|
501
|
+
visitarExpressaoReferenciaFuncao(_expressao) {
|
|
502
|
+
throw new Error('Método não implementado.');
|
|
450
503
|
}
|
|
451
504
|
/* istanbul ignore next */
|
|
452
|
-
|
|
453
|
-
throw new Error('Método não implementado');
|
|
505
|
+
visitarExpressaoAcessoMetodo(_expressao) {
|
|
506
|
+
throw new Error('Método não implementado.');
|
|
454
507
|
}
|
|
455
508
|
/* istanbul ignore next */
|
|
456
|
-
|
|
457
|
-
throw new Error('Método não implementado');
|
|
509
|
+
visitarExpressaoAcessoPropriedade(_expressao) {
|
|
510
|
+
throw new Error('Método não implementado.');
|
|
458
511
|
}
|
|
459
512
|
/* istanbul ignore next */
|
|
460
|
-
|
|
461
|
-
throw new Error('Método não implementado');
|
|
513
|
+
visitarDeclaracaoTendoComo(_declaracao) {
|
|
514
|
+
throw new Error('Método não implementado.');
|
|
462
515
|
}
|
|
463
516
|
/* istanbul ignore next */
|
|
464
|
-
|
|
465
|
-
throw new Error('Método não implementado');
|
|
517
|
+
visitarDeclaracaoInicioAlgoritmo(_declaracao) {
|
|
518
|
+
throw new Error('Método não implementado.');
|
|
466
519
|
}
|
|
467
520
|
/* istanbul ignore next */
|
|
468
|
-
|
|
469
|
-
throw new Error('Método não implementado');
|
|
521
|
+
visitarDeclaracaoCabecalhoPrograma(_declaracao) {
|
|
522
|
+
throw new Error('Método não implementado.');
|
|
470
523
|
}
|
|
471
524
|
/* istanbul ignore next */
|
|
472
|
-
|
|
473
|
-
throw new Error('Método não implementado');
|
|
525
|
+
visitarExpressaoTupla(_expressao) {
|
|
526
|
+
throw new Error('Método não implementado.');
|
|
474
527
|
}
|
|
475
528
|
/* istanbul ignore next */
|
|
476
|
-
|
|
477
|
-
throw new Error('Método não implementado');
|
|
529
|
+
visitarExpressaoAcessoElementoMatriz(_expressao) {
|
|
530
|
+
throw new Error('Método não implementado.');
|
|
478
531
|
}
|
|
479
532
|
/* istanbul ignore next */
|
|
480
|
-
|
|
481
|
-
throw new Error('Método não implementado');
|
|
533
|
+
visitarExpressaoAtribuicaoPorIndicesMatriz(_expressao) {
|
|
534
|
+
throw new Error('Método não implementado.');
|
|
482
535
|
}
|
|
483
536
|
/* istanbul ignore next */
|
|
484
|
-
|
|
485
|
-
throw new Error('Método não implementado');
|
|
537
|
+
visitarExpressaoExpressaoRegular(_expressao) {
|
|
538
|
+
throw new Error('Método não implementado.');
|
|
486
539
|
}
|
|
487
540
|
/* istanbul ignore next */
|
|
488
|
-
|
|
489
|
-
throw new Error('Método não implementado');
|
|
541
|
+
visitarExpressaoTipoDe(_expressao) {
|
|
542
|
+
throw new Error('Método não implementado.');
|
|
490
543
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
544
|
+
/* istanbul ignore next */
|
|
545
|
+
visitarExpressaoFalhar(_expressao) {
|
|
546
|
+
throw new Error('Método não implementado.');
|
|
547
|
+
}
|
|
548
|
+
/* istanbul ignore next */
|
|
549
|
+
visitarDeclaracaoParaCada(_declaracao) {
|
|
550
|
+
throw new Error('Método não implementado.');
|
|
551
|
+
}
|
|
552
|
+
/* istanbul ignore next */
|
|
553
|
+
visitarDeclaracaoVarMultiplo(_declaracao) {
|
|
554
|
+
throw new Error('Método não implementado.');
|
|
555
|
+
}
|
|
556
|
+
/* istanbul ignore next */
|
|
557
|
+
visitarDeclaracaoConstMultiplo(_declaracao) {
|
|
558
|
+
throw new Error('Método não implementado.');
|
|
559
|
+
}
|
|
560
|
+
/* istanbul ignore next */
|
|
561
|
+
visitarExpressaoContinua(_declaracao) {
|
|
562
|
+
throw new Error('Método não implementado.');
|
|
563
|
+
}
|
|
564
|
+
/* istanbul ignore next */
|
|
565
|
+
visitarExpressaoSustar(_declaracao) {
|
|
566
|
+
throw new Error('Método não implementado.');
|
|
567
|
+
}
|
|
568
|
+
/* istanbul ignore next */
|
|
569
|
+
visitarExpressaoRetornar(_declaracao) {
|
|
570
|
+
throw new Error('Método não implementado.');
|
|
571
|
+
}
|
|
572
|
+
/* istanbul ignore next */
|
|
573
|
+
visitarExpressaoFuncaoConstruto(_expressao) {
|
|
574
|
+
throw new Error('Método não implementado.');
|
|
575
|
+
}
|
|
576
|
+
/* istanbul ignore next */
|
|
577
|
+
visitarExpressaoDefinirValor(_expressao) {
|
|
578
|
+
throw new Error('Método não implementado.');
|
|
579
|
+
}
|
|
580
|
+
/* istanbul ignore next */
|
|
581
|
+
visitarDeclaracaoDefinicaoFuncao(_declaracao) {
|
|
582
|
+
throw new Error('Método não implementado.');
|
|
583
|
+
}
|
|
584
|
+
/* istanbul ignore next */
|
|
585
|
+
visitarDeclaracaoClasse(_declaracao) {
|
|
586
|
+
throw new Error('Método não implementado.');
|
|
587
|
+
}
|
|
588
|
+
/* istanbul ignore next */
|
|
589
|
+
visitarExpressaoAcessoMetodoOuPropriedade(_expressao) {
|
|
590
|
+
throw new Error('Método não implementado.');
|
|
591
|
+
}
|
|
592
|
+
/* istanbul ignore next */
|
|
593
|
+
visitarExpressaoIsto(_expressao) {
|
|
594
|
+
throw new Error('Método não implementado.');
|
|
595
|
+
}
|
|
596
|
+
/* istanbul ignore next */
|
|
597
|
+
visitarExpressaoDicionario(_expressao) {
|
|
598
|
+
throw new Error('Método não implementado.');
|
|
599
|
+
}
|
|
600
|
+
async visitarExpressaoVetor(expressao) {
|
|
601
|
+
const valores = [];
|
|
602
|
+
for (const elemento of expressao.valores) {
|
|
603
|
+
const avaliado = await this.avaliar(elemento);
|
|
604
|
+
valores.push(this.resolverValor(avaliado));
|
|
503
605
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
606
|
+
return valores;
|
|
607
|
+
}
|
|
608
|
+
/* istanbul ignore next */
|
|
609
|
+
visitarExpressaoSuper(_expressao) {
|
|
610
|
+
throw new Error('Método não implementado.');
|
|
611
|
+
}
|
|
612
|
+
/* istanbul ignore next */
|
|
613
|
+
visitarExpressaoFimPara(_declaracao) {
|
|
614
|
+
throw new Error('Método não implementado.');
|
|
615
|
+
}
|
|
616
|
+
/* istanbul ignore next */
|
|
617
|
+
visitarDeclaracaoTente(_declaracao) {
|
|
618
|
+
throw new Error('Método não implementado.');
|
|
619
|
+
}
|
|
620
|
+
/* istanbul ignore next */
|
|
621
|
+
visitarDeclaracaoImportar(_declaracao) {
|
|
622
|
+
throw new Error('Método não implementado.');
|
|
623
|
+
}
|
|
624
|
+
// ── Motor de execução ────────────────────────────────────────────────────────
|
|
625
|
+
async avaliar(expressao) {
|
|
626
|
+
return await expressao.aceitar(this);
|
|
627
|
+
}
|
|
628
|
+
procurarVariavel(simbolo) {
|
|
629
|
+
return this.pilhaEscoposExecucao.obterValorVariavel(simbolo);
|
|
511
630
|
}
|
|
512
|
-
/**
|
|
513
|
-
* Efetivamente executa uma declaração.
|
|
514
|
-
* @param declaracao A declaração a ser executada.
|
|
515
|
-
* @param mostrarResultado Se resultado deve ser mostrado ou não. Normalmente usado
|
|
516
|
-
* pelo modo LAIR.
|
|
517
|
-
*/
|
|
518
631
|
async executar(declaracao, mostrarResultado = false) {
|
|
519
632
|
const resultado = await declaracao.aceitar(this);
|
|
520
|
-
if (mostrarResultado)
|
|
633
|
+
if (mostrarResultado)
|
|
521
634
|
this.funcaoDeRetorno(this.paraTexto(resultado));
|
|
522
|
-
}
|
|
523
635
|
if (resultado || typeof resultado === 'boolean') {
|
|
524
636
|
this.resultadoInterpretador.push(this.paraTexto(resultado));
|
|
525
637
|
}
|
|
526
638
|
return resultado;
|
|
527
639
|
}
|
|
528
|
-
/**
|
|
529
|
-
* Executa o último escopo empilhado no topo na pilha de escopos do interpretador.
|
|
530
|
-
* Esse método pega exceções, mas apenas as devolve.
|
|
531
|
-
*
|
|
532
|
-
* O tratamento das exceções é feito de acordo com o bloco chamador.
|
|
533
|
-
* Por exemplo, em `tente ... pegue ... finalmente`, a exceção é capturada e tratada.
|
|
534
|
-
* Em outros blocos, pode ser desejável ter o erro em tela.
|
|
535
|
-
* @param manterAmbiente Se verdadeiro, ambiente do topo da pilha de escopo é copiado para o ambiente imediatamente abaixo.
|
|
536
|
-
* @returns O resultado da execução do escopo, se houver.
|
|
537
|
-
*/
|
|
538
640
|
async executarUltimoEscopo(manterAmbiente = false) {
|
|
539
641
|
const ultimoEscopo = this.pilhaEscoposExecucao.topoDaPilha();
|
|
540
642
|
try {
|
|
@@ -560,10 +662,7 @@ class InterpretadorPortugolIpt {
|
|
|
560
662
|
if (chamavel instanceof estruturas_1.FuncaoPadrao) {
|
|
561
663
|
return chamavel.chamar(this, argumentos, null);
|
|
562
664
|
}
|
|
563
|
-
const argumentosFormatados = argumentos.map((valor) => ({
|
|
564
|
-
nome: null,
|
|
565
|
-
valor,
|
|
566
|
-
}));
|
|
665
|
+
const argumentosFormatados = argumentos.map((valor) => ({ nome: null, valor }));
|
|
567
666
|
return chamavel.chamar(this, argumentosFormatados, null);
|
|
568
667
|
}
|
|
569
668
|
async interpretar(declaracoes, manterAmbiente) {
|