@Override
	public Object visitExpression(ExpressionContext ctx, CalcScope scope) {
		setCurrentScope(scope);
		CalcValue value = new CalcValue();
		value.setType(int.class);
		if (ctx.getChildCount() == 1) {
			if (ctx.integerLiteral() instanceof CalcParser.IntegerLiteralContext) {
				value.setValue(visitIntegerLiteral(ctx.integerLiteral(), scope));
			} else {
				CalcVariable variable = scope.child(ctx.ID().getText());
				if (variable == null) {
					throw new CalcException("VARIABLE: " + ctx.ID().getText() + " NOT DECLARED!");
				}
				value = scope.child(ctx.ID().getText()).getVariableValue();
			}
		} else {
			if (ctx.getChild(0).getText().equals("(")) {
				value = (CalcValue) visitExpression(ctx.expression(0), scope);
			} else {
				CalcValue left = (CalcValue) visitExpression(ctx.expression(0), scope);
				CalcValue right = (CalcValue) visitExpression(ctx.expression(1), scope);
				if (ctx.op.getType() == CalcParser.ADD) {
					value.setValue(((Integer) left.getValue() + (Integer) right.getValue()));
				} else if (ctx.op.getType() == CalcParser.SUB) {
					value.setValue(((Integer) left.getValue() - (Integer) right.getValue()));
				} else if (ctx.op.getType() == CalcParser.MUL) {
					value.setValue(((Integer) left.getValue() * (Integer) right.getValue()));
				} else if (ctx.op.getType() == CalcParser.DIV) {
					value.setValue(((Integer) left.getValue() / (Integer) right.getValue()));
				} else if (ctx.op.getType() == CalcParser.MOD) {
					value.setValue(((Integer) left.getValue() % (Integer) right.getValue()));
				}
			}
		}
		return value;
	}