예제 #1
0
        // Build a try-catch-finally statement
        public static void BuildExceptionHandler(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var ex = new ExceptionHandler(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(ex);

            // Build the contents of the try block
            parser.ConsumeParseTree(root, ex.Try, currentNode.ChildNodes[0]);

            // Build each case block.
            if (currentNode.ChildNodes[1].ChildNodes.Count > 0)
            {
                foreach (var node in currentNode.ChildNodes[1].ChildNodes)
                {
                    var c = new CatchClause(ex, node.Token.Convert());
                    c.Type = node.ChildNodes[1].FindTokenAndGetText();
                    c.Name = node.ChildNodes[2].FindTokenAndGetText();
                    ex.CatchClauses.Add(c);
                    parser.ConsumeParseTree(root, c, node.ChildNodes[3]);
                }
            }

            // Build the finally block.
            parser.ConsumeParseTree(root, ex.Finally, currentNode.ChildNodes[2]);
        }
예제 #2
0
        // Build a constructor expression.
        public static void BuildConstructor(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var ctor = new Constructor(parentExpression, currentNode.Token.Convert());
            parentExpression.ChildExpressions.Add(ctor);

            // Interpret the declaration modifiers.
            InterpretModifiers(root, ctor, currentNode.ChildNodes[0]);

            // Interpret the arguments of the constructor.
            if (currentNode.ChildNodes[2].ChildNodes.Count > 0)
            {
                foreach (var n in currentNode.ChildNodes[2].ChildNodes)
                {
                    BuildArgument(parser, ctor, n.ChildNodes[0]);
                }
            }

            // Build the "this" or "base" constructors called, if any.
            if(currentNode.ChildNodes[3].ChildNodes.Count > 0)
            {
                if(currentNode.ChildNodes[3].ChildNodes[0].ChildNodes[0].Term.ToString() == "this")
                {
                    ctor.Sub = true;
                }
                foreach (var n in currentNode.ChildNodes[3].ChildNodes[0].ChildNodes[1].ChildNodes)
                {
                    parser.ConsumeParseTree(root, ctor.SubParameters, n);
                }
            }

            // Build the expressions in the method body of the constructor.
            parser.ConsumeParseTree(root, ctor, currentNode.ChildNodes[4]);
        }
예제 #3
0
        // Build an instantiation expression "new foo()"
        public static void BuildInstantiation(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var ist = new Instantiation(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(ist);

            // A non-array instantiation
            if (currentNode.ChildNodes[1].ChildNodes[0].Term.ToString() == "new_instantiate")
            {
                ist.Name = parser.CheckAlias(currentNode.ChildNodes[1].ChildNodes[0].FindTokenAndGetText());

                if (currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[1].ChildNodes.Count > 0)
                {
                    foreach (var n in currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[1].ChildNodes)
                    {
                        ist.GenericTypes.Add(parser.CheckAlias(n.FindTokenAndGetText()));
                    }
                }

                foreach (var n in currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[2].ChildNodes)
                {
                    parser.ConsumeParseTree(root, ist.Parameters, n);
                }
            }
            else // An array instantiation
            {
                ist.IsArray = true;
                ist.Name    = parser.CheckAlias(currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[0].FindTokenAndGetText());

                parser.ConsumeParseTree(root, ist.Parameters, currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[2]);
            }
        }
예제 #4
0
        // Build an instantiation expression "new foo()"
        public static void BuildInstantiation(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var ist = new Instantiation(parentExpression, currentNode.Token.Convert());
            parentExpression.ChildExpressions.Add(ist);

            // A non-array instantiation
            if (currentNode.ChildNodes[1].ChildNodes[0].Term.ToString() == "new_instantiate")
            {

                ist.Name = parser.CheckAlias(currentNode.ChildNodes[1].ChildNodes[0].FindTokenAndGetText());

                if (currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[1].ChildNodes.Count > 0)
                    foreach (var n in currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[1].ChildNodes)
                    {
                        ist.GenericTypes.Add(parser.CheckAlias(n.FindTokenAndGetText()));
                    }

                foreach (var n in currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[2].ChildNodes)
                {
                    parser.ConsumeParseTree(root, ist.Parameters, n);
                }
            }
            else // An array instantiation
            {
                ist.IsArray = true;
                ist.Name = parser.CheckAlias(currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[0].FindTokenAndGetText());

                parser.ConsumeParseTree(root, ist.Parameters, currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[2]);
            }
        }
예제 #5
0
        // Build a constructor expression.
        public static void BuildConstructor(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var ctor = new Constructor(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(ctor);

            // Interpret the declaration modifiers.
            InterpretModifiers(root, ctor, currentNode.ChildNodes[0]);

            // Interpret the arguments of the constructor.
            if (currentNode.ChildNodes[2].ChildNodes.Count > 0)
            {
                foreach (var n in currentNode.ChildNodes[2].ChildNodes)
                {
                    BuildArgument(parser, ctor, n.ChildNodes[0]);
                }
            }

            // Build the "this" or "base" constructors called, if any.
            if (currentNode.ChildNodes[3].ChildNodes.Count > 0)
            {
                if (currentNode.ChildNodes[3].ChildNodes[0].ChildNodes[0].Term.ToString() == "this")
                {
                    ctor.Sub = true;
                }
                foreach (var n in currentNode.ChildNodes[3].ChildNodes[0].ChildNodes[1].ChildNodes)
                {
                    parser.ConsumeParseTree(root, ctor.SubParameters, n);
                }
            }

            // Build the expressions in the method body of the constructor.
            parser.ConsumeParseTree(root, ctor, currentNode.ChildNodes[4]);
        }
예제 #6
0
        // Build property declaration statement
        public static void BuildProperty(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var property = new Property(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(property);

            // If the parent is a module, make the property shared
            var c = parentExpression as Class;

            if (c.IsModule)
            {
                property.IsShared = true;
            }

            // Interpret the modifiers for the property declaration
            InterpretModifiers(root, property, currentNode.ChildNodes[0].ChildNodes[0]);

            // Check for conflicting/invalid property modifiers
            if (property.IsShared && (property.IsFinal || property.IsOverride))
            {
                root.CompilerErrors.Add(new IncompatibleModifiersCompilerError("", currentNode.FindToken().Location.Line,
                                                                               currentNode.FindToken().Location.Position));
            }

            // Find the return type for the property: check if it's generic or an array
            var typeNode = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0];

            if (typeNode.ChildNodes[0].Term.ToString() == "array")
            {
                property.Name     = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText();
                property.TypeName = parser.CheckAlias(typeNode.ChildNodes[0].ChildNodes[0].FindTokenAndGetText()) + "[]";
            }
            else if (typeNode.ChildNodes[0].Term.ToString() == "generic_identifier")
            {
                property.Name     = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText();
                property.TypeName = typeNode.ChildNodes[0].ChildNodes[0].FindTokenAndGetText() + "<";
                for (int i = 0; i < typeNode.ChildNodes[0].ChildNodes[2].ChildNodes.Count; i++)
                {
                    property.TypeName += typeNode.ChildNodes[0].ChildNodes[2].ChildNodes[i].FindTokenAndGetText();
                    if (i < typeNode.ChildNodes[0].ChildNodes[2].ChildNodes.Count - 1)
                    {
                        property.TypeName += ",";
                    }
                }
                property.TypeName += ">";
            }
            else
            {
                property.Name     = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText();
                property.TypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].FindTokenAndGetText());
            }

            // Build the get block for the property
            parser.ConsumeParseTree(root, property.GetBlock, currentNode.ChildNodes[1]);

            // Build the set block for the property
            parser.ConsumeParseTree(root, property.SetBlock, currentNode.ChildNodes[2]);
        }
예제 #7
0
        // Build a while loop statement (a for loop with just the conditional)
        public static void BuildWhileLoop(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var whileLoop = new WhileLoop(parentExpression, currentNode.Token.Convert());
            parentExpression.ChildExpressions.Add(whileLoop);

            // Build the conditional expressoin
            parser.ConsumeParseTree(root, whileLoop.Condition, currentNode.ChildNodes[1]);

            // Build the statements that make up the body of the while loop
            parser.ConsumeParseTree(root, whileLoop, currentNode.ChildNodes[2]);
        }
예제 #8
0
        // Build a while loop statement (a for loop with just the conditional)
        public static void BuildWhileLoop(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var whileLoop = new WhileLoop(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(whileLoop);

            // Build the conditional expressoin
            parser.ConsumeParseTree(root, whileLoop.Condition, currentNode.ChildNodes[1]);

            // Build the statements that make up the body of the while loop
            parser.ConsumeParseTree(root, whileLoop, currentNode.ChildNodes[2]);
        }
예제 #9
0
        // Build a case block statement
        public static void BuildCaseBlock(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var caseBlock = new CaseBlock(parentExpression, currentNode.Token.Convert());
            parentExpression.ChildExpressions.Add(caseBlock);

            // Get the expression being tested against
            parser.ConsumeParseTree(root, caseBlock.Variable, currentNode.ChildNodes[1]);

            // Build the expressions in the body of the case block
            foreach (var e in currentNode.ChildNodes[2].ChildNodes)
                parser.ConsumeParseTree(root, caseBlock, e);
        }
예제 #10
0
        // Build property declaration statement
        public static void BuildProperty(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var property = new Property(parentExpression, currentNode.Token.Convert());
            parentExpression.ChildExpressions.Add(property);

            // If the parent is a module, make the property shared
            var c = parentExpression as Class;
            if (c.IsModule)
            {
                property.IsShared = true;
            }

            // Interpret the modifiers for the property declaration
            InterpretModifiers(root, property, currentNode.ChildNodes[0].ChildNodes[0]);

            // Check for conflicting/invalid property modifiers
            if (property.IsShared && (property.IsFinal || property.IsOverride))
                root.CompilerErrors.Add(new IncompatibleModifiersCompilerError("", currentNode.FindToken().Location.Line,
                    currentNode.FindToken().Location.Position));

            // Find the return type for the property: check if it's generic or an array
            var typeNode = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0];
            if(typeNode.ChildNodes[0].Term.ToString() == "array")
            {
                property.Name = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText();
                property.TypeName = parser.CheckAlias(typeNode.ChildNodes[0].ChildNodes[0].FindTokenAndGetText()) + "[]";
            }
            else if (typeNode.ChildNodes[0].Term.ToString() == "generic_identifier")
            {
                property.Name = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText();
                property.TypeName = typeNode.ChildNodes[0].ChildNodes[0].FindTokenAndGetText() + "<";
                for(int i = 0; i < typeNode.ChildNodes[0].ChildNodes[2].ChildNodes.Count; i++)
                {
                    property.TypeName += typeNode.ChildNodes[0].ChildNodes[2].ChildNodes[i].FindTokenAndGetText();
                    if (i < typeNode.ChildNodes[0].ChildNodes[2].ChildNodes.Count - 1)
                        property.TypeName += ",";
                }
                property.TypeName += ">";
            }
            else
            {
                property.Name = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText();
                property.TypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].FindTokenAndGetText());
            }

            // Build the get block for the property
            parser.ConsumeParseTree(root, property.GetBlock, currentNode.ChildNodes[1]);

            // Build the set block for the property
            parser.ConsumeParseTree(root, property.SetBlock, currentNode.ChildNodes[2]);
        }
