<commit_before>package tours.typechecker;

import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.TerminalNode;
import tours.SymbolTable;
import tours.Type;
import tours.grammar.ToursBaseListener;
import tours.grammar.ToursParser;

import java.util.ArrayList;
import java.util.List;

public class TypeChecker extends ToursBaseListener {
    private final SymbolTable symbolTable;
    private List<String> errors;

    public TypeChecker() {
        symbolTable = new SymbolTable();
        errors = new ArrayList<>();
    }

    @Override
    public void enterBody(@NotNull ToursParser.BodyContext ctx) {
        symbolTable.openScope();
    }

    @Override
    public void exitBody(@NotNull ToursParser.BodyContext ctx) {
        symbolTable.closeScope();
    }

    @Override
    public void exitVariablePrimitive(@NotNull ToursParser.VariablePrimitiveContext ctx) {
        // declarations
        for (TerminalNode identifier : ctx.IDENTIFIER()) {
            String id = identifier.getText();
            if (symbolTable.containsInCurrentScope(id)) {
                errors.add(String.format("Error <variable already defined> on line %s, pos %s", identifier.getSymbol().getLine(), identifier.getSymbol().getCharPositionInLine()));
            } else {
                symbolTable.addVariable(id, new Type(ctx.primitiveType().getText()));
                symbolTable.addVariable(ctx.getText(), new Type(ctx.primitiveType().getText()));
            }
        }

        // assignment
        if (ctx.expression() != null && !(new Type(ctx.primitiveType().getText())).equals(symbolTable.getType(ctx.expression().getText()))) {
            errors.add(String.format("Error <mismatching types> on line %s, pos %s", ctx.ASSIGNMENT().getSymbol().getLine(), ctx.ASSIGNMENT().getSymbol().getCharPositionInLine()));
        }
    }

    @Override
    public void exitVariableArray(@NotNull ToursParser.VariableArrayContext ctx) {
        // declarations
        for (TerminalNode identifier : ctx.IDENTIFIER()) {
            String id = identifier.getText();
            if (symbolTable.containsInCurrentScope(id)) {
                errors.add(String.format("Error <variable already defined> on line %s, pos %s", identifier.getSymbol().getLine(), identifier.getSymbol().getCharPositionInLine()));
            } else {
                symbolTable.addVariable(id, new Type(ctx.arrayType().getText()));
                symbolTable.addVariable(ctx.getText(), new Type(ctx.arrayType().getText()));
            }
        }

        // assignment
        if (!(new Type(ctx.arrayType().getText())).getPrimitiveType().equals(symbolTable.getType(ctx.arrayAssignment().getText()))) {
            errors.add(String.format("Error <mismatching types> on line %s, pos %s", ctx.ASSIGNMENT().getSymbol().getLine(), ctx.ASSIGNMENT().getSymbol().getCharPositionInLine()));
        }<commit_msg>Fixed build on type checker<commit_after>package tours.typechecker;

import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.TerminalNode;
import tours.SymbolTable;
import tours.Type;
import tours.grammar.ToursBaseListener;
import tours.grammar.ToursParser;

import java.util.ArrayList;
import java.util.List;

public class TypeChecker extends ToursBaseListener {
    private final SymbolTable symbolTable;
    private List<String> errors;

    public TypeChecker() {
        symbolTable = new SymbolTable();
        errors = new ArrayList<>();
    }

    @Override
    public void enterBody(@NotNull ToursParser.BodyContext ctx) {
        symbolTable.openScope();
    }

    @Override
    public void exitBody(@NotNull ToursParser.BodyContext ctx) {
        symbolTable.closeScope();
    }

    @Override
    public void exitVariablePrimitive(@NotNull ToursParser.VariablePrimitiveContext ctx) {
        // declarations
        for (TerminalNode identifier : ctx.IDENTIFIER()) {
            String id = identifier.getText();
            if (symbolTable.containsInCurrentScope(id)) {
                errors.add(String.format("Error <variable already defined> on line %s, pos %s", identifier.getSymbol().getLine(), identifier.getSymbol().getCharPositionInLine()));
            } else {
                symbolTable.addVariable(id, new Type(ctx.primitiveType().getText()));
                symbolTable.addVariable(ctx.getText(), new Type(ctx.primitiveType().getText()));
            }
        }

        // assignment
        if (ctx.expression() != null && !(new Type(ctx.primitiveType().getText())).equals(symbolTable.getType(ctx.expression().getText()))) {
            errors.add(String.format("Error <mismatching types> on line %s, pos %s", ctx.ASSIGNMENT().getSymbol().getLine(), ctx.ASSIGNMENT().getSymbol().getCharPositionInLine()));
        }
    }

    @Override
    public void exitVariableArray(@NotNull ToursParser.VariableArrayContext ctx) {
        // declarations
        for (TerminalNode identifier : ctx.IDENTIFIER()) {
            String id = identifier.getText();
            if (symbolTable.containsInCurrentScope(id)) {
                errors.add(String.format("Error <variable already defined> on line %s, pos %s", identifier.getSymbol().getLine(), identifier.getSymbol().getCharPositionInLine()));
            } else {
                symbolTable.addVariable(id, new Type(ctx.arrayType().getText()));
                symbolTable.addVariable(ctx.getText(), new Type(ctx.arrayType().getText()));
            }
        }

        String arrayType = new Type(ctx.arrayType().getText()).getPrimitiveType();
        String assignmentType = symbolTable.getType(ctx.arrayAssignment().getText()).toString();
        // assignment
        if (!arrayType.equals(assignmentType)) {
            errors.add(String.format("Error <mismatching types> on line %s, pos %s", ctx.ASSIGNMENT().getSymbol().getLine(), ctx.ASSIGNMENT().getSymbol().getCharPositionInLine()));
        }
{'fraction_non_alphanumeric': 0.1315566117806824, 'fraction_numerical': 0.0006790018672551349, 'mean_word_length': 3.131837307152875, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, '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': '1363366', 'n_tokens_mistral': 1561, 'n_tokens_neox': 1531, 'n_words': 310}