public CodeBlockNode AddNode(IAbstractSyntaxTree lexerNode) { switch (lexerNode.Type) { case Lexer.TokenType.WhileLoop: return(AddNode(WhileBlock.Parse(this, lexerNode))); case Lexer.TokenType.ConditionalSentence: return(AddNode(ConditionBlockNode.Parse(this, lexerNode))); case Lexer.TokenType.CodeBlockNode: return(AddNode(CodeBlockNode.Parse(this, lexerNode))); case Lexer.TokenType.ForLoop: return(AddNode(ForLoopNode.Parse(this, lexerNode))); case Lexer.TokenType.ForEachLoop: return(AddNode(ForEachNode.Parse(this, lexerNode))); case Lexer.TokenType.StatementWithEndOfLine: if (lexerNode.Children.Count == 2) { return(AddStatement(lexerNode.Children[0])); } else { //empty statement a.k.a ";" return(this); } case Lexer.TokenType.UnknownNode: ErrorCode.InvalidStructure.ReportAndThrow(Parser.GetSequencePoint(lexerNode), "Could not parse as a statement"); return(null); //unreachable default: ErrorCode.InvalidStructure.ReportAndThrow(Parser.GetSequencePoint(lexerNode), "Unexpected node {0} in while parsing code block", lexerNode.Type); return(null); //unreachable } }
public static ForEachNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode) { //For + LeftParenthesis + ForEachDeclaration + In + Value + RightParenthesis + CodeConstruct), Contract.Requires(lexerNode.Type == Lexer.TokenType.ForEachLoop); var instance = new ForEachNode(context, context.Parser.GetSequencePoint(lexerNode)); var collection = ExpressionNode.Parse(context, lexerNode.Children[4]); if (!collection.IsGettable) { ErrorCode.NotAnRValue.ReportAndThrow(collection.SequencePoint, "collection must be a gettable expression"); } if (collection.ExpressionReturnType.IsTypeless()) { ErrorCode.InvalidForEachCollection.ReportAndThrow(collection.SequencePoint, "collection must not be a typeless expression"); } var collectionElementType = collection.ExpressionReturnType.GetEnumerableElementType(); if (collectionElementType == null) { ErrorCode.InvalidForEachCollection.ReportAndThrow(collection.SequencePoint, "Cannot iterate over expression type {0}", collection.ExpressionReturnType); } var declaration = LoopVariableDeclaration.Parse(context, lexerNode.Children[2], collectionElementType); if (!collectionElementType.IsAssignableTo(declaration.Variable.VariableType)) { ErrorCode.TypeMismatch.ReportAndThrow(declaration.SequencePoint, "Cannot assign collection elements of type {0} to {1}", collectionElementType, declaration.Variable.VariableType); } instance.collection = collection; instance.variable = declaration; instance.body = CodeBlockNode.Parse(instance, lexerNode.Children[6]); return(instance); }