<commit_before>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.beholder.memelang.model.visitor;

import br.beholder.memelang.model.language.MemelangParser;
import br.beholder.memelang.model.analisador.Identificador.Tipo;
import br.beholder.memelang.model.analisador.Escopo;
import br.beholder.memelang.model.analisador.Identificador;
import br.beholder.memelang.model.language.MemelangParser.ExpressaoContext;
import br.beholder.memelang.model.language.MemelangParser.TipoContext;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.antlr.v4.runtime.tree.TerminalNode;



/**
 *
 * @author Alisson
 */
public class SemanticVisitor extends MemeVisitor{
    
    List<ParseCancellationException> semanticErrors = new ArrayList<ParseCancellationException>();
    List<String> semanticWarnings = new ArrayList<String>();
    Stack<Identificador.Tipo> pilhaTipoExpressao = new Stack<>();
    Stack<Operation> pilhaOperacao = new Stack<>();
    boolean temRetorno = false;
    Tipo tipoFuncao = null;
    int contEscopo = 1;
    
    public SemanticVisitor(List<Identificador> tabelaSimbolos) {
        super(tabelaSimbolos);
    }

    public List<Identificador> getTabelaSimbolos() {
        return tabelaSimbolos;
    }
    
    @Override
    public Object visitTipoComVoid(MemelangParser.TipoComVoidContext ctx) {
        if (ctx.VOID() != null) {
            tipoAtual = Tipo.VOID;
        } else {
            visitTipo(ctx.tipo());
        }
        return null;
    }

    public Tipo visitExpressaoLoop(MemelangParser.ExpressaoContext ctx){
        if (ctx == null) {
            return null;
        }
        Stack<Identificador.Tipo> pilhaTipoExpressaoLoop = new Stack<>();
        Stack<Operation> pilhaOperacaoLoop = new Stack<>();
        
        
        for (MemelangParser.OperationsContext opCont : ctx.operations()) {
            pilhaOperacaoLoop.push(verificarTipoOperacao(opCont));
        }
        for (int i = 0; i < ctx.val_final().size(); i++) {
            String valFinal = ctx.val_final(i).getText();            
            Tipo tipoExpParenteses = null;
            if(ctx.val_final(i).multidimensional() != null){
                valFinal =  ctx.val_final(i).ID().getText();
            }
            if(ctx.val_final(i).chamadaFuncao() != null){
                valFinal = ctx.val_final(i).chamadaFuncao().ID().getText();
            }
            if(ctx.val_final(i).PARENTESEABRE() != null){
                pilhaTipoExpressaoLoop.push(visitExpressaoLoop(ctx.val_final(i).expressao()));
                
                continue;
            }
            if (Identificador.getId(valFinal, tabelaSimbolos, escopoAtual) != null) {
                Identificador id = Identificador.getId(valFinal, tabelaSimbolos, escopoAtual);
                if (ctx.val_final(i).multidimensional() != null) {
                    Tipo posicaoVetor = visitExpressaoLoop(ctx.val_final(i).multidimensional().expressao(0));
                    if(posicaoVetor != Tipo.INTEIRO){
                        this.semanticErrors.add(new ParseCancellationException("Tentando acessar posição de vetor com tipo não inteiro na Linha: " + ctx.start.getLine() + " Coluna: " + ctx.start.getCharPositionInLine()));
                    }
                    visitMultidimensional(ctx.val_final(i).multidimensional(), posicaoVetor);
                } else {
                    multidimensional = 0;
                }
                if (!id.isInicializada()) {
                    this.semanticErrors.add(new ParseCancellationException("Váriavel " + id.getNome() + " não inicializada Linha: " + ctx.start.getLine() + " Coluna: " + ctx.start.getCharPositionInLine()));
                }
                if (id.getDimensoes() != multidimensional) {
                    this.semanticErrors.add(new ParseCancellationException("Dimensões incorreta do vetor " + id.getNome() + " . Ele possui " + id.getDimensoes() + " dimensões e foi usada " + multidimensional + " Linha: " + ctx.start.getLine() + " Coluna: " + ctx.start.getCharPositionInLine()));
                }
                id.setUsada(true);
                
                pilhaTipoExpressaoLoop.push(id.getTipo());
                
            }else if(verificarTipoConstante(ctx.val_final(i)) == null && tipoExpParenteses == null){
                this.semanticErrors.add(new ParseCancellationException("Váriavel " + valFinal + " não existe neste escopo Linha: " + ctx.start.getLine() + " Coluna: " + ctx.start.getCharPositionInLine()));
            }else{
                if(tipoExpParenteses != null){
                    pilhaTipoExpressaoLoop.push(tipoExpParenteses);
                }
                pilhaTipoExpressaoLoop.push(verificarTipoConstante(ctx.val_final(i)));
            }
        }
        verificarCompatibilidadeOperacao(ctx, pilhaTipoExpressaoLoop, pilhaOperacaoLoop);
        return pilhaTipoExpressaoLoop.peek();
    }
    
