// Build a simple return statement that does not return a value. void BuildReturn(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { Return e = new Return(parentExpression, currentNode.FindToken().Convert()); parentExpression.ChildExpressions.Add(e); e.ParentExpression = parentExpression; }
// Builds an argument for the constructor. public static void BuildArgument(IronyParser parser, Constructor method, ParseTreeNode node) { // Check for a directioned argument (out, ref). if (node.Term.ToString() == "out_parameter") { var a = new DirectionedParameter(null, node.FindToken().Convert()); switch (node.ChildNodes[0].ChildNodes[0].Term.ToString()) { case "ref": a.Direction = ParameterDirection.Ref; break; case "out": a.Direction = ParameterDirection.Out; break; } a.TypeName = parser.CheckAlias(node.ChildNodes[1].FindTokenAndGetText()); a.Name = node.ChildNodes[2].FindTokenAndGetText(); method.Parameters.Add(a); } else { // Build an undirectioned argument. var a = new SimpleParameter(null, node.FindToken().Convert()); a.TypeName = parser.CheckAlias(node.ChildNodes[0].FindTokenAndGetText()); a.Name = node.ChildNodes[1].FindTokenAndGetText(); method.Parameters.Add(a); } }
// 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]); } }
// 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]); }
// 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]); }
// Build a null literal public static void BuildNullLiteral(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var e = new Literal(parentExpression, currentNode.FindToken().Convert()); parentExpression.ChildExpressions.Add(e); e.Value = null; }
// 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]); } }
// 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); } } }
// Build an interface method declaration. public static void BuildInterfaceMethod(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var method = new MethodDeclaration(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(method); // Build the return type of the interface method. method.ReturnTypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].FindTokenAndGetText()); // The name of the interface method. method.Name = currentNode.ChildNodes[0].ChildNodes[1].FindTokenAndGetText(); // Build the list of generic type names. if (currentNode.ChildNodes[1].ChildNodes.Count > 0) { var generics = currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[1]; foreach (string s in IronyParser.InterpretList(generics)) { method.GenericTypeNames.Add(parser.CheckAlias(s)); } } // Build the arguments of the method if (currentNode.ChildNodes[2].ChildNodes.Count > 0) { foreach (var n in currentNode.ChildNodes[2].ChildNodes) { MethodDeclarationBuilder.BuildArgument(parser, method, n.ChildNodes[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]); }
// Build an interface method declaration. public static void BuildInterfaceMethod(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var method = new MethodDeclaration(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(method); // Build the return type of the interface method. method.ReturnTypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].FindTokenAndGetText()); // The name of the interface method. method.Name = currentNode.ChildNodes[0].ChildNodes[1].FindTokenAndGetText(); // Build the list of generic type names. if (currentNode.ChildNodes[1].ChildNodes.Count > 0) { var generics = currentNode.ChildNodes[1].ChildNodes[0].ChildNodes[1]; foreach (string s in IronyParser.InterpretList(generics)) method.GenericTypeNames.Add(parser.CheckAlias(s)); } // Build the arguments of the method if (currentNode.ChildNodes[2].ChildNodes.Count > 0) { foreach (var n in currentNode.ChildNodes[2].ChildNodes) { MethodDeclarationBuilder.BuildArgument(parser, method, n.ChildNodes[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]); }
// Build an interface property declaration public static void BuildInterfaceProperty(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var property = new Property(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(property); property.TypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].FindTokenAndGetText()); property.Name = currentNode.ChildNodes[0].ChildNodes[1].FindTokenAndGetText(); }
// 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]); }
// 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]); }
// Build a variable reference (the "v" in "v = 1" void BuildVariableReference(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var e = new VariableReference(parentExpression, currentNode.FindToken().Convert()); e.Name = currentNode.FindTokenAndGetText(); e.ParentExpression = parentExpression; parentExpression.ChildExpressions.Add(e); }
// Build a number, string, or character literal: v = 1234 public static void BuildLiteral(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var e = new Literal(parentExpression, currentNode.FindToken().Convert()); parentExpression.ChildExpressions.Add(e); e.ParentExpression = parentExpression; e.Value = currentNode.Token.Value; }
// 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]); }
// 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]); }
// Build an import expression: one for each name imported. public static void BuildImport(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { foreach (var node in currentNode.ChildNodes[1].ChildNodes) { var i = new Import(parentExpression, currentNode.FindToken().Convert()); parentExpression.ChildExpressions.Add(i); i.ParentExpression = parentExpression; i.Name = node.FindTokenAndGetText(); } }
// Build an event declaration. public static void BuildEvent(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var e = new Event(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(e); InterpretModifiers(root, e, currentNode.ChildNodes[0]); e.DelegateName = currentNode.ChildNodes[2].ChildNodes[0].FindTokenAndGetText(); e.Name = currentNode.ChildNodes[2].ChildNodes[1].FindTokenAndGetText(); }
// Build a boolean literal: v = true public static void BuildBoolLiteral(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var e = new Literal(parentExpression, currentNode.FindToken().Convert()); parentExpression.ChildExpressions.Add(e); e.ParentExpression = parentExpression; if (currentNode.ChildNodes[0].FindTokenAndGetText() == "true") e.Value = true; else e.Value = false; }
// 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]); }
// 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); }
// 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); }
// 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]); }
// Build the arguments of the delegate declaration. public static void BuildArgument(IronyParser parser, DelegateDeclaration method, ParseTreeNode node) { if (node.Term.ToString() == "out_parameter") { var a = new DirectionedParameter(null, node.FindToken().Convert()); switch (node.ChildNodes[0].ChildNodes[0].Term.ToString()) { case "ref": a.Direction = ParameterDirection.Ref; break; case "out": a.Direction = ParameterDirection.Out; break; } a.TypeName = parser.CheckAlias(node.ChildNodes[1].FindTokenAndGetText()); a.Name = node.ChildNodes[2].FindTokenAndGetText(); method.Parameters.Add(a); } else if (node.Term.ToString() == "array_parameter") { var a = new SimpleParameter(null, node.FindToken().Convert()); a.TypeName = parser.CheckAlias(node.ChildNodes[0].FindTokenAndGetText()) + "[]"; a.Name = node.ChildNodes[3].FindTokenAndGetText(); method.Parameters.Add(a); } else if (node.Term.ToString() == "generic_parameter") { var a = new SimpleParameter(null, node.FindToken().Convert()); string typeName = node.ChildNodes[0].ChildNodes[0].FindTokenAndGetText() + "<"; for (int i = 0; i < node.ChildNodes[0].ChildNodes[2].ChildNodes.Count; i++) { typeName += parser.CheckAlias(node.ChildNodes[0].ChildNodes[2].ChildNodes[i].FindTokenAndGetText()); if (i < node.ChildNodes[0].ChildNodes[2].ChildNodes.Count - 1) { typeName += ","; } } typeName += ">"; a.TypeName = typeName; a.Name = node.ChildNodes[1].FindTokenAndGetText(); method.Parameters.Add(a); } else { var a = new SimpleParameter(null, node.FindToken().Convert()); a.TypeName = parser.CheckAlias(node.ChildNodes[0].FindTokenAndGetText()); a.Name = node.ChildNodes[1].FindTokenAndGetText(); method.Parameters.Add(a); } }
// Build a class variable expression. public static void BuildClassVariable(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { ClassVariable c = new ClassVariable(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(c); // Set default modifiers var p = parentExpression as Class; if (p.IsModule) { c.IsShared = true; } if (p.IsStruct) { c.Accessibility = Accessibility.Public; } // Interpret declaration modifiers (shared, public, etc). InterpretClassVariableModifiers(root, c, currentNode.ChildNodes[0].ChildNodes[0]); // Treat array type and generic type declarations differently. if (currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].Term.ToString() == "array") { c.TypeName = 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]; c.Name = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText()); c.TypeName = parser.CheckAlias(genericNode.ChildNodes[0].FindTokenAndGetText()) + "<"; for (int n = 0; n < genericNode.ChildNodes[2].ChildNodes.Count; n++) { c.TypeName += parser.CheckAlias(genericNode.ChildNodes[2].ChildNodes[n].FindTokenAndGetText()); if (n < genericNode.ChildNodes[2].ChildNodes.Count - 1) { c.TypeName += ","; } } c.TypeName += ">"; } else { c.TypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].FindTokenAndGetText()); } // Get the variable name. c.Name = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText(); }
// Build the arguments of the delegate declaration. public static void BuildArgument(IronyParser parser, DelegateDeclaration method, ParseTreeNode node) { if (node.Term.ToString() == "out_parameter") { var a = new DirectionedParameter(null, node.FindToken().Convert()); switch (node.ChildNodes[0].ChildNodes[0].Term.ToString()) { case "ref": a.Direction = ParameterDirection.Ref; break; case "out": a.Direction = ParameterDirection.Out; break; } a.TypeName = parser.CheckAlias(node.ChildNodes[1].FindTokenAndGetText()); a.Name = node.ChildNodes[2].FindTokenAndGetText(); method.Parameters.Add(a); } else if (node.Term.ToString() == "array_parameter") { var a = new SimpleParameter(null, node.FindToken().Convert()); a.TypeName = parser.CheckAlias(node.ChildNodes[0].FindTokenAndGetText()) + "[]"; a.Name = node.ChildNodes[3].FindTokenAndGetText(); method.Parameters.Add(a); } else if(node.Term.ToString() == "generic_parameter") { var a = new SimpleParameter(null, node.FindToken().Convert()); string typeName = node.ChildNodes[0].ChildNodes[0].FindTokenAndGetText() + "<"; for (int i = 0; i < node.ChildNodes[0].ChildNodes[2].ChildNodes.Count; i++ ) { typeName += parser.CheckAlias(node.ChildNodes[0].ChildNodes[2].ChildNodes[i].FindTokenAndGetText()); if (i < node.ChildNodes[0].ChildNodes[2].ChildNodes.Count - 1) typeName += ","; } typeName += ">"; a.TypeName = typeName; a.Name = node.ChildNodes[1].FindTokenAndGetText(); method.Parameters.Add(a); } else { var a = new SimpleParameter(null, node.FindToken().Convert()); a.TypeName = parser.CheckAlias(node.ChildNodes[0].FindTokenAndGetText()); a.Name = node.ChildNodes[1].FindTokenAndGetText(); method.Parameters.Add(a); } }
// 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); } }
// 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); } } }
// Build a boolean literal: v = true public static void BuildBoolLiteral(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var e = new Literal(parentExpression, currentNode.FindToken().Convert()); parentExpression.ChildExpressions.Add(e); e.ParentExpression = parentExpression; if (currentNode.ChildNodes[0].FindTokenAndGetText() == "true") { e.Value = true; } else { e.Value = false; } }
// 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]); }
// Build an argument with a direction: out or ref void BuildDirectionedArgument(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { DirectionedArgument o = new DirectionedArgument(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(o); switch (currentNode.ChildNodes[0].FindTokenAndGetText()) { case "out": o.Direction = ParameterDirection.Out; break; case "ref": o.Direction = ParameterDirection.Ref; break; } o.Name = currentNode.ChildNodes[1].FindTokenAndGetText(); }
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]); }
// Build a delegate declaration expression. public static void BuildDelegate(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var d = new DelegateDeclaration(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(d); // Interpret the declaration modifiers. InterpretModifiers(root, d, currentNode.ChildNodes[0]); // Find the return type of the declaration: check for array and generic types differently. if (currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].Term.ToString() == "array") { d.ReturnTypeName = parser.CheckAlias(currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].FindTokenAndGetText()) + "[]"; } else if (currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].Term.ToString() == "generic_identifier") { string returnType = currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].ChildNodes[0].FindTokenAndGetText() + "<"; for (int i = 0; i < currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].ChildNodes[2].ChildNodes.Count; i++) { var genericNode = currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].ChildNodes[2].ChildNodes[i]; returnType += parser.CheckAlias(genericNode.FindTokenAndGetText()); if (i < currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].ChildNodes[2].ChildNodes.Count - 1) { returnType += ","; } } returnType += ">"; d.ReturnTypeName = returnType; } else { d.ReturnTypeName = parser.CheckAlias(currentNode.ChildNodes[2].ChildNodes[0].FindTokenAndGetText()); } d.Name = currentNode.ChildNodes[2].ChildNodes[1].FindTokenAndGetText(); // Build the arguments of the delegate declaration. if (currentNode.ChildNodes[3].ChildNodes.Count > 0) { foreach (var n in currentNode.ChildNodes[3].ChildNodes) { BuildArgument(parser, d, n.ChildNodes[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); } } }
// 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]); }
// Build a class variable expression. public static void BuildClassVariable(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { ClassVariable c = new ClassVariable(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(c); // Set default modifiers var p = parentExpression as Class; if (p.IsModule) { c.IsShared = true; } if (p.IsStruct) c.Accessibility = Accessibility.Public; // Interpret declaration modifiers (shared, public, etc). InterpretClassVariableModifiers(root, c, currentNode.ChildNodes[0].ChildNodes[0]); // Treat array type and generic type declarations differently. if (currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].ChildNodes[0].Term.ToString() == "array") { c.TypeName = 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]; c.Name = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText()); c.TypeName = parser.CheckAlias(genericNode.ChildNodes[0].FindTokenAndGetText()) + "<"; for (int n = 0; n < genericNode.ChildNodes[2].ChildNodes.Count; n++) { c.TypeName += parser.CheckAlias(genericNode.ChildNodes[2].ChildNodes[n].FindTokenAndGetText()); if (n < genericNode.ChildNodes[2].ChildNodes.Count - 1) c.TypeName += ","; } c.TypeName += ">"; } else c.TypeName = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[0].FindTokenAndGetText()); // Get the variable name. c.Name = currentNode.ChildNodes[0].ChildNodes[1].ChildNodes[1].FindTokenAndGetText(); }
// Build a delegate declaration expression. public static void BuildDelegate(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var d = new DelegateDeclaration(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(d); // Interpret the declaration modifiers. InterpretModifiers(root, d, currentNode.ChildNodes[0]); // Find the return type of the declaration: check for array and generic types differently. if (currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].Term.ToString() == "array") { d.ReturnTypeName = parser.CheckAlias(currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].FindTokenAndGetText()) + "[]"; } else if (currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].Term.ToString() == "generic_identifier") { string returnType = currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].ChildNodes[0].FindTokenAndGetText() + "<"; for(int i = 0; i < currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].ChildNodes[2].ChildNodes.Count; i++) { var genericNode = currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].ChildNodes[2].ChildNodes[i]; returnType += parser.CheckAlias(genericNode.FindTokenAndGetText()); if (i < currentNode.ChildNodes[2].ChildNodes[0].ChildNodes[0].ChildNodes[2].ChildNodes.Count - 1) returnType += ","; } returnType += ">"; d.ReturnTypeName = returnType; } else d.ReturnTypeName = parser.CheckAlias(currentNode.ChildNodes[2].ChildNodes[0].FindTokenAndGetText()); d.Name = currentNode.ChildNodes[2].ChildNodes[1].FindTokenAndGetText(); // Build the arguments of the delegate declaration. if (currentNode.ChildNodes[3].ChildNodes.Count > 0) { foreach (var n in currentNode.ChildNodes[3].ChildNodes) { BuildArgument(parser, d, n.ChildNodes[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]); }
// 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]); } }
// Build a variable declaration void BuildExplicitVariableDeclaration(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { ExplicitVariableDeclaration e = new ExplicitVariableDeclaration(parentExpression, currentNode.FindToken().Convert()); parentExpression.ChildExpressions.Add(e); // "int foo" if (currentNode.ChildNodes[0].ChildNodes[0].Term.ToString() == "simple_explicit_variable_declaration") { e.TypeName = CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[0].FindTokenAndGetText()); e.Name = currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[1].FindTokenAndGetText(); } // "var foo" if (currentNode.ChildNodes[0].ChildNodes[0].Term.ToString() == "implicit_variable_declaration") { e.TypeName = "var"; e.Name = currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[1].FindTokenAndGetText(); } // int [] foo if (currentNode.ChildNodes[0].ChildNodes[0].Term.ToString() == "array_explicit_variable_declaration") { e.TypeName = parser.CheckAlias(CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[0].FindTokenAndGetText())) + "[]"; e.Name = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[3].FindTokenAndGetText()); } // List{int} foo if (currentNode.ChildNodes[0].ChildNodes[0].Term.ToString() == "generic_explicit_variable_declaration") { e.TypeName = CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[0].FindTokenAndGetText()); foreach (ParseTreeNode n in currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[2].ChildNodes) { e.GenericTypes.Add(parser.CheckAlias(n.FindTokenAndGetText())); } e.Name = currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[4].FindTokenAndGetText(); } }
// 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]); } }
// 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]); }
// Build an enum expression public static void BuildEnum(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { Pie.Expressions.Enum e = new Pie.Expressions.Enum(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(e); int i = 0; // Find modifiers InterpretModifiers(root, e, currentNode.ChildNodes[i]); i+=2; e.UnqualifiedName = currentNode.ChildNodes[i].FindTokenAndGetText(); i+=1; int enumValue = 0; // Get the constants defined by this enum: check that they have values assigned. if(currentNode.ChildNodes[i].ChildNodes.Count > 0) { foreach(var node in currentNode.ChildNodes[i].ChildNodes[0].ChildNodes) { if(node.ChildNodes[0].Term.ToString() == "identifier_constant") { e.Constants.Add(new EnumConstant(node.ChildNodes[0].FindTokenAndGetText(), enumValue++)); } if (node.ChildNodes[0].Term.ToString() == "assignment_constant") { enumValue = Int32.Parse(node.ChildNodes[0].ChildNodes[2].FindTokenAndGetText()); e.Constants.Add(new EnumConstant(node.ChildNodes[0].FindTokenAndGetText(), enumValue++)); } } } }
// 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]); } }
// Build a return statement that returns a value void BuildReturnValue(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { Return e = new Return(parentExpression, currentNode.FindToken().Convert()); parentExpression.ChildExpressions.Add(e); e.ParentExpression = parentExpression; ConsumeParseTree(root, e, currentNode.ChildNodes[1]); }
// Build an argument with a direction: out or ref void BuildDirectionedArgument(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { DirectionedArgument o = new DirectionedArgument(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(o); switch(currentNode.ChildNodes[0].FindTokenAndGetText()) { case "out": o.Direction = ParameterDirection.Out; break; case "ref": o.Direction = ParameterDirection.Ref; break; } o.Name = currentNode.ChildNodes[1].FindTokenAndGetText(); }
// 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]); }
// Build a value expression: "value" keyword is used to get the value in the setter public static void BuildValue(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var v = new Value(parentExpression, currentNode.Token.Convert()); parentExpression.ChildExpressions.Add(v); }
// Build a variable declaration void BuildExplicitVariableDeclaration(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { ExplicitVariableDeclaration e = new ExplicitVariableDeclaration(parentExpression, currentNode.FindToken().Convert()); parentExpression.ChildExpressions.Add(e); // "int foo" if(currentNode.ChildNodes[0].ChildNodes[0].Term.ToString() == "simple_explicit_variable_declaration") { e.TypeName = CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[0].FindTokenAndGetText()); e.Name = currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[1].FindTokenAndGetText(); } // "var foo" if (currentNode.ChildNodes[0].ChildNodes[0].Term.ToString() == "implicit_variable_declaration") { e.TypeName = "var"; e.Name = currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[1].FindTokenAndGetText(); } // int [] foo if (currentNode.ChildNodes[0].ChildNodes[0].Term.ToString() == "array_explicit_variable_declaration") { e.TypeName = parser.CheckAlias(CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[0].FindTokenAndGetText())) + "[]"; e.Name = parser.CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[3].FindTokenAndGetText()); } // List{int} foo if(currentNode.ChildNodes[0].ChildNodes[0].Term.ToString() == "generic_explicit_variable_declaration") { e.TypeName = CheckAlias(currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[0].FindTokenAndGetText()); foreach (ParseTreeNode n in currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[2].ChildNodes) { e.GenericTypes.Add(parser.CheckAlias(n.FindTokenAndGetText())); } e.Name = currentNode.ChildNodes[0].ChildNodes[0].ChildNodes[4].FindTokenAndGetText(); } }