Exemple #1
0
 /// <summary>
 /// Carries out type checking on a node
 /// </summary>
 /// <param name="node">The node to perform type checking on</param>
 private void PerformTypeChecking(IAbstractSyntaxTreeNode node)
 {
     if (node is null)
     {
         // Shouldn't have null nodes - there is a problem with your parsing
         Debugger.Write("Tried to perform type checking on a null tree node");
     }
     else if (node is ErrorNode)
     {
         // Shouldn't have error nodes - there is a problem with your parsing
         Debugger.Write("Tried to perform type checking on an error tree node");
     }
     else
     {
         string     functionName = "PerformTypeCheckingOn" + node.GetType().Name.Remove(node.GetType().Name.Length - 4);
         MethodInfo function     = this.GetType().GetMethod(functionName, NonPublic | Public | Instance | Static);
         if (function == null)
         {
             // There is not a correctly named function below
             Debugger.Write($"Couldn't find the function {functionName} when type checking");
         }
         else
         {
             function.Invoke(this, new[] { node });
         }
     }
 }
Exemple #2
0
 /// <summary>
 /// Carries out code generation for a node
 /// </summary>
 /// <param name="node">The node to generate code for</param>
 private TargetCode GenerateCodeFor(IAbstractSyntaxTreeNode node)
 {
     if (node is null)
     {
         // Shouldn't have null nodes - there is a problem with your parsing
         Debugger.Write("Tried to generate code for a null tree node");
         return(null);
     }
     else if (node is ErrorNode)
     {
         // Shouldn't have error nodes - there is a problem with your parsing
         Debugger.Write("Tried to generate code for an error tree node");
         return(null);
     }
     else
     {
         string     functionName = "GenerateCodeFor" + node.GetType().Name.Remove(node.GetType().Name.Length - 4);
         MethodInfo function     = this.GetType().GetMethod(functionName, NonPublic | Public | Instance | Static);
         if (function == null)
         {
             // There is not a correctly named function below
             Debugger.Write($"Couldn't find the function {functionName} when generating code");
             return(null);
         }
         else
         {
             return((TargetCode)function.Invoke(this, new[] { node }));
         }
     }
 }
 /// <summary>
 /// Carries out identification on a node
 /// </summary>
 /// <param name="node">The node to perform identification on</param>
 private void PerformIdentification(IAbstractSyntaxTreeNode node)
 {
     if (node is null)
     {
         IsItDirty();
         Reporter.IdentifierErrorPositions.Add($"Error has occured here:, null tree node");
         // Shouldn't have null nodes - there is a problem with your parsing
         Debugger.Write("Tried to perform identification on a null tree node");
     }
     else if (node is ErrorNode)
     {
         IsItDirty();
         Reporter.IdentifierErrorPositions.Add($"Error has occured here: {node.Position}, error tree node.");
         // Shouldn't have error nodes - there is a problem with your parsing
         Debugger.Write("Tried to perform identification on an error tree node");
     }
     else
     {
         string     functionName = "PerformIdentificationOn" + node.GetType().Name.Remove(node.GetType().Name.Length - 4);
         MethodInfo function     = this.GetType().GetMethod(functionName, NonPublic | Public | Instance | Static);
         if (function == null)
         {
             IsItDirty();
             Reporter.IdentifierErrorPositions.Add($"Error has occured here: {node.Position}, {node.GetType()} function name is null ");
             // There is not a correctly named function below
             Debugger.Write($"Couldn't find the function {functionName} when doing identification");
         }
         else
         {
             function.Invoke(this, new[] { node });
         }
     }
 }
Exemple #4
0
 /// <summary>
 /// Gets the token associated with a node
 /// </summary>
 /// <param name="node">The node to get the token for</param>
 /// <returns>The token associated with this node</returns>
 private static Token GetToken(IAbstractSyntaxTreeNode node)
 {
     return(node.GetType().GetProperties()
            .Where(property => property.PropertyType.GetType() == typeof(Token))
            .Select(property => (Token)property.GetValue(node))
            .FirstOrDefault());
 }
Exemple #5
0
        /// <summary>
        /// Gets children of a node which are in a collection
        /// </summary>
        /// <param name="node">The node to get children for</param>
        /// <returns>The children of the node which are in an immutable array</returns>
        private static List <IAbstractSyntaxTreeNode> GetCollectionOfChildNodes(IAbstractSyntaxTreeNode node)
        {
            // Find if there is a property of type ImmutableArray<X>, where X is a kind of node
            IEnumerable childCollection = node.GetType()
                                          .GetProperties()
                                          .Where(property => property.PropertyType.IsGenericType)
                                          .Where(property => property.PropertyType.GetGenericTypeDefinition() == typeof(ImmutableArray <>))
                                          .Where(property => property.PropertyType
                                                 .GetGenericArguments()
                                                 .SingleOrDefault()
                                                 .GetInterfaces()
                                                 .Contains(typeof(IAbstractSyntaxTreeNode)))
                                          .Select(property => property.GetValue(node))
                                          .FirstOrDefault()
                                          as IEnumerable;

            List <IAbstractSyntaxTreeNode> children = new List <IAbstractSyntaxTreeNode>();

            if (childCollection != null)
            {
                foreach (object child in childCollection)
                {
                    children.Add((IAbstractSyntaxTreeNode)child);
                }
            }
            return(children);
        }
