public void CheckSemantic(CaseNode node, IScope scope = null)
        {
            CheckSemantic(node.Expression, scope);

            IType type = null;

            foreach (var caseOptionNode in node.CaseOptionNodes)
            {
                CheckSemantic(caseOptionNode, scope);

                type = type is null ?
                       caseOptionNode.ComputedType :
                       CoolType.Lca((CoolType)type, (CoolType)caseOptionNode.ComputedType);
            }
            node.ComputedType = type;
        }
        public void CheckSemantic(IfNode node, IScope scope = null)
        {
            CheckSemantic(node.Condition, scope);

            if (node.Condition.ComputedType.Name != "Bool")
            {
                Logger.LogError(node.Line, node.CharPositionInLine,
                                $"Cannot implicitly convert type '{node.Condition.ComputedType}' to 'Bool'");
            }

            CheckSemantic(node.ThenExpression, scope);
            if (node.ElseExpression == null)
            {
                node.ComputedType = node.ThenExpression.ComputedType;
            }
            else
            {
                CheckSemantic(node.ElseExpression, scope);
                node.ComputedType = CoolType.Lca((CoolType)node.ThenExpression.ComputedType,
                                                 (CoolType)node.ElseExpression.ComputedType);
            }
        }