@designliquido/delegua
Version:
Linguagem de programação simples e moderna usando português estruturado.
245 lines (240 loc) • 11.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MicroAvaliadorSintaticoPitugues = void 0;
const construtos_1 = require("../../construtos");
const declaracoes_1 = require("../../declaracoes");
const micro_avaliador_sintatico_base_1 = require("../micro-avaliador-sintatico-base");
const inferenciador_1 = require("../../inferenciador");
const pitugues_1 = __importDefault(require("../../tipos-de-simbolos/pitugues"));
/**
* O MicroAvaliadorSintatico funciona apenas dentro de interpolações de texto.
*/
class MicroAvaliadorSintaticoPitugues extends micro_avaliador_sintatico_base_1.MicroAvaliadorSintaticoBase {
primario() {
const simboloAtual = this.simbolos[this.atual];
switch (simboloAtual.tipo) {
// TODO: Verificar se vamos usar isso.
/* case tiposDeSimbolos.CHAVE_ESQUERDA:
this.avancarEDevolverAnterior();
const chaves = [];
valores = [];
if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.CHAVE_DIREITA)) {
return new Dicionario(-1, Number(this.linha), [], []);
}
while (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.CHAVE_DIREITA)) {
const chave = this.atribuir();
this.consumir(tiposDeSimbolos.DOIS_PONTOS, "Esperado ':' entre chave e valor.");
const valor = this.atribuir();
chaves.push(chave);
valores.push(valor);
if (this.simbolos[this.atual].tipo !== tiposDeSimbolos.CHAVE_DIREITA) {
this.consumir(tiposDeSimbolos.VIRGULA, 'Esperado vírgula antes da próxima expressão.');
}
}
return new Dicionario(-1, Number(this.linha), chaves, valores); */
// TODO: Verificar se vamos usar isso.
case pitugues_1.default.COLCHETE_ESQUERDO:
this.avancarEDevolverAnterior();
const valores = [];
if (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.COLCHETE_DIREITO)) {
return new construtos_1.Vetor(-1, Number(this.linha), []);
}
while (!this.verificarSeSimboloAtualEIgualA(pitugues_1.default.COLCHETE_DIREITO)) {
const valor = this.declaracao();
valores.push(valor);
if (this.simbolos[this.atual].tipo !== pitugues_1.default.COLCHETE_DIREITO) {
this.consumir(pitugues_1.default.VIRGULA, 'Esperado vírgula antes da próxima expressão.');
}
}
const tipoVetor = (0, inferenciador_1.inferirTipoVariavel)(valores);
return new construtos_1.Vetor(-1, Number(this.linha), valores, tipoVetor);
case pitugues_1.default.FALSO:
this.avancarEDevolverAnterior();
return new construtos_1.Literal(-1, Number(this.linha), false);
case pitugues_1.default.NULO:
this.avancarEDevolverAnterior();
return new construtos_1.Literal(-1, Number(this.linha), null);
case pitugues_1.default.NUMERO:
case pitugues_1.default.TEXTO:
const simboloNumeroTexto = this.avancarEDevolverAnterior();
const tipoInferido = (0, inferenciador_1.inferirTipoVariavel)(simboloNumeroTexto.literal);
return new construtos_1.Literal(-1, Number(this.linha), simboloNumeroTexto.literal, tipoInferido);
case pitugues_1.default.IDENTIFICADOR:
const simboloIdentificador = this.avancarEDevolverAnterior();
return new construtos_1.Variavel(-1, simboloIdentificador);
case pitugues_1.default.PARENTESE_ESQUERDO:
this.avancarEDevolverAnterior();
const expressao = this.ou();
this.consumir(pitugues_1.default.PARENTESE_DIREITO, "Esperado ')' após a expressão.");
return new construtos_1.Agrupamento(-1, Number(this.linha), expressao);
case pitugues_1.default.VERDADEIRO:
this.avancarEDevolverAnterior();
return new construtos_1.Literal(-1, Number(this.linha), true);
}
throw this.erro(this.simbolos[this.atual], 'Esperado expressão.');
}
finalizarChamada(entidadeChamada) {
const argumentos = [];
if (!this.verificarTipoSimboloAtual(pitugues_1.default.PARENTESE_DIREITO)) {
do {
if (argumentos.length >= 255) {
throw this.erro(this.simbolos[this.atual], 'Não pode haver mais de 255 argumentos.');
}
argumentos.push(this.ou());
} while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.VIRGULA));
}
this.consumir(pitugues_1.default.PARENTESE_DIREITO, "Esperado ')' após os argumentos.");
return new construtos_1.Chamada(-1, entidadeChamada, argumentos);
}
chamar() {
let expressao = this.primario();
while (true) {
if (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.PARENTESE_ESQUERDO)) {
expressao = this.finalizarChamada(expressao);
}
else if (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.PONTO)) {
const nome = this.consumir(pitugues_1.default.IDENTIFICADOR, "Esperado nome do método após '.'.");
expressao = new construtos_1.AcessoMetodoOuPropriedade(-1, expressao, nome);
}
else if (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.COLCHETE_ESQUERDO)) {
const indice = this.ou();
const simboloFechamento = this.consumir(pitugues_1.default.COLCHETE_DIREITO, "Esperado ']' após escrita do indice.");
expressao = new construtos_1.AcessoIndiceVariavel(-1, expressao, indice, simboloFechamento);
}
else {
break;
}
}
return expressao;
}
multiplicar() {
let expressao = this.exponenciacao();
while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.MULTIPLICACAO, pitugues_1.default.DIVISAO, pitugues_1.default.MODULO, pitugues_1.default.DIVISAO_INTEIRA)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.exponenciacao();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
unario() {
if (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.INTERROGACAO)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.unario();
this.erro(operador, "O símbolo '?' não é um operador válido em Pituguês.");
return direito;
}
if (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.NEGACAO, pitugues_1.default.SUBTRACAO, pitugues_1.default.BIT_NOT)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.unario();
return new construtos_1.Unario(-1, operador, direito, 'ANTES');
}
return this.chamar();
}
exponenciacao() {
let expressao = this.unario();
while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.EXPONENCIACAO)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.exponenciacao();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
adicaoOuSubtracao() {
let expressao = this.multiplicar();
while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.ADICAO, pitugues_1.default.SUBTRACAO)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.multiplicar();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
bitShift() {
let expressao = this.adicaoOuSubtracao();
while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.MENOR_MENOR, pitugues_1.default.MAIOR_MAIOR)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.adicaoOuSubtracao();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
bitE() {
let expressao = this.bitShift();
while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.BIT_AND)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.bitShift();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
bitOu() {
let expressao = this.bitE();
while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.BIT_OR, pitugues_1.default.BIT_XOR)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.bitE();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
comparar() {
let expressao = this.bitOu();
while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.MAIOR, pitugues_1.default.MAIOR_IGUAL, pitugues_1.default.MENOR, pitugues_1.default.MENOR_IGUAL)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.bitOu();
expressao = new construtos_1.Binario(-1, expressao, operador, direito);
}
return expressao;
}
em() {
let expressao = this.comparacaoIgualdade();
while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.EM)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.comparacaoIgualdade();
expressao = new construtos_1.Logico(-1, expressao, operador, direito);
}
return expressao;
}
e() {
let expressao = this.em();
while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.E)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.em();
expressao = new construtos_1.Logico(-1, expressao, operador, direito);
}
return expressao;
}
ou() {
let expressao = this.e();
while (this.verificarSeSimboloAtualEIgualA(pitugues_1.default.OU)) {
const operador = this.simbolos[this.atual - 1];
const direito = this.e();
expressao = new construtos_1.Logico(-1, expressao, operador, direito);
}
return expressao;
}
atribuir() {
return this.ou();
}
expressao() {
return this.atribuir();
}
analisar(retornoLexador, linha) {
this.erros = [];
this.atual = 0;
this.linha = linha;
this.simbolos = retornoLexador?.simbolos || [];
const declaracoes = [];
while (this.atual < this.simbolos.length) {
const expressao = this.expressao();
declaracoes.push(new declaracoes_1.Expressao(expressao));
}
return {
declaracoes: declaracoes,
erros: this.erros,
};
}
}
exports.MicroAvaliadorSintaticoPitugues = MicroAvaliadorSintaticoPitugues;
//# sourceMappingURL=micro-avaliador-sintatico-pitugues.js.map