public static KirinForToLoop ParseNodes( KirinForToLoop startNode, KirinNode[] nodes, KirinLoopEnd endNode, string content) { var statement = startNode; if (endNode != null) { statement.Length = (endNode.Start + endNode.Length) - startNode.Start; statement.Statement = FiMLexer.ParseStatement(nodes, content); } return(statement); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith("For every") || !content.Contains(" from ") || !content.Contains(" to ")) { return(false); } var match = Regex.Match(content, @"^For every (.+) from (.+) to (.+)"); if (!match.Success) { return(false); } var node = new KirinForToLoop(start, length) { VariableName = match.Groups[1].Value, RawFrom = match.Groups[2].Value, RawTo = match.Groups[3].Value, RawInterval = string.Empty }; var eType = FiMHelper.DeclarationType.Determine(" " + node.VariableName, out string eKeyword); if (eType != KirinVariableType.NUMBER) { throw new FiMException("Expected type number in a for-to loop"); } var byMatch = Regex.Match(node.RawTo, @"^(.+?) by (.+)"); if (byMatch.Success) { node.RawTo = byMatch.Groups[1].Value; node.RawInterval = byMatch.Groups[2].Value; } node.VariableName = node.VariableName.Substring(eKeyword.Length); node.ExpectedType = eType; result = node; return(true); }
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()); }