import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.antlr.v4.runtime.tree.ParseTreeProperty;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

public class AntlrCalcEvaluator extends ACalcParserBaseVisitor<Integer> {
    @Override
    public Integer visitProgram(ACalcParser.ProgramContext ctx) {
        visit(ctx.stmt());
        visit(ctx.prog());
        return null;
    }

    @Override
    public Integer visitStmt(ACalcParser.StmtContext ctx) {
        int value = visit(ctx.exp());
        System.out.println(value);
        return null;
    }

    @Override
    public Integer visitAddSub(ACalcParser.AddSubContext ctx) {
        int lhs = visit(ctx.exp());
        int rhs = visit(ctx.term());
        String oper = ctx.OPA().getText();
        if (oper.equals("+")) return lhs + rhs;
        else return lhs - rhs;
    }

    @Override
    public Integer visitSingleTerm(ACalcParser.SingleTermContext ctx) {
        return visit(ctx.term());
    }

    @Override
    public Integer visitMulDiv(ACalcParser.MulDivContext ctx) {
        int lhs = visit(ctx.term());
        int rhs = visit(ctx.factor());
        String oper = ctx.OPM().getText();
        if (oper.equals("*")) return lhs * rhs;
        else return lhs / rhs;
    }

    @Override
    public Integer visitSingleFactor(ACalcParser.SingleFactorContext ctx) {
        return visit(ctx.factor());
    }

    @Override
    public Integer visitNum(ACalcParser.NumContext ctx) {
        String numstr = ctx.NUM().getText();
        return Integer.valueOf(numstr);
    }

    @Override
    public Integer visitParens(ACalcParser.ParensContext ctx) {
        return visit(ctx.exp());
    }
}