public static ReturnNode Create(CodeBlockNode context, ExpressionNode expression, SequencePoint point) { var instance = new ReturnNode(point); instance.expression = expression; var returnType = context.GetMethod().MethodReturnType; if (expression != null) { if (returnType.TypeEquals(context.Parser.Void)) { ErrorCode.TypeMismatch.ReportAndThrow(instance.SequencePoint, "Cannot return a value in a void method"); } if (!expression.ExpressionReturnType.IsAssignableTo(returnType)) { ErrorCode.TypeMismatch.ReportAndThrow(instance.SequencePoint, "Method returns {0}, cannot return {1}", returnType, expression.ExpressionReturnType); } if (!expression.IsGettable) { ErrorCode.NotAnRValue.ReportAndThrow(point, "Returned expression must be gettable"); } } else { if (!returnType.TypeEquals(context.Parser.Void)) { ErrorCode.TypeMismatch.ReportAndThrow(instance.SequencePoint, "Method returns {0}, must return a value", returnType); } } return(instance); }
public static CodeBlockNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode) { Contract.Requires(lexerNode.Type.IsCodeConstruct()); CodeBlockNode instance = null; if (lexerNode.Type == Lexer.TokenType.CodeBlockNode) { instance = new CodeBlockNode(context, context.Parser.GetSequencePoint(lexerNode)); foreach (var node in lexerNode.Children) { try { switch (node.Type) { case Lexer.TokenType.LeftCurlyBrace: case Lexer.TokenType.RightCurlyBrace: break; default: instance.AddNode(node); break; } } catch (CompilerException) { }//recover, continue parsing } } else { instance = new CodeBlockNode(context, context.Parser.GetSequencePoint(lexerNode)); instance.AddNode(lexerNode); } return(instance); }
private ForLoopNode(CodeBlockNode init, ExpressionNode condition, CodeBlockNode increment, CodeBlockNode body, SequencePoint point) : base(point) { this.initializer = init; this.condition = condition; this.increment = increment; this.body = body; }
public static WhileBlock Parse(ContextNode context, IAbstractSyntaxTree lexerNode) { Contract.Requires(lexerNode.Type == TokenType.WhileLoop); var point = context.Parser.GetSequencePoint(lexerNode); var condition = ExpressionNode.Parse(context, lexerNode.Children[2]); var block = CodeBlockNode.Parse(context, lexerNode.Children[4]); return(Create(context, condition, block, point)); }
public void Emit() { parsedBody = CodeBlockNode.Parse(this, body); if (MethodReturnType.FullName != Parser.Void.FullName && !parsedBody.Returns) { ErrorCode.MissingReturn.ReportAndThrow(SequencePoint, "Not all control paths return a value"); } if (Parser.ProjectParser.ShouldEmit) { emitter.ParseTree(parsedBody); } }
public static ReturnNode Parse(CodeBlockNode context, IAbstractSyntaxTree lexerNode) { Contract.Requires(lexerNode.Type == Lexer.TokenType.ReturnNode); var point = context.Parser.GetSequencePoint(lexerNode); var returnType = context.GetMethod().MethodReturnType; ExpressionNode expression = null; if (lexerNode.Children.Count == 2) { expression = ExpressionNode.Parse(context, lexerNode.Children[1], returnType); } return(Create(context, expression, point)); }
public static ConditionBlockNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode) { Contract.Requires(lexerNode.Type == TokenType.ConditionalSentence); Contract.Ensures(Contract.Result <ConditionBlockNode>() != null); var point = context.Parser.GetSequencePoint(lexerNode); var condition = ExpressionNode.Parse(context, lexerNode.Children[2]); var trueBlock = CodeBlockNode.Parse(context, lexerNode.Children[4]); CodeBlockNode falseBlock = null; if (lexerNode.Children.Count > 5) { falseBlock = CodeBlockNode.Parse(context, lexerNode.Children[6]); } return(Create(context, condition, trueBlock, falseBlock, point)); }
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); }
//context should be init block if init exists public static ForLoopNode Create(ContextNode context, CodeBlockNode init, ExpressionNode condition, CodeBlockNode increment, CodeBlockNode body, SequencePoint point) { if (init == null) { init = CodeBlockNode.Create(context, point); } if (condition == null) { condition = LiteralNode.Create(context, true, point); } if (increment == null) { increment = CodeBlockNode.Create(context, point); } if (!(condition.IsGettable && condition.ExpressionReturnType.IsAssignableTo(context.Parser.Bool))) { ErrorCode.InvalidCondition.ReportAndThrow(point, "Condition must be a gettable boolean expression"); } return(new ForLoopNode(init, condition, increment, body, point)); }
public static ParserNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode) { Contract.Requires(context != null); CodeBlockNode init = null; ExpressionNode condition = null; CodeBlockNode increment = null; IAbstractSyntaxTree initNode = lexerNode.Children[2]; IAbstractSyntaxTree conditionNode = lexerNode.Children[4]; IAbstractSyntaxTree incrementNode = lexerNode.Children[6]; IAbstractSyntaxTree bodyNode = lexerNode.Children[8]; if (initNode.Type != TokenType.Empty) { init = CodeBlockNode.Create(context, context.Parser.GetSequencePoint(initNode)); init.AddStatement(initNode); //makes init scope encompass for scope context = init; } if (conditionNode.Type != TokenType.Empty) { condition = ExpressionNode.Parse(context, conditionNode, context.Parser.Bool); } if (incrementNode.Type != TokenType.Empty) { increment = CodeBlockNode.Create(context, context.Parser.GetSequencePoint(incrementNode)); increment.AddStatement(incrementNode); } var body = CodeBlockNode.Parse(context, bodyNode); return(ForLoopNode.Create(context, init, condition, increment, body, context.Parser.GetSequencePoint(lexerNode))); }
public static ConditionBlockNode Create(ContextNode context, ExpressionNode condition, CodeBlockNode trueBlock, CodeBlockNode falseBlock, SequencePoint point) { var instance = new ConditionBlockNode(point); if (!condition.IsGettable || !condition.ExpressionReturnType.IsAssignableTo(context.Parser.Bool)) { ErrorCode.InvalidCondition.ReportAndThrow(point, "Condition must be a gettable boolean expression"); } instance.condition = condition; instance.trueBlock = trueBlock; instance.falseBlock = falseBlock; return(instance); }
public static WhileBlock Create(ContextNode context, ExpressionNode condition, CodeBlockNode body, SequencePoint point) { var instance = new WhileBlock(point); if (!condition.IsGettable || !condition.ExpressionReturnType.TypeEquals(context.Parser.Bool)) { ErrorCode.InvalidCondition.ReportAndThrow(point, "Condition must be a gettable boolean expression"); } instance.condition = condition; instance.block = body; return(instance); }