@designliquido/delegua
Version:
Linguagem de programação simples e moderna usando português estruturado.
314 lines • 11.9 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.LexadorCalango = void 0;
const simbolo_1 = require("../simbolo");
const calango_1 = __importDefault(require("./palavras-reservadas/calango"));
const calango_2 = __importDefault(require("../../tipos-de-simbolos/calango"));
class LexadorCalango {
eDigito(caractere) {
return caractere >= '0' && caractere <= '9';
}
eAlfabeto(caractere) {
const acentuacoes = [
'á',
'Á',
'ã',
'Ã',
'â',
'Â',
'à',
'À',
'é',
'É',
'ê',
'Ê',
'í',
'Í',
'ó',
'Ó',
'õ',
'Õ',
'ô',
'Ô',
'ú',
'Ú',
'ç',
'Ç',
'_',
];
return ((caractere >= 'a' && caractere <= 'z') ||
(caractere >= 'A' && caractere <= 'Z') ||
acentuacoes.includes(caractere));
}
eAlfabetoOuDigito(caractere) {
return this.eDigito(caractere) || this.eAlfabeto(caractere);
}
eFinalDoCodigo() {
if (this.linha > this.codigo.length - 1)
return true;
return (this.linha == this.codigo.length - 1 &&
this.codigo[this.codigo.length - 1].length <= this.atual);
}
eUltimaLinha() {
return this.linha >= this.codigo.length - 1;
}
eFinalDaLinha() {
return this.atual >= this.codigo[this.linha].length;
}
avancar() {
this.atual += 1;
if (this.eFinalDaLinha() && !this.eUltimaLinha()) {
this.linha++;
this.atual = 0;
// this.logicaEmLinhaIniciada = false;
}
}
adicionarSimbolo(tipo, literal) {
const texto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
const comprimento = Math.max(texto.length, 1);
const colunaInicio = this.inicioSimbolo + 1;
const colunaFim = this.inicioSimbolo + comprimento;
this.simbolos.push(new simbolo_1.Simbolo(tipo, texto, literal, this.linha, -1, colunaInicio, colunaFim));
}
simboloAtual() {
if (this.eFinalDaLinha())
return '\0';
if (this.linha > this.codigo.length - 1)
return '\0';
return this.codigo[this.linha].charAt(this.atual);
}
proximoSimbolo() {
if (this.atual + 1 >= this.codigo[this.linha].length)
return '\0';
return this.codigo[this.linha].charAt(this.atual + 1);
}
simboloAnterior() {
return this.codigo[this.linha].charAt(this.atual - 1);
}
analisarTexto(delimitador) {
const linhaPrimeiroCaracter = this.linha;
while (this.simboloAtual() !== delimitador && !this.eFinalDoCodigo()) {
this.avancar();
}
if (this.eFinalDoCodigo()) {
this.erros.push({
linha: this.linha + 1,
caractere: this.simboloAnterior(),
mensagem: 'Texto não finalizado.',
});
return;
}
const textoCompleto = this.codigo[this.linha].substring(this.inicioSimbolo + 1, this.atual);
this.simbolos.push(new simbolo_1.Simbolo(calango_2.default.TEXTO, textoCompleto, textoCompleto, linhaPrimeiroCaracter + 1, this.hashArquivo));
}
analisarCaracter() {
const linhaPrimeiroCaracter = this.linha;
// Restringe leitura à linha atual (como analisarNumero), evitando
// que avancar() mude this.linha e corrompa o cálculo do substring.
while (this.simboloAtual() !== "'" &&
this.linha === linhaPrimeiroCaracter &&
!this.eFinalDoCodigo()) {
this.avancar();
}
if (this.linha !== linhaPrimeiroCaracter || this.eFinalDoCodigo()) {
this.erros.push({
linha: linhaPrimeiroCaracter + 1,
caractere: this.simboloAnterior(),
mensagem: 'Caractere não finalizado.',
});
return;
}
const valorCaracter = this.codigo[linhaPrimeiroCaracter].substring(this.inicioSimbolo + 1, this.atual);
this.simbolos.push(new simbolo_1.Simbolo(calango_2.default.LITERAL_CARACTER, valorCaracter, valorCaracter, linhaPrimeiroCaracter + 1, this.hashArquivo));
}
analisarNumero() {
const linhaPrimeiroDigito = this.linha;
while (this.eDigito(this.simboloAtual()) && this.linha === linhaPrimeiroDigito) {
this.avancar();
}
if (this.simboloAtual() == '.' && this.eDigito(this.proximoSimbolo())) {
this.avancar();
while (this.eDigito(this.simboloAtual())) {
this.avancar();
}
}
let numeroCompleto;
if (linhaPrimeiroDigito < this.linha) {
const linhaNumero = this.codigo[linhaPrimeiroDigito];
numeroCompleto = linhaNumero.substring(this.inicioSimbolo, linhaNumero.length);
}
else {
numeroCompleto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
}
this.simbolos.push(new simbolo_1.Simbolo(calango_2.default.NUMERO, numeroCompleto, parseFloat(numeroCompleto), linhaPrimeiroDigito + 1, this.hashArquivo));
}
identificarPalavraChave() {
const linhaPrimeiroCaracter = this.linha;
while (this.eAlfabetoOuDigito(this.simboloAtual()) &&
this.linha === linhaPrimeiroCaracter) {
this.avancar();
}
let textoPalavraChave;
if (linhaPrimeiroCaracter < this.linha) {
const linhaPalavraChave = this.codigo[linhaPrimeiroCaracter];
textoPalavraChave = linhaPalavraChave.substring(this.inicioSimbolo, linhaPalavraChave.length);
}
else {
textoPalavraChave = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
}
const tipo = textoPalavraChave in calango_1.default
? calango_1.default[textoPalavraChave]
: calango_2.default.IDENTIFICADOR;
this.simbolos.push(new simbolo_1.Simbolo(tipo, textoPalavraChave, null, linhaPrimeiroCaracter + 1, this.hashArquivo));
}
analisarToken() {
const caractere = this.simboloAtual();
switch (caractere) {
case ' ':
case '\t':
case '\0':
this.avancar();
break;
case '\r':
case '\n':
this.adicionarSimbolo(calango_2.default.QUEBRA_LINHA); // Quebra de linha adicionada para identificar o início do código
this.avancar();
break;
case ';': // Calango exige o ponto e vírgula para indicar final do código
this.adicionarSimbolo(calango_2.default.PONTO_E_VIRGULA);
this.avancar();
break;
case '"':
this.avancar();
this.analisarTexto('"');
this.avancar();
break;
case "'":
this.avancar();
this.analisarCaracter();
this.avancar();
break;
case ':':
this.adicionarSimbolo(calango_2.default.DOIS_PONTOS);
this.avancar();
break;
case '[':
this.adicionarSimbolo(calango_2.default.COLCHETE_ESQUERDO);
this.avancar();
break;
case ']':
this.adicionarSimbolo(calango_2.default.COLCHETE_DIREITO);
this.avancar();
break;
case '(':
this.adicionarSimbolo(calango_2.default.PARENTESE_ESQUERDO);
this.avancar();
break;
case ')':
this.adicionarSimbolo(calango_2.default.PARENTESE_DIREITO);
this.avancar();
break;
case ',':
this.adicionarSimbolo(calango_2.default.VIRGULA);
this.avancar();
break;
case '+':
this.adicionarSimbolo(calango_2.default.ADICAO);
this.avancar();
break;
case '-':
this.adicionarSimbolo(calango_2.default.SUBTRACAO);
this.avancar();
break;
case '*':
this.adicionarSimbolo(calango_2.default.MULTIPLICACAO);
this.avancar();
break;
case '/':
if (this.proximoSimbolo() === '/') {
// Comentário de linha: consumir até ao fim da linha sem emitir símbolo.
// Guardamos o número da linha para parar quando avancar() mudar para a próxima.
const linhaComentario = this.linha;
while (this.linha === linhaComentario && !this.eFinalDoCodigo()) {
this.avancar();
}
}
else {
this.adicionarSimbolo(calango_2.default.DIVISAO);
this.avancar();
}
break;
case '=':
this.adicionarSimbolo(calango_2.default.IGUAL_ATRIBUICAO);
this.avancar();
break;
case '>':
this.avancar();
if (this.simboloAtual() === '=') {
this.adicionarSimbolo(calango_2.default.MAIOR_IGUAL, '>=');
this.avancar();
}
else {
this.adicionarSimbolo(calango_2.default.MAIOR);
}
break;
case '<':
this.avancar();
if (this.simboloAtual() === '=') {
this.adicionarSimbolo(calango_2.default.MENOR_IGUAL, '<=');
this.avancar();
}
else if (this.simboloAtual() === '>') {
this.adicionarSimbolo(calango_2.default.DIFERENTE, '<>');
this.avancar();
}
else {
this.adicionarSimbolo(calango_2.default.MENOR);
}
break;
case '%':
this.adicionarSimbolo(calango_2.default.MODULO);
this.avancar();
break;
case '^':
this.adicionarSimbolo(calango_2.default.EXPONENCIACAO);
this.avancar();
break;
default:
if (this.eDigito(caractere))
this.analisarNumero();
else if (this.eAlfabeto(caractere))
this.identificarPalavraChave();
else {
this.erros.push({
linha: this.linha + 1,
caractere: caractere,
mensagem: 'Caractere inesperado.',
});
this.avancar();
}
}
}
mapear(codigo, hashArquivo) {
this.simbolos = [];
this.erros = [];
this.inicioSimbolo = 0;
this.atual = 0;
this.linha = 0;
this.codigo = codigo || [''];
this.hashArquivo = hashArquivo;
while (!this.eFinalDoCodigo()) {
this.inicioSimbolo = this.atual;
this.analisarToken();
}
return {
simbolos: this.simbolos,
erros: this.erros,
};
}
}
exports.LexadorCalango = LexadorCalango;
//# sourceMappingURL=lexador-calango.js.map