예제 #1
0
        private void CalculateTypeForNodes(IAstNode exprNode)
        {
            if (exprNode.AstNodeType == AstNodeTypes.BinaryOperator)
            {
                var binOpNode = exprNode.AsBinaryOp();

                CalculateTypeForNodes(binOpNode.LeftOperand);
                binOpNode.TypeName = binOpNode.LeftOperand.AsNodeWithType().TypeName;
                CalculateTypeForNodes(binOpNode.RightOperand);
            }
            else if (exprNode.AstNodeType == AstNodeTypes.UnaryOperator)
            {
                CalculateTypeForNodes(exprNode.AsUnaryOp().Operand);
            }
            else if (exprNode.AstNodeType == AstNodeTypes.VarReference)
            {
                var varRef = exprNode.AsVarReferene();

                if (!_symbolTable.ContainsKey(varRef.Name))
                {
                    throw new SemanticErrorException($"Variable '{varRef.Name}' is not declared.", exprNode);
                }

                exprNode.AsVarReferene().TypeName = _symbolTable[varRef.Name];
            }
        }
예제 #2
0
        private void CheckNodeType(IAstNode exprNode)
        {
            if (exprNode.AstNodeType == AstNodeTypes.BinaryOperator)
            {
                var binOpNode = exprNode.AsBinaryOp();

                CheckNodeType(binOpNode.LeftOperand);
                CheckNodeType(binOpNode.RightOperand);

                if (binOpNode.LeftOperand.AsNodeWithType().TypeName !=
                    binOpNode.RightOperand.AsNodeWithType().TypeName)
                {
                    throw new SemanticErrorException("Type mismatch.", binOpNode);
                }
            }
            else if (exprNode.AstNodeType == AstNodeTypes.UnaryOperator)
            {
                var unaryOpNode = exprNode.AsUnaryOp();

                CheckNodeType(unaryOpNode.Operand);
                if (unaryOpNode.TypeName != unaryOpNode.Operand.AsNodeWithType().TypeName)
                {
                    throw new SemanticErrorException("Type mismatch.", unaryOpNode);
                }
            }
        }
예제 #3
0
        public void Traverse(IAstNode astNode)
        {
            ProcessNode?.Invoke(astNode);

            switch (astNode.AstNodeType)
            {
            case AstNodeTypes.VarStatement:
                Traverse(astNode.AsVarStatement().Expression);
                break;

            case AstNodeTypes.PrintStatement:
                foreach (var printExpr in astNode.AsPrintStatement().PrintExpressions)
                {
                    Traverse(printExpr);
                }
                break;

            case AstNodeTypes.PrintExpression:
                Traverse(astNode.AsPrintExpression().Expression);
                break;

            case AstNodeTypes.UnaryOperator:
                Traverse(astNode.AsUnaryOp().Operand);
                break;

            case AstNodeTypes.BinaryOperator:
                Traverse(astNode.AsBinaryOp().LeftOperand);
                Traverse(astNode.AsBinaryOp().RightOperand);
                break;

            case AstNodeTypes.NumberLiteral:
                break;

            case AstNodeTypes.StringLiteral:
                break;

            case AstNodeTypes.VarReference:
                break;
            }

            PostProcessNode?.Invoke(astNode.AstNodeType);
        }