package fr.umlv.tatoo.tutorial.evalautoast;

import java.util.Stack;

import fr.umlv.tatoo.tutorial.evalautoast.ast.ExprMinus;
import fr.umlv.tatoo.tutorial.evalautoast.ast.ExprParens;
import fr.umlv.tatoo.tutorial.evalautoast.ast.ExprPlus;
import fr.umlv.tatoo.tutorial.evalautoast.ast.ExprStar;
import fr.umlv.tatoo.tutorial.evalautoast.ast.ExprValue;
import fr.umlv.tatoo.tutorial.evalautoast.ast.Start;
import fr.umlv.tatoo.tutorial.evalautoast.ast.ValueToken;
import fr.umlv.tatoo.tutorial.evalautoast.ast.Visitor;

public class EvaluationVisitor extends Visitor<Void, Void, RuntimeException> {
	private Stack<Integer> stack = new Stack<Integer>();
	
	@Override
	public Void visit(ExprMinus expr_minus, Void _param)
			throws RuntimeException {
		expr_minus.getExpr().accept(this, _param);
		int val = stack.pop();
		expr_minus.getExpr2().accept(this, _param);
		int val2 = stack.pop();
		stack.push(val - val2);
		return null;
	}

	@Override
	public Void visit(ExprParens expr_parens, Void _param)
			throws RuntimeException {
		expr_parens.getExpr().accept(this, _param);
		return null;
	}

	@Override
	public Void visit(ExprPlus expr_plus, Void _param) throws RuntimeException {
		expr_plus.getExpr().accept(this, _param);
		int val = stack.pop();
		expr_plus.getExpr2().accept(this, _param);
		int val2 = stack.pop();
		stack.push(val + val2);
		return null;
	}

	@Override
	public Void visit(ExprStar expr_star, Void _param) throws RuntimeException {
		expr_star.getExpr().accept(this, _param);
		int val = stack.pop();
		expr_star.getExpr2().accept(this, _param);
		int val2 = stack.pop();
		stack.push(val * val2);
		return null;
	}

	@Override
	public Void visit(ExprValue expr_value, Void _param)
			throws RuntimeException {
		stack.push(expr_value.getValue().getValue());
		return null;
	}

	@Override
	public Void visit(Start start, Void _param) throws RuntimeException {
		start.getExpr().accept(this, _param);
		System.out.println(stack.pop());
		return null;
	}

	@Override
	public Void visit(ValueToken value, Void _param) throws RuntimeException {
		return null;
	}

}