예제 #11
0
        // Build a case block statement
        public static void BuildCaseBlock(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var caseBlock = new CaseBlock(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(caseBlock);

            // Get the expression being tested against
            parser.ConsumeParseTree(root, caseBlock.Variable, currentNode.ChildNodes[1]);

            // Build the expressions in the body of the case block
            foreach (var e in currentNode.ChildNodes[2].ChildNodes)
            {
                parser.ConsumeParseTree(root, caseBlock, e);
            }
        }
예제 #12
0
        // Build a method invocation with generic type names
        public static void BuildGenericMethodInvocation(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var methodInvocation = new MethodInvocation(parentExpression, currentNode.FindToken().Convert());

            methodInvocation.Name = currentNode.ChildNodes[0].FindTokenAndGetText();
            parentExpression.ChildExpressions.Add(methodInvocation);
            methodInvocation.ParentExpression = parentExpression;

            // Interpret the generic type names
            if (currentNode.ChildNodes[2].ChildNodes.Count > 0)
            {
                foreach (var n in currentNode.ChildNodes[2].ChildNodes)
                {
                    methodInvocation.GenericTypes.Add(n.FindTokenAndGetText());
                }
            }

            // interpret the expressions that are passed to the invocation as arguments
            if (currentNode.ChildNodes[4].ChildNodes.Count > 0)
            {
                foreach (var n in currentNode.ChildNodes[1].ChildNodes)
                {
                    parser.ConsumeParseTree(root, methodInvocation.Parameters, n);
                }
            }
        }
예제 #13
0
        // Builds a "class" expression: really could be a class, struct, or module.
        public static void BuildClass(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            Class c = new Class(parentExpression, currentNode.FindToken().Convert());
            parentExpression.ChildExpressions.Add(c);

            int i = 0;

            // Interpret the declaration modifiers (abstract, public, internal, etc).
            InterpretClassModifiers( root, c, currentNode.ChildNodes[i]);

            i++;

            // Determine if it's a class, module, or struct.
            switch(currentNode.ChildNodes[i].Term.ToString())
            {
                case "module":
                    c.IsModule = true;
                    c.IsFinal = true;
                    c.IsPartial = true;
                    break;
                case "struct":
                    c.IsStruct = true;
                    c.IsModule = false;
                    break;
                default:
                    c.IsStruct = false;
                    c.IsModule = false;
                    break;
            }

            i++;

            // Class name
            c.UnqualifiedName = currentNode.ChildNodes[i].FindTokenAndGetText();

            i++;

            // Get the generic type list.
            if (currentNode.ChildNodes[i].ChildNodes.Count > 0)
            {
                var generics = currentNode.ChildNodes[i].ChildNodes[0].ChildNodes[1];
                foreach (string s in IronyParser.InterpretList(generics))
                    c.GenericTypeNames.Add(s);
            }

            i++;

            // Get the base type list.
            if (currentNode.ChildNodes[i].ChildNodes.Count > 0)
            {
                var baseTypes = currentNode.ChildNodes[i].ChildNodes[0].ChildNodes[0];
                foreach (string s in IronyParser.InterpretList(baseTypes))
                    c.BaseTypeNames.Add(s);
            }

            i+=1;

            // Build the child expressions of the class.
            parser.ConsumeParseTree(root, c, currentNode.ChildNodes[i]);
        }
예제 #14
0
        // Build an indexed identifier expression (foo[0])
        public static void BuildIndexedIdentifier(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var indexedIdentifier = new IndexedIdentifier(parentExpression, currentNode.Token.Convert());
            parentExpression.ChildExpressions.Add(indexedIdentifier);

            indexedIdentifier.Name = currentNode.ChildNodes[0].FindTokenAndGetText();
            parser.ConsumeParseTree(root, indexedIdentifier, currentNode.ChildNodes[2]);
        }
예제 #15
0
        // Build a namespace expression
        public static void BuildNamespace(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            Namespace n = new Namespace(parentExpression, currentNode.FindToken().Convert());
            n.Name = currentNode.ChildNodes[1].FindTokenAndGetText();
            parentExpression.ChildExpressions.Add(n);

            parser.ConsumeParseTree(root, n, currentNode.ChildNodes[2]);
        }
예제 #16
0
        // Build a throw expression
        public static void BuildThrow(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            Throw e = new Throw(parentExpression, currentNode.FindToken().Convert());

            parentExpression.ChildExpressions.Add(e);
            e.ParentExpression = parentExpression;

            parser.ConsumeParseTree(root, e, currentNode.ChildNodes[1]);
        }
예제 #17
0
        // Build an indexed identifier expression (foo[0])
        public static void BuildIndexedIdentifier(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var indexedIdentifier = new IndexedIdentifier(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(indexedIdentifier);

            indexedIdentifier.Name = currentNode.ChildNodes[0].FindTokenAndGetText();
            parser.ConsumeParseTree(root, indexedIdentifier, currentNode.ChildNodes[2]);
        }
예제 #18
0
        // Build a namespace expression
        public static void BuildNamespace(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            Namespace n = new Namespace(parentExpression, currentNode.FindToken().Convert());

            n.Name = currentNode.ChildNodes[1].FindTokenAndGetText();
            parentExpression.ChildExpressions.Add(n);

            parser.ConsumeParseTree(root, n, currentNode.ChildNodes[2]);
        }
예제 #19
0
        // Build an assignment statement: i = 0, i += 1, i |= foo, etc
        public static void BuildAssignment(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var assignment = new Assignment(parentExpression, currentNode.FindToken().Convert());

            parentExpression.ChildExpressions.Add(assignment);

            // Get the expression being assigned to
            parser.ConsumeParseTree(root, assignment, currentNode.ChildNodes[0]);

            // Determine what kind of assignment this is
            switch (currentNode.ChildNodes[1].FindTokenAndGetText())
            {
            case "=":
                assignment.AssignmentType = AssignmentType.Equal;
                break;

            case "+=":
                assignment.AssignmentType = AssignmentType.Add;
                break;

            case "-=":
                assignment.AssignmentType = AssignmentType.Subtract;
                break;

            case "*=":
                assignment.AssignmentType = AssignmentType.Multiply;
                break;

            case "/=":
                assignment.AssignmentType = AssignmentType.Divide;
                break;

            case "|=":
                assignment.AssignmentType = AssignmentType.Or;
                break;

            case "&=":
                assignment.AssignmentType = AssignmentType.And;
                break;
            }

            // Get the value being assigned.
            parser.ConsumeParseTree(root, assignment, currentNode.ChildNodes[2]);
        }
예제 #20
0
        // Build an if conditional statement.
        public static void BuildIfBlock(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var i = new IfBlock(parentExpression, currentNode.FindToken().Convert());
            parentExpression.ChildExpressions.Add(i);

            int c = 1;

            // Build the conditional expression
            parser.ConsumeParseTree(root, i.Conditional, currentNode.ChildNodes[c]);

            c++;

            // Build the true block
            parser.ConsumeParseTree(root, i.TrueBlock, currentNode.ChildNodes[c]);

            c++;

            // Build the false block if one exists.
            if(currentNode.ChildNodes[c].ChildNodes.Count != 0)
                parser.ConsumeParseTree(root, i.FalseBlock, currentNode.ChildNodes[c]);
        }
예제 #21
0
        // Build a switch block statement
        public static void BuildSwitchBlock(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var s = new SwitchBlock(parentExpression, currentNode.Token.Convert());
            parentExpression.ChildExpressions.Add(s);

            // Get the expression being tested
            parser.ConsumeParseTree(root, s.Variable, currentNode.ChildNodes[1]);

            // Build each case block
            if(currentNode.ChildNodes[2].ChildNodes.Count > 0)
                foreach(var node in currentNode.ChildNodes[2].ChildNodes[0].ChildNodes)
                    BuildCaseBlock(parser, root, s, node);
        }
예제 #22
0
        // Build an assignment statement: i = 0, i += 1, i |= foo, etc
        public static void BuildAssignment(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var assignment = new Assignment(parentExpression, currentNode.FindToken().Convert());
            parentExpression.ChildExpressions.Add(assignment);

            // Get the expression being assigned to
            parser.ConsumeParseTree(root, assignment, currentNode.ChildNodes[0]);

            // Determine what kind of assignment this is
            switch(currentNode.ChildNodes[1].FindTokenAndGetText())
            {
                case "=":
                    assignment.AssignmentType = AssignmentType.Equal;
                    break;
                case "+=":
                    assignment.AssignmentType = AssignmentType.Add;
                    break;
                case "-=":
                    assignment.AssignmentType = AssignmentType.Subtract;
                    break;
                case "*=":
                    assignment.AssignmentType = AssignmentType.Multiply;
                    break;
                case "/=":
                    assignment.AssignmentType = AssignmentType.Divide;
                    break;
                case "|=":
                    assignment.AssignmentType = AssignmentType.Or;
                    break;
                case "&=":
                    assignment.AssignmentType = AssignmentType.And;
                    break;
            }

            // Get the value being assigned.
            parser.ConsumeParseTree(root, assignment, currentNode.ChildNodes[2]);
        }
예제 #23
0
        // Build an if conditional statement.
        public static void BuildIfBlock(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var i = new IfBlock(parentExpression, currentNode.FindToken().Convert());

            parentExpression.ChildExpressions.Add(i);

            int c = 1;

            // Build the conditional expression
            parser.ConsumeParseTree(root, i.Conditional, currentNode.ChildNodes[c]);

            c++;

            // Build the true block
            parser.ConsumeParseTree(root, i.TrueBlock, currentNode.ChildNodes[c]);

            c++;

            // Build the false block if one exists.
            if (currentNode.ChildNodes[c].ChildNodes.Count != 0)
            {
                parser.ConsumeParseTree(root, i.FalseBlock, currentNode.ChildNodes[c]);
            }
        }
예제 #24
0
        // Build a method invocation statement (foo(1))
        public static void BuildMethodInvocation(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var methodInvocation = new MethodInvocation(parentExpression, currentNode.FindToken().Convert());
            methodInvocation.Name = currentNode.ChildNodes[0].FindTokenAndGetText();
            parentExpression.ChildExpressions.Add(methodInvocation);

            // interpret the expressions that are passed to the invocation as arguments
            if (currentNode.ChildNodes[1].ChildNodes.Count > 0)
            {
                foreach (var n in currentNode.ChildNodes[1].ChildNodes)
                {
                    parser.ConsumeParseTree(root, methodInvocation.Parameters, n);

                }
            }
        }
예제 #25
0
        // Build an interface expression.
        public static void BuildInterface(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var inter = new Interface(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(inter);

            int i = 0;

            // Find modifiers for the declaration
            InterpretModifiers(root, inter, currentNode.ChildNodes[i]);

            i++;

            i++;

            // get interface name
            inter.UnqualifiedName = currentNode.ChildNodes[i].FindTokenAndGetText();

            i++;

            // Build the generic type list
            if (currentNode.ChildNodes[i].ChildNodes.Count > 0)
            {
                var generics = currentNode.ChildNodes[i].ChildNodes[0].ChildNodes[1];
                foreach (string s in IronyParser.InterpretList(generics))
                {
                    inter.GenericTypeNames.Add(s);
                }
            }

            i++;

            // Build the base type list.
            if (currentNode.ChildNodes[i].ChildNodes.Count > 0)
            {
                var baseTypes = currentNode.ChildNodes[i].ChildNodes[0].ChildNodes[0];
                foreach (string s in IronyParser.InterpretList(baseTypes))
                {
                    inter.BaseTypeNames.Add(s);
                }
            }

            i += 1;

            // Build the children of the interface
            parser.ConsumeParseTree(root, inter, currentNode.ChildNodes[i]);
        }
예제 #26
0
        public static void BuildUnaryOperator(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var op = new UnaryOperator(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(op);
            switch (currentNode.ChildNodes[0].FindTokenAndGetText())
            {
            case "!":
                op.OperatorType = UnaryOperatorType.Not;
                break;

            case "-":
                op.OperatorType = UnaryOperatorType.Negate;
                break;
            }
            parser.ConsumeParseTree(root, op, currentNode.ChildNodes[1]);
        }
예제 #27
0
        // Build a switch block statement
        public static void BuildSwitchBlock(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var s = new SwitchBlock(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(s);

            // Get the expression being tested
            parser.ConsumeParseTree(root, s.Variable, currentNode.ChildNodes[1]);

            // Build each case block
            if (currentNode.ChildNodes[2].ChildNodes.Count > 0)
            {
                foreach (var node in currentNode.ChildNodes[2].ChildNodes[0].ChildNodes)
                {
                    BuildCaseBlock(parser, root, s, node);
                }
            }
        }
예제 #28
0
        // Build a for loop statement.
        public static void BuildForLoop(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var loop = new ForLoop(parentExpression, currentNode.Token.Convert());

            parentExpression.ChildExpressions.Add(loop);

            // Build the initializer expression for the loop.
            parser.ConsumeParseTree(root, loop.Initialization, currentNode.ChildNodes[1]);

            // Build the conditional expression for the loop.
            switch (currentNode.ChildNodes[3].ChildNodes[0].Term.ToString())
            {
            case "for_range":
                parser.ConsumeParseTree(root, loop.Condition, currentNode.ChildNodes[3].ChildNodes[0].ChildNodes[0]);
                parser.ConsumeParseTree(root, loop.Condition, currentNode.ChildNodes[3].ChildNodes[0].ChildNodes[2]);
                break;

            default:
                parser.ConsumeParseTree(root, loop.Condition, currentNode.ChildNodes[3].ChildNodes[0]);
                break;
            }

            // Build the increment/decrement step expression for the loop.
            if (currentNode.ChildNodes[4].ChildNodes.Count > 0)
            {
                parser.ConsumeParseTree(root, loop.Step, currentNode.ChildNodes[4]);
            }
            else
            {
                var literal = new Literal(loop, null);
                literal.Value = 1;
                loop.Step.ChildExpressions.Add(literal);
            }

            // Form the body of the loop.
            if (currentNode.ChildNodes[5].ChildNodes.Count > 0)
            {
                parser.ConsumeParseTree(root, loop, currentNode.ChildNodes[5]);
            }
        }
예제 #29
0
        // Build a for loop statement.
        public static void BuildForLoop(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var loop = new ForLoop(parentExpression, currentNode.Token.Convert());
            parentExpression.ChildExpressions.Add(loop);

            // Build the initializer expression for the loop.
            parser.ConsumeParseTree(root, loop.Initialization, currentNode.ChildNodes[1]);

            // Build the conditional expression for the loop.
            switch(currentNode.ChildNodes[3].ChildNodes[0].Term.ToString())
            {
                case "for_range":
                    parser.ConsumeParseTree(root, loop.Condition, currentNode.ChildNodes[3].ChildNodes[0].ChildNodes[0]);
                    parser.ConsumeParseTree(root, loop.Condition, currentNode.ChildNodes[3].ChildNodes[0].ChildNodes[2]);
                    break;
                default:
                    parser.ConsumeParseTree(root, loop.Condition, currentNode.ChildNodes[3].ChildNodes[0]);
                    break;
            }

            // Build the increment/decrement step expression for the loop.
            if(currentNode.ChildNodes[4].ChildNodes.Count > 0)
            {
                parser.ConsumeParseTree(root, loop.Step, currentNode.ChildNodes[4]);
            }
            else
            {
                var literal = new Literal(loop, null);
                literal.Value = 1;
                loop.Step.ChildExpressions.Add(literal);
            }

            // Form the body of the loop.
            if(currentNode.ChildNodes[5].ChildNodes.Count > 0)
            {
                parser.ConsumeParseTree(root, loop, currentNode.ChildNodes[5]);
            }
        }
예제 #30
0
 public static void BuildUnaryOperator(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
 {
     var op = new UnaryOperator(parentExpression, currentNode.Token.Convert());
     parentExpression.ChildExpressions.Add(op);
     switch(currentNode.ChildNodes[0].FindTokenAndGetText())
     {
         case "!":
             op.OperatorType = UnaryOperatorType.Not;
             break;
         case "-":
             op.OperatorType = UnaryOperatorType.Negate;
             break;
     }
     parser.ConsumeParseTree(root, op, currentNode.ChildNodes[1]);
 }
예제 #31
0
        // Build a binary operator statement
        public static void BuildBinaryOperator(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var op = new BinaryOperator(parentExpression, currentNode.FindToken().Convert());

            parentExpression.ChildExpressions.Add(op);

            // Determine which binary operator this is
            switch (currentNode.ChildNodes[1].Term.ToString())
            {
            case "*":
                op.OperatorType = BinaryOperatorType.Multiply;
                break;

            case "/":
                op.OperatorType = BinaryOperatorType.Divide;
                break;

            case "+":
                op.OperatorType = BinaryOperatorType.Add;
                break;

            case "-":
                op.OperatorType = BinaryOperatorType.Subtract;
                break;

            case "%":
                op.OperatorType = BinaryOperatorType.Modulo;
                break;

            case "<=":
                op.OperatorType = BinaryOperatorType.LessOrEqual;
                break;

            case "<":
                op.OperatorType = BinaryOperatorType.Less;
                break;

            case "==":
                op.OperatorType = BinaryOperatorType.Equal;
                break;

            case "!=":
                op.OperatorType = BinaryOperatorType.NotEqual;
                break;

            case ">=":
                op.OperatorType = BinaryOperatorType.GreaterOrEqual;
                break;

            case ">":
                op.OperatorType = BinaryOperatorType.Greater;
                break;

            case ">>":
                op.OperatorType = BinaryOperatorType.BitwiseShiftRight;
                break;

            case "<<":
                op.OperatorType = BinaryOperatorType.BitwiseShiftLeft;
                break;

            case "&&":
                op.OperatorType = BinaryOperatorType.LogicalAnd;
                break;

            case "||":
                op.OperatorType = BinaryOperatorType.LogicalOr;
                break;

            case "|":
                op.OperatorType = BinaryOperatorType.BitwiseOr;
                break;

            case "&":
                op.OperatorType = BinaryOperatorType.BitwiseAnd;
                break;

            case "^":
                op.OperatorType = BinaryOperatorType.BitwiseXor;
                break;

            case "as":
                op.OperatorType = BinaryOperatorType.As;
                break;
            }

            // Get the left operand
            parser.ConsumeParseTree(root, op, currentNode.ChildNodes[0]);

            // "as" operator is a type case and needs to be handled differently
            if (op.OperatorType == BinaryOperatorType.As)
            {
                var v = new VariableReference(op, null);
                v.Name = currentNode.ChildNodes[2].ChildNodes[0].FindTokenAndGetText();
                op.ChildExpressions.Add(v);
            }
            else
            {
                parser.ConsumeParseTree(root, op, currentNode.ChildNodes[2]);
            }
        }
예제 #32
0
        // Builds a "class" expression: really could be a class, struct, or module.
        public static void BuildClass(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            Class c = new Class(parentExpression, currentNode.FindToken().Convert());

            parentExpression.ChildExpressions.Add(c);

            int i = 0;

            // Interpret the declaration modifiers (abstract, public, internal, etc).
            InterpretClassModifiers(root, c, currentNode.ChildNodes[i]);

            i++;

            // Determine if it's a class, module, or struct.
            switch (currentNode.ChildNodes[i].Term.ToString())
            {
            case "module":
                c.IsModule  = true;
                c.IsFinal   = true;
                c.IsPartial = true;
                break;

            case "struct":
                c.IsStruct = true;
                c.IsModule = false;
                break;

            default:
                c.IsStruct = false;
                c.IsModule = false;
                break;
            }

            i++;

            // Class name
            c.UnqualifiedName = currentNode.ChildNodes[i].FindTokenAndGetText();

            i++;

            // Get the generic type list.
            if (currentNode.ChildNodes[i].ChildNodes.Count > 0)
            {
                var generics = currentNode.ChildNodes[i].ChildNodes[0].ChildNodes[1];
                foreach (string s in IronyParser.InterpretList(generics))
                {
                    c.GenericTypeNames.Add(s);
                }
            }

            i++;

            // Get the base type list.
            if (currentNode.ChildNodes[i].ChildNodes.Count > 0)
            {
                var baseTypes = currentNode.ChildNodes[i].ChildNodes[0].ChildNodes[0];
                foreach (string s in IronyParser.InterpretList(baseTypes))
                {
                    c.BaseTypeNames.Add(s);
                }
            }

            i += 1;

            // Build the child expressions of the class.
            parser.ConsumeParseTree(root, c, currentNode.ChildNodes[i]);
        }
예제 #33
0
        // Build a method declaration expression
        public static void BuildMethodDeclaration(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            MethodDeclaration e = new MethodDeclaration(parentExpression, currentNode.FindToken().Convert());

            parentExpression.ChildExpressions.Add(e);

            int i = 0;

            // Set default modifiers
            var c = parentExpression as Class;

            if (c.IsModule) // If the parent is a module, set the method to shared.
            {
                e.IsShared = true;
            }

            // Interpret the modifiers for the method declaration
            InterpretModifiers(root, e, currentNode.ChildNodes[0].ChildNodes[0]);

            if (e.IsShared && (e.IsFinal || e.IsOverride))
            {
                root.CompilerErrors.Add(new IncompatibleModifiersCompilerError("", currentNode.FindToken().Location.Line,
                                                                               currentNode.FindToken().Location.Position));
            }

            i += 1; // skip the def

            // Interpret the return type name: check if it's an array, generic, or simple type name
            if (currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].Term.ToString() == "array")
            {
                e.Name           = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText();
                e.ReturnTypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].FindTokenAndGetText()) + "[]";
            }
            else if (currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].Term.ToString() == "generic_identifier")
            {
                var genericNode = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0];
                e.Name           = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText());
                e.ReturnTypeName = parser.CheckAlias(genericNode.ChildNodes[0].FindTokenAndGetText()) + "<";
                for (int n = 0; n < genericNode.ChildNodes[2].ChildNodes.Count; n++)
                {
                    e.ReturnTypeName += parser.CheckAlias(genericNode.ChildNodes[2].ChildNodes[n].FindTokenAndGetText());
                    if (n < genericNode.ChildNodes[2].ChildNodes.Count - 1)
                    {
                        e.ReturnTypeName += ",";
                    }
                }
                e.ReturnTypeName += ">";
            }
            else
            {
                e.Name           = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText();
                e.ReturnTypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].FindTokenAndGetText());
            }

            i++;

            i++;

            // Add the generic type names for the method declaration
            if (currentNode.ChildNodes[1].ChildNodes.Count > 0)
            {
                var generics = currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[1];
                foreach (string s in IronyParser.InterpretList(generics))
                {
                    e.GenericTypeNames.Add(s);
                }
            }

            i += 1;

            // add the arguments for the method declaration
            if (currentNode.ChildNodes[2].ChildNodes.Count > 0)
            {
                foreach (var n in currentNode.ChildNodes[2].ChildNodes)
                {
                    BuildArgument(parser, e, n.ChildNodes[0]);
                }
            }

            // Build the body of statements in the method declaration
            parser.ConsumeParseTree(root, e, currentNode.ChildNodes[3]);
        }