Exemple #6
0
 /// <summary>
 /// Gets the children of a node
 /// </summary>
 /// <param name="node">The node to get children for</param>
 /// <returns>The children of the node</returns>
 private static List <IAbstractSyntaxTreeNode> GetChildNodes(IAbstractSyntaxTreeNode node)
 {
     return(node.GetType().GetProperties()
            .Where(property => property.PropertyType
                   .GetInterfaces()
                   .Contains(typeof(IAbstractSyntaxTreeNode)))
            .Select(property => (IAbstractSyntaxTreeNode)property.GetValue(node))
            .ToList());
 }
Exemple #7
0
 /// <summary>
 /// Converts the subtree belonging to a node to a string
 /// </summary>
 /// <param name="lastChild">Whether or not this node is the last child at each parent level of the tree</param>
 /// <param name="node">The node to print</param>
 /// <param name="token">The token associated with the node</param>
 /// <param name="children">The children of the node to print in the desired order</param>
 /// <returns>A string representation of the subtree rooted at the given node</returns>
 private static string GeneralNodeToString(ImmutableList <bool> lastChild, IAbstractSyntaxTreeNode node, Token token, IAbstractSyntaxTreeNode[] children)
 {
     if (node == null)
     {
         return(DrawIndent(lastChild) + "NULL" + System.Environment.NewLine);
     }
     else
     {
         return(DrawIndent(lastChild) +
                GetNodeName(node) +
                (token == null ? "" : $" \"{token.Spelling}\"") +
                GetPropertyString(node) +
                System.Environment.NewLine +
                (children == null ? "" : ChildrenToString(lastChild, children)));
     }
 }
Exemple #8
0
 /// <summary>
 /// Gets a node's properties as a string
 /// </summary>
 /// <param name="node">The node to get the string for</param>
 /// <returns>A string containing type and declaration properties of the node, as appropriate</returns>
 private static string GetPropertyString(IAbstractSyntaxTreeNode node)
 {
     if (node is ITypedNode typedNode)
     {
         if (node is IDeclaredNode declaredNode)
         {
             return(" [" + GetDeclarationString(declaredNode) + ", " + GetTypeString(typedNode) + "]");
         }
         else
         {
             return(" [" + GetTypeString(typedNode) + "]");
         }
     }
     else if (node is IDeclaredNode declaredNode)
     {
         return(" [" + GetDeclarationString(declaredNode) + "]");
     }
     else
     {
         return("");
     }
 }
Exemple #9
0
        /// <summary>
        /// Gets the name of a node
        /// </summary>
        /// <param name="node">The node to get the name of</param>
        /// <returns>A name based on the node's type</returns>
        private static string GetNodeName(IAbstractSyntaxTreeNode node)
        {
            string name = node.GetType().Name;

            return(name.EndsWith("Node") ? name.Substring(0, name.Length - 4) : name);
        }
Exemple #10
0
 /// <summary>
 /// Converts the subtree belonging to a node to a string
 /// </summary>
 /// <param name="lastChild">Whether or not this node is the last child at each parent level of the tree</param>
 /// <param name="node">The node to print</param>
 /// <param name="token">The token associated with the node</param>
 /// <returns>A string representation of the subtree rooted at the given node</returns>
 private static string TerminalNodeToString(ImmutableList <bool> lastChild, IAbstractSyntaxTreeNode node, Token token)
 {
     return(GeneralNodeToString(lastChild, node, token, null));
 }
Exemple #11
0
 /// <summary>
 /// Converts the subtree belonging to a node to a string
 /// </summary>
 /// <param name="lastChild">Whether or not this node is the last child at each parent level of the tree</param>
 /// <param name="node">The node to print</param>
 /// <param name="children">The children of the node to print in the desired order</param>
 /// <returns>A string representation of the subtree rooted at the given node</returns>
 private static string NodeToString(ImmutableList <bool> lastChild, IAbstractSyntaxTreeNode node, params IAbstractSyntaxTreeNode[] children)
 {
     return(GeneralNodeToString(lastChild, node, null, children));
 }
