private RuntimeResult VisitWhileNode(WhileNode node, Context context) { RuntimeResult condResult = Visit(node.Condition, context); if (condResult.HasError) { return(condResult); } Values.Value output = new Values.NullValue().SetPositionAndContext(node.Position, context); while (condResult.Value.GetAsBoolean()) { RuntimeResult bodyResult = Visit(node.Body, context); if (bodyResult.HasError) { return(bodyResult); } if (context.Return) { return(bodyResult); } output = bodyResult.Value; if (context.Break) { context.Break = false; break; } condResult = Visit(node.Condition, context); if (condResult.HasError) { return(condResult); } } return(new RuntimeResult(output)); }
private RuntimeResult VisitReturnNode(ReturnNode node, Context context) { if (node.Node == null) { Values.Value val = new Values.NullValue().SetPositionAndContext(node.Position, context); context.Return = true; return(new RuntimeResult(val)); } else { RuntimeResult result = Visit(node.Node, context); if (result.HasError) { return(result); } context.Return = true; return(new RuntimeResult(result.Value)); } }
private RuntimeResult VisitDoNode(DoNode node, Context context) { Values.Value output = new Values.NullValue().SetPositionAndContext(node.Position, context); while (true) { RuntimeResult bodyResult = Visit(node.Body, context); if (bodyResult.HasError) { return(bodyResult); } output = bodyResult.Value; RuntimeResult condResult = Visit(node.Condition, context); if (condResult.HasError) { return(condResult); } if (!condResult.Value.GetAsBoolean()) { break; } } return(new RuntimeResult(output)); }
private RuntimeResult VisitBlockNode(BlockNode node, Context context) { Values.Value output = new Values.NullValue().SetPositionAndContext(node.Position, context); for (int i = 0; i < node.Statements.Count; i++) { RuntimeResult runtimeResult = Visit(node.Statements[i], context); if (runtimeResult.HasError) { return(runtimeResult); } if (context.Return) { return(runtimeResult); } if (context.Continue) { context.Continue = false; return(runtimeResult); } output = runtimeResult.Value; } return(new RuntimeResult(output)); }
private RuntimeResult VisitForNode(ForNode node, Context context) { RuntimeResult startResult = Visit(node.Start, context); if (startResult.HasError) { return(startResult); } if (startResult.Value.Type != Values.ValueType.INTEGER) { return(new RuntimeResult(new RuntimeError(node.Token.Position, "Start value must be an integer", context))); } int start = (int)startResult.Value.Data; RuntimeResult endResult = Visit(node.End, context); if (endResult.HasError) { return(endResult); } if (endResult.Value.Type != Values.ValueType.INTEGER) { return(new RuntimeResult(new RuntimeError(node.Token.Position, "Stop value must be an integer", context))); } int end = (int)endResult.Value.Data; int step = 1; if (node.Step != null) { RuntimeResult stepResult = Visit(node.Step, context); if (stepResult.HasError) { return(stepResult); } if (endResult.Value.Type != Values.ValueType.INTEGER) { return(new RuntimeResult(new RuntimeError(node.Token.Position, "Step value must be an integer", context))); } step = (int)stepResult.Value.Data; } string id = node.Token.Value.ToString(); context.AddSymbol(id, startResult.Value); Values.Value output = new Values.NullValue().SetPositionAndContext(node.Token.Position, context); if (step > 0) { while (start < end) { RuntimeResult bodyResult = Visit(node.Body, context); if (bodyResult.HasError) { return(bodyResult); } if (context.Return) { return(bodyResult); } output = bodyResult.Value; if (context.Break) { context.Break = false; break; } start += step; startResult.Value.Data = start; } } else { while (start > end) { RuntimeResult bodyResult = Visit(node.Body, context); if (bodyResult.HasError) { return(bodyResult); } if (context.Return) { return(bodyResult); } output = bodyResult.Value; if (context.Break) { context.Break = false; break; } start += step; startResult.Value.Data = start; } } return(new RuntimeResult(output)); }