public static KirinIfStatement ParseNodes( KirinIfStatementStart startNode, KirinNode[] nodes, KirinIfStatementEnd endNode, string content) { var statement = new KirinIfStatement(-1, -1); string currentCondition = startNode.RawCondition; KirinNode conditionNode = startNode; List <KirinNode> subStatement = new List <KirinNode>(); foreach (var subnode in nodes) { if (subnode.NodeType != "KirinElseIfStatement") { subStatement.Add(subnode); } else { var conditionStatement = FiMLexer.ParseStatement(subStatement.ToArray(), content); try { statement.AddCondition(currentCondition, conditionStatement); } catch (FiMException ex) { throw new Exception(ex.Message + " at line " + FiMHelper.GetIndexPair(content, conditionNode.Start).Line); } var elseIfNode = subnode as KirinElseIfStatement; currentCondition = elseIfNode.RawCondition; conditionNode = subnode; subStatement.Clear(); } } if (subStatement.Count > 0) { var conditionStatement = FiMLexer.ParseStatement(subStatement.ToArray(), content); try { statement.AddCondition(currentCondition, conditionStatement); } catch (FiMException ex) { throw new Exception(ex.Message + " at line " + FiMHelper.GetIndexPair(content, conditionNode.Start).Line); } } statement.SetComplete(startNode.Start, endNode.Start + endNode.Length); if (statement.Count == 0) { throw new FiMException("If Statement has empty conditions"); } return(statement); }
public static KirinNode[] GetStatementNodes( KirinNode startingNode, KirinNode[] nodes, int startIndex, string content, out int endIndex ) { endIndex = startIndex; string endNodeType = startingNode.NodeType == "KirinIfStatementStart" ? "KirinIfStatementEnd" : "KirinLoopEnd"; List <KirinNode> statementNodes = new List <KirinNode>(); for (int si = startIndex + 1; si < nodes.Length; si++) { var subnode = nodes[si]; if (subnode.NodeType == "KirinIfStatementStart" || subnode.NodeType == "KirinForInLoop" || subnode.NodeType == "KirinForToLoop" || subnode.NodeType == "KirinWhileLoop" || subnode.NodeType == "KirinSwitchStart") { var subnodes = GetStatementNodes(subnode, nodes, si, content, out si); var eNode = new KirinExecutableNode(-1, -1); if (subnode.NodeType == "KirinIfStatementStart") { var sn = subnode as KirinIfStatementStart; var en = nodes[si] as KirinIfStatementEnd; eNode = KirinIfStatement.ParseNodes(sn, subnodes, en, content); } else if (subnode.NodeType == "KirinForInLoop") { var sn = subnode as KirinForInLoop; var en = nodes[si] as KirinLoopEnd; eNode = KirinForInLoop.ParseNodes(sn, subnodes, en, content); } else if (subnode.NodeType == "KirinForToLoop") { var sn = subnode as KirinForToLoop; var en = nodes[si] as KirinLoopEnd; eNode = KirinForToLoop.ParseNodes(sn, subnodes, en, content); } else if (subnode.NodeType == "KirinWhileLoop") { var sn = subnode as KirinWhileLoop; var en = nodes[si] as KirinLoopEnd; eNode = KirinWhileLoop.ParseNodes(sn, subnodes, en, content); } else if (subnode.NodeType == "KirinSwitchStart") { var sn = subnode as KirinSwitchStart; var en = nodes[si] as KirinLoopEnd; eNode = KirinSwitch.ParseNodes(sn, subnodes, en, content); } statementNodes.Add(eNode); continue; } if (subnode.NodeType == endNodeType) { endIndex = si; break; } if (si == nodes.Length - 1) { throw new FiMException($"Failed to find end of statement"); } statementNodes.Add(subnode); } return(statementNodes.ToArray()); }