Exemple #12
0
        /// <summary>
        /// Converts the subtree belonging to a node to a string
        /// </summary>
        /// <param name="lastChild">Whether or not this node is the last child at each parent level of the tree</param>
        /// <param name="node">The node to print</param>
        /// <returns>A string representation of the subtree rooted at the given node</returns>
        private static string ToString(ImmutableList <bool> lastChild, IAbstractSyntaxTreeNode node)
        {
            switch (node)
            {
            // Program
            case ProgramNode programNode:
                return(NodeToString(lastChild, programNode, programNode.Command));

            // Commands
            case AssignCommandNode assignCommand:
                return(NodeToString(lastChild, assignCommand, assignCommand.Identifier, assignCommand.Expression));

            case BeginCommandNode beginCommand:
                return(NodeToString(lastChild, beginCommand, beginCommand.Command));

            case CallCommandNode callCommand:
                return(NodeToString(lastChild, callCommand, callCommand.Identifier, callCommand.Parameter));

            case IfCommandNode ifCommand:
                return(NodeToString(lastChild, ifCommand, ifCommand.Expression, ifCommand.ThenCommand));

            case IfElseCommandNode ifElseCommand:
                return(NodeToString(lastChild, ifElseCommand, ifElseCommand.Expression, ifElseCommand.ThenCommand, ifElseCommand.ElseCommand));

            case LetCommandNode letCommand:
                return(NodeToString(lastChild, letCommand, letCommand.Declaration, letCommand.Command));

            case SequentialCommandNode sequentialCommand:
                return(NodeToString(lastChild, sequentialCommand, sequentialCommand.Commands.ToArray()));

            case BlankCommandNode blankCommand:
                return(NodeToString(lastChild, blankCommand));

            case WhileCommandNode whileCommand:
                return(NodeToString(lastChild, whileCommand, whileCommand.Expression, whileCommand.Command));

            case ForCommandNode forCommand:
                return(NodeToString(lastChild, forCommand, forCommand.Assign, forCommand.Expression, forCommand.Command));


            // Declarations
            case ConstDeclarationNode constDeclaration:
                return(NodeToString(lastChild, constDeclaration, constDeclaration.Identifier, constDeclaration.Expression));

            case SequentialDeclarationNode sequentialDeclaration:
                return(NodeToString(lastChild, sequentialDeclaration, sequentialDeclaration.Declarations.ToArray()));

            case VarDeclarationNode varDeclaration:
                return(NodeToString(lastChild, varDeclaration, varDeclaration.TypeDenoter, varDeclaration.Identifier));

            // Expressions
            case BinaryExpressionNode binaryExpression:
                return(NodeToString(lastChild, binaryExpression, binaryExpression.LeftExpression, binaryExpression.Op, binaryExpression.RightExpression));

            case CharacterExpressionNode characterExpression:
                return(NodeToString(lastChild, characterExpression, characterExpression.CharLit));

            case IdExpressionNode idExpression:
                return(NodeToString(lastChild, idExpression, idExpression.Identifier));

            case IntegerExpressionNode integerExpression:
                return(NodeToString(lastChild, integerExpression, integerExpression.IntLit));

            case UnaryExpressionNode unaryExpression:
                return(NodeToString(lastChild, unaryExpression, unaryExpression.Op, unaryExpression.Expression));


            // Parameters
            case EmptyParameterNode blankParameter:
                return(NodeToString(lastChild, blankParameter));

            case ExpressionParameterNode expressionParameter:
                return(NodeToString(lastChild, expressionParameter, expressionParameter.Expression));

            case VarParameterNode varParameter:
                return(NodeToString(lastChild, varParameter, varParameter.Identifier));

            // Types
            case TypeDenoterNode typeDenoter:
                return(NodeToString(lastChild, typeDenoter, typeDenoter.Identifier));

            // Terminals
            case CharacterLiteralNode characterLiteral:
                return(TerminalNodeToString(lastChild, characterLiteral, characterLiteral.CharacterLiteralToken));

            case IdentifierNode identifier:
                return(TerminalNodeToString(lastChild, identifier, identifier.IdentifierToken));

            case IntegerLiteralNode integerLiteral:
                return(TerminalNodeToString(lastChild, integerLiteral, integerLiteral.IntegerLiteralToken));

            case OperatorNode operation:
                return(TerminalNodeToString(lastChild, operation, operation.OperatorToken));

            // Error
            case ErrorNode errorNode:
                return(NodeToString(lastChild, errorNode));

            // Anything without a case written for it ends up here
            default:
                if (node == null)
                {
                    // Null - not a lot we can do
                    Debugger.Write("Tried to print a null tree node");
                    return(NodeToString(lastChild, node));
                }
                else
                {
                    // Use reflection to try to draw node
                    Debugger.Write($"Tried to print an unknown tree node type {node.GetType().Name}");
                    IAbstractSyntaxTreeNode[] children = GetChildNodes(node).Concat(GetCollectionOfChildNodes(node)).ToArray();
                    Token token = GetToken(node);
                    return(GeneralNodeToString(lastChild, node, token, children.Length == 0 ? null : children));
                }
            }
        }
Exemple #13
0
 /// <summary>
 /// Gets a node and its subtree as a string
 /// </summary>
 /// <param name="node">The node to get the string for</param>
 /// <returns>A string representation of the node and its descendents</returns>
 public static string ToString(IAbstractSyntaxTreeNode node)
 {
     return(ToString(ImmutableList <bool> .Empty, node));
 }