예제 #34
0
        // Build a method declaration expression
        public static void BuildMethodDeclaration(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            MethodDeclaration e = new MethodDeclaration(parentExpression, currentNode.FindToken().Convert());
            parentExpression.ChildExpressions.Add(e);

            int i = 0;

            // Set default modifiers
            var c = parentExpression as Class;
            if(c.IsModule) // If the parent is a module, set the method to shared.
            {
                e.IsShared = true;
            }

            // Interpret the modifiers for the method declaration
            InterpretModifiers(root, e, currentNode.ChildNodes[0].ChildNodes[0]);

            if(e.IsShared && (e.IsFinal || e.IsOverride))
                root.CompilerErrors.Add(new IncompatibleModifiersCompilerError("", currentNode.FindToken().Location.Line,
                    currentNode.FindToken().Location.Position));

            i+=1; // skip the def

            // Interpret the return type name: check if it's an array, generic, or simple type name
            if (currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].Term.ToString() == "array")
            {
                e.Name = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText();
                e.ReturnTypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].FindTokenAndGetText()) + "[]";
            }
            else if (currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].Term.ToString() == "generic_identifier")
            {
                var genericNode = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0];
                e.Name = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText());
                e.ReturnTypeName = parser.CheckAlias(genericNode.ChildNodes[0].FindTokenAndGetText()) + "<";
                for(int n = 0; n < genericNode.ChildNodes[2].ChildNodes.Count; n++)
                {
                    e.ReturnTypeName += parser.CheckAlias(genericNode.ChildNodes[2].ChildNodes[n].FindTokenAndGetText());
                    if(n < genericNode.ChildNodes[2].ChildNodes.Count - 1)
                        e.ReturnTypeName += ",";
                }
                e.ReturnTypeName += ">";
            }
            else
            {
                e.Name = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText();
                e.ReturnTypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].FindTokenAndGetText());
            }

            i++;

            i++;

            // Add the generic type names for the method declaration
            if (currentNode.ChildNodes[1].ChildNodes.Count > 0)
            {
                var generics = currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[1];
                foreach (string s in IronyParser.InterpretList(generics))
                    e.GenericTypeNames.Add(s);
            }

            i+=1;

            // add the arguments for the method declaration
            if (currentNode.ChildNodes[2].ChildNodes.Count > 0)
            {
                foreach (var n in currentNode.ChildNodes[2].ChildNodes)
                {
                    BuildArgument(parser, e, n.ChildNodes[0]);
                }
            }

            // Build the body of statements in the method declaration
            parser.ConsumeParseTree(root, e, currentNode.ChildNodes[3]);
        }
