diff --git a/fontes/interpretador/dialetos/visualg/comum.ts b/fontes/interpretador/dialetos/visualg/comum.ts index e9ed965b..acb3f7db 100644 --- a/fontes/interpretador/dialetos/visualg/comum.ts +++ b/fontes/interpretador/dialetos/visualg/comum.ts @@ -1,5 +1,7 @@ import { + AcessoElementoMatriz, AcessoIndiceVariavel, + AtribuicaoPorIndicesMatriz, Binario, Construto, FimPara, @@ -287,3 +289,105 @@ export async function resolverIncrementoPara(interpretador: InterpretadorBase, d } } } + +export async function visitarExpressaoAcessoElementoMatriz(expressao: AcessoElementoMatriz): Promise { + const promises = await Promise.all([ + this.avaliar(expressao.entidadeChamada), + this.avaliar(expressao.indicePrimario), + this.avaliar(expressao.indiceSecundario), + ]); + + const variavelObjeto: VariavelInterface = promises[0]; + const indicePrimario = promises[1]; + const indiceSecundario = promises[2]; + + const objeto = variavelObjeto.hasOwnProperty('valor') ? variavelObjeto.valor : variavelObjeto; + let valorIndicePrimario = indicePrimario.hasOwnProperty('valor') ? indicePrimario.valor : indicePrimario; + let valorIndiceSecundario = indiceSecundario.hasOwnProperty('valor') ? indiceSecundario.valor : indiceSecundario; + + if (Array.isArray(objeto)) { + if (!Number.isInteger(valorIndicePrimario) || !Number.isInteger(valorIndiceSecundario)) { + return Promise.reject( + new ErroEmTempoDeExecucao( + expressao.simboloFechamento, + 'Somente inteiros podem ser usados para indexar um vetor.', + expressao.linha + ) + ); + } + + if (valorIndicePrimario < 0 && objeto.length !== 0) { + while (valorIndicePrimario < 0) { + valorIndicePrimario += objeto.length; + } + } + if (valorIndiceSecundario < 0 && objeto.length !== 0) { + while (valorIndiceSecundario < 0) { + valorIndiceSecundario += objeto.length; + } + } + + if (valorIndicePrimario >= objeto.length || valorIndiceSecundario >= objeto.length) { + return Promise.reject( + new ErroEmTempoDeExecucao( + expressao.simboloFechamento, + 'Índice do vetor fora do intervalo.', + expressao.linha + ) + ); + } + return objeto[valorIndicePrimario][valorIndiceSecundario]; + } + return Promise.reject( + new ErroEmTempoDeExecucao( + expressao.entidadeChamada.valor, + 'Somente listas, dicionários, classes e objetos podem ser mudados por sobrescrita.', + expressao.linha + ) + ); +} + +export async function visitarExpressaoAtribuicaoPorIndicesMatriz(expressao: AtribuicaoPorIndicesMatriz): Promise { + const promises = await Promise.all([ + this.avaliar(expressao.objeto), + this.avaliar(expressao.indicePrimario), + this.avaliar(expressao.indiceSecundario), + this.avaliar(expressao.valor), + ]); + + let objeto = promises[0]; + let indicePrimario = promises[1]; + let indiceSecundario = promises[2]; + const valor = promises[3]; + + objeto = objeto.hasOwnProperty('valor') ? objeto.valor : objeto; + indicePrimario = indicePrimario.hasOwnProperty('valor') ? indicePrimario.valor : indicePrimario; + indiceSecundario = indiceSecundario.hasOwnProperty('valor') ? indiceSecundario.valor : indiceSecundario; + + if (Array.isArray(objeto)) { + if (indicePrimario < 0 && objeto.length !== 0) { + while (indicePrimario < 0) { + indicePrimario += objeto.length; + } + } + if (indiceSecundario < 0 && objeto.length !== 0) { + while (indiceSecundario < 0) { + indiceSecundario += objeto.length; + } + } + + while (objeto.length < indicePrimario || objeto.length < indiceSecundario) { + objeto.push(null); + } + + objeto[indicePrimario][indiceSecundario] = valor; + return Promise.resolve(); + } + return Promise.reject( + new ErroEmTempoDeExecucao( + expressao.objeto.nome, + 'Somente listas, dicionários, classes e objetos podem ser mudados por sobrescrita.', + expressao.linha + ) + ); +} diff --git a/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.ts b/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.ts index 7fd07983..c5922ede 100644 --- a/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.ts +++ b/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.ts @@ -4,11 +4,10 @@ import { registrarBibliotecaNumericaVisuAlg, registrarBibliotecaCaracteresVisuAlg, } from '../../../bibliotecas/dialetos/visualg'; -import { Binario, Construto, FimPara, Logico } from '../../../construtos'; +import { AcessoElementoMatriz, AtribuicaoPorIndicesMatriz, Binario, Construto, FimPara, Logico } from '../../../construtos'; import { EscrevaMesmaLinha, Escreva, Fazer, Leia, Const, Para, Bloco } from '../../../declaracoes'; import { ContinuarQuebra, Quebra, SustarQuebra } from '../../../quebras'; import { InterpretadorComDepuracao } from '../../interpretador-com-depuracao'; - import * as comum from './comum'; /** @@ -29,6 +28,14 @@ export class InterpretadorVisuAlgComDepuracao extends InterpretadorComDepuracao throw new Error('Método não implementado.'); } + async visitarExpressaoAcessoElementoMatriz(expressao: AcessoElementoMatriz): Promise { + await comum.visitarExpressaoAcessoElementoMatriz(expressao); + } + + async visitarExpressaoAtribuicaoPorIndicesMatriz(expressao: AtribuicaoPorIndicesMatriz): Promise { + await comum.visitarExpressaoAtribuicaoPorIndicesMatriz(expressao); + } + private async avaliarArgumentosEscrevaVisuAlg(argumentos: Construto[]): Promise { let formatoTexto: string = ''; diff --git a/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts b/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts index db020a57..da9a6155 100644 --- a/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts +++ b/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts @@ -4,8 +4,6 @@ import { InterpretadorBase } from '../..'; import { ContinuarQuebra, Quebra, SustarQuebra } from '../../../quebras'; import { registrarBibliotecaNumericaVisuAlg } from '../../../bibliotecas/dialetos/visualg/numerica'; import { registrarBibliotecaCaracteresVisuAlg } from '../../../bibliotecas/dialetos/visualg'; -import { ErroEmTempoDeExecucao } from '../../../excecoes'; -import { VariavelInterface } from '../../../interfaces'; import * as comum from './comum'; /** @@ -35,105 +33,11 @@ export class InterpretadorVisuAlg extends InterpretadorBase { } async visitarExpressaoAcessoElementoMatriz(expressao: AcessoElementoMatriz): Promise { - const promises = await Promise.all([ - this.avaliar(expressao.entidadeChamada), - this.avaliar(expressao.indicePrimario), - this.avaliar(expressao.indiceSecundario), - ]); - - const variavelObjeto: VariavelInterface = promises[0]; - const indicePrimario = promises[1]; - const indiceSecundario = promises[2]; - - const objeto = variavelObjeto.hasOwnProperty('valor') ? variavelObjeto.valor : variavelObjeto; - let valorIndicePrimario = indicePrimario.hasOwnProperty('valor') ? indicePrimario.valor : indicePrimario; - let valorIndiceSecundario = indiceSecundario.hasOwnProperty('valor') ? indiceSecundario.valor : indiceSecundario; - - if (Array.isArray(objeto)) { - if (!Number.isInteger(valorIndicePrimario) || !Number.isInteger(valorIndiceSecundario)) { - return Promise.reject( - new ErroEmTempoDeExecucao( - expressao.simboloFechamento, - 'Somente inteiros podem ser usados para indexar um vetor.', - expressao.linha - ) - ); - } - - if (valorIndicePrimario < 0 && objeto.length !== 0) { - while (valorIndicePrimario < 0) { - valorIndicePrimario += objeto.length; - } - } - if (valorIndiceSecundario < 0 && objeto.length !== 0) { - while (valorIndiceSecundario < 0) { - valorIndiceSecundario += objeto.length; - } - } - - if (valorIndicePrimario >= objeto.length || valorIndiceSecundario >= objeto.length) { - return Promise.reject( - new ErroEmTempoDeExecucao( - expressao.simboloFechamento, - 'Índice do vetor fora do intervalo.', - expressao.linha - ) - ); - } - return objeto[valorIndicePrimario][valorIndiceSecundario]; - } - return Promise.reject( - new ErroEmTempoDeExecucao( - expressao.entidadeChamada.valor, - 'Somente listas, dicionários, classes e objetos podem ser mudados por sobrescrita.', - expressao.linha - ) - ); + await comum.visitarExpressaoAcessoElementoMatriz(expressao); } async visitarExpressaoAtribuicaoPorIndicesMatriz(expressao: AtribuicaoPorIndicesMatriz): Promise { - const promises = await Promise.all([ - this.avaliar(expressao.objeto), - this.avaliar(expressao.indicePrimario), - this.avaliar(expressao.indiceSecundario), - this.avaliar(expressao.valor), - ]); - - let objeto = promises[0]; - let indicePrimario = promises[1]; - let indiceSecundario = promises[2]; - const valor = promises[3]; - - objeto = objeto.hasOwnProperty('valor') ? objeto.valor : objeto; - indicePrimario = indicePrimario.hasOwnProperty('valor') ? indicePrimario.valor : indicePrimario; - indiceSecundario = indiceSecundario.hasOwnProperty('valor') ? indiceSecundario.valor : indiceSecundario; - - if (Array.isArray(objeto)) { - if (indicePrimario < 0 && objeto.length !== 0) { - while (indicePrimario < 0) { - indicePrimario += objeto.length; - } - } - if (indiceSecundario < 0 && objeto.length !== 0) { - while (indiceSecundario < 0) { - indiceSecundario += objeto.length; - } - } - - while (objeto.length < indicePrimario || objeto.length < indiceSecundario) { - objeto.push(null); - } - - objeto[indicePrimario][indiceSecundario] = valor; - return Promise.resolve(); - } - return Promise.reject( - new ErroEmTempoDeExecucao( - expressao.objeto.nome, - 'Somente listas, dicionários, classes e objetos podem ser mudados por sobrescrita.', - expressao.linha - ) - ); + await comum.visitarExpressaoAtribuicaoPorIndicesMatriz(expressao); } private async avaliarArgumentosEscrevaVisuAlg(argumentos: Construto[]): Promise {