    @Override
    public Object visitExpressao(MemelangParser.ExpressaoContext ctx) {
        if (ctx == null) {
            return null;
        }
        this.pilhaOperacao.clear();
        this.pilhaTipoExpressao.clear();
        for (MemelangParser.OperationsContext opCont : ctx.operations()) {
            this.pilhaOperacao.push(verificarTipoOperacao(opCont));
        }
        for (int i = 0; i < ctx.val_final().size(); i++) {
            String valFinal = ctx.val_final(i).getText();            
            if(ctx.val_final(i).multidimensional() != null){
                valFinal =  ctx.val_final(i).ID().getText();
            }
            if(ctx.val_final(i).chamadaFuncao()!= null){
                visitChamadaFuncao(ctx.val_final(i).chamadaFuncao());
                valFinal = ctx.val_final(i).chamadaFuncao().ID().getText();
            }
            if(ctx.val_final(i).PARENTESEABRE() != null){
                this.pilhaTipoExpressao.push(visitExpressaoLoop(ctx.val_final(i).expressao()));<commit_msg>verificando escopo de variavel no retorno<commit_after>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.beholder.memelang.model.visitor;

import br.beholder.memelang.model.language.MemelangParser;
import br.beholder.memelang.model.analisador.Identificador.Tipo;
import br.beholder.memelang.model.analisador.Escopo;
import br.beholder.memelang.model.analisador.Identificador;
import br.beholder.memelang.model.language.MemelangParser.ExpressaoContext;
import br.beholder.memelang.model.language.MemelangParser.TipoContext;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.antlr.v4.runtime.tree.TerminalNode;



/**
 *
 * @author Alisson
 */
public class SemanticVisitor extends MemeVisitor{
    
    List<ParseCancellationException> semanticErrors = new ArrayList<ParseCancellationException>();
    List<String> semanticWarnings = new ArrayList<String>();
    Stack<Identificador.Tipo> pilhaTipoExpressao = new Stack<>();
    Stack<Operation> pilhaOperacao = new Stack<>();
    boolean temRetorno = false;
    Tipo tipoFuncao = null;
    int contEscopo = 1;
    
    public SemanticVisitor(List<Identificador> tabelaSimbolos) {
        super(tabelaSimbolos);
    }

    public List<Identificador> getTabelaSimbolos() {
        return tabelaSimbolos;
    }
    
    @Override
    public Object visitTipoComVoid(MemelangParser.TipoComVoidContext ctx) {
        if (ctx.VOID() != null) {
            tipoAtual = Tipo.VOID;
        } else {
            visitTipo(ctx.tipo());
        }
        return null;
    }

    public Tipo visitExpressaoLoop(MemelangParser.ExpressaoContext ctx){
        if (ctx == null) {
            return null;
        }
        Stack<Identificador.Tipo> pilhaTipoExpressaoLoop = new Stack<>();
        Stack<Operation> pilhaOperacaoLoop = new Stack<>();
        
        
        for (MemelangParser.OperationsContext opCont : ctx.operations()) {
            pilhaOperacaoLoop.push(verificarTipoOperacao(opCont));
        }
        for (int i = 0; i < ctx.val_final().size(); i++) {
            String valFinal = ctx.val_final(i).getText();            
            Tipo tipoExpParenteses = null;
            if(ctx.val_final(i).multidimensional() != null){
                valFinal =  ctx.val_final(i).ID().getText();
            }
            if(ctx.val_final(i).chamadaFuncao() != null){
                valFinal = ctx.val_final(i).chamadaFuncao().ID().getText();
            }
            if(ctx.val_final(i).PARENTESEABRE() != null){
                pilhaTipoExpressaoLoop.push(visitExpressaoLoop(ctx.val_final(i).expressao()));
                
                continue;
            }
            if (Identificador.getId(valFinal, tabelaSimbolos, escopoAtual) != null) {
                Identificador id = Identificador.getId(valFinal, tabelaSimbolos, escopoAtual);
                if (ctx.val_final(i).multidimensional() != null) {
                    Tipo posicaoVetor = visitExpressaoLoop(ctx.val_final(i).multidimensional().expressao(0));
                    if(posicaoVetor != Tipo.INTEIRO){
                        this.semanticErrors.add(new ParseCancellationException("Tentando acessar posição de vetor com tipo não inteiro na Linha: " + ctx.start.getLine() + " Coluna: " + ctx.start.getCharPositionInLine()));
                    }
                    visitMultidimensional(ctx.val_final(i).multidimensional(), posicaoVetor);
                } else {
                    multidimensional = 0;
                }
                if (!id.isInicializada()) {
                    this.semanticErrors.add(new ParseCancellationException("Váriavel " + id.getNome() + " não inicializada Linha: " + ctx.start.getLine() + " Coluna: " + ctx.start.getCharPositionInLine()));
                }
                if (id.getDimensoes() != multidimensional) {
                    this.semanticErrors.add(new ParseCancellationException("Dimensões incorreta do vetor " + id.getNome() + " . Ele possui " + id.getDimensoes() + " dimensões e foi usada " + multidimensional + " Linha: " + ctx.start.getLine() + " Coluna: " + ctx.start.getCharPositionInLine()));
                }
                id.setUsada(true);
                
                pilhaTipoExpressaoLoop.push(id.getTipo());
                
            }else if(verificarTipoConstante(ctx.val_final(i)) == null && tipoExpParenteses == null){
                this.semanticErrors.add(new ParseCancellationException("Váriavel " + valFinal + " não existe neste escopo Linha: " + ctx.start.getLine() + " Coluna: " + ctx.start.getCharPositionInLine()));
            }else{
                if(tipoExpParenteses != null){
                    pilhaTipoExpressaoLoop.push(tipoExpParenteses);
                }
                pilhaTipoExpressaoLoop.push(verificarTipoConstante(ctx.val_final(i)));
            }
        }
        verificarCompatibilidadeOperacao(ctx, pilhaTipoExpressaoLoop, pilhaOperacaoLoop);
        if(pilhaTipoExpressaoLoop.empty())
        {
            return null;
        }
        return pilhaTipoExpressaoLoop.peek();
    }
    
    @Override
    public Object visitExpressao(MemelangParser.ExpressaoContext ctx) {
        if (ctx == null) {
            return null;
        }
        this.pilhaOperacao.clear();
        this.pilhaTipoExpressao.clear();
        for (MemelangParser.OperationsContext opCont : ctx.operations()) {
            this.pilhaOperacao.push(verificarTipoOperacao(opCont));
        }
        for (int i = 0; i < ctx.val_final().size(); i++) {
            String valFinal = ctx.val_final(i).getText();            
            if(ctx.val_final(i).multidimensional() != null){
                valFinal =  ctx.val_final(i).ID().getText();
            }
            if(ctx.val_final(i).chamadaFuncao()!= null){
                visitChamadaFuncao(ctx.val_final(i).chamadaFuncao());
                valFinal = ctx.val_final(i).chamadaFuncao().ID().getText();
            }
            if(ctx.val_final(i).PARENTESEABRE() != null){
                this.pilhaTipoExpressao.push(visitExpressaoLoop(ctx.val_final(i).expressao()));
{'fraction_non_alphanumeric': 0.11634920634920635, 'fraction_numerical': 0.0012698412698412698, 'mean_word_length': 2.431644880174292, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2012341', 'n_tokens_mistral': 3922, 'n_tokens_neox': 3825, 'n_words': 595}