예제 #35
0
        // Build a binary operator statement
        public static void BuildBinaryOperator(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode)
        {
            var op = new BinaryOperator(parentExpression, currentNode.FindToken().Convert());
            parentExpression.ChildExpressions.Add(op);

            // Determine which binary operator this is
            switch (currentNode.ChildNodes[1].Term.ToString())
            {
                case "*":
                    op.OperatorType = BinaryOperatorType.Multiply;
                    break;
                case "/":
                    op.OperatorType = BinaryOperatorType.Divide;
                    break;
                case "+":
                    op.OperatorType = BinaryOperatorType.Add;
                    break;
                case "-":
                    op.OperatorType = BinaryOperatorType.Subtract;
                    break;
                case "%":
                    op.OperatorType = BinaryOperatorType.Modulo;
                    break;
                case "<=":
                    op.OperatorType = BinaryOperatorType.LessOrEqual;
                    break;
                case "<":
                    op.OperatorType = BinaryOperatorType.Less;
                    break;
                case "==":
                    op.OperatorType = BinaryOperatorType.Equal;
                    break;
                case "!=":
                    op.OperatorType = BinaryOperatorType.NotEqual;
                    break;
                case ">=":
                    op.OperatorType = BinaryOperatorType.GreaterOrEqual;
                    break;
                case ">":
                    op.OperatorType = BinaryOperatorType.Greater;
                    break;
                case ">>":
                    op.OperatorType = BinaryOperatorType.BitwiseShiftRight;
                    break;
                case "<<":
                    op.OperatorType = BinaryOperatorType.BitwiseShiftLeft;
                    break;
                case "&&":
                    op.OperatorType = BinaryOperatorType.LogicalAnd;
                    break;
                case "||":
                    op.OperatorType = BinaryOperatorType.LogicalOr;
                    break;
                case "|":
                    op.OperatorType = BinaryOperatorType.BitwiseOr;
                    break;
                case "&":
                    op.OperatorType = BinaryOperatorType.BitwiseAnd;
                    break;
                case "^":
                    op.OperatorType = BinaryOperatorType.BitwiseXor;
                    break;
                case "as":
                    op.OperatorType = BinaryOperatorType.As;
                    break;
            }

            // Get the left operand
            parser.ConsumeParseTree(root, op, currentNode.ChildNodes[0]);

            // "as" operator is a type case and needs to be handled differently
            if(op.OperatorType == BinaryOperatorType.As)
            {
                var v = new VariableReference(op, null);
                v.Name = currentNode.ChildNodes[2].ChildNodes[0].FindTokenAndGetText();
                op.ChildExpressions.Add(v);
            }
            else
                parser.ConsumeParseTree(root, op, currentNode.ChildNodes[2]);
        }