public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith(ReturnStart)) { return(false); } string subContent = content.Substring(ReturnStart.Length); var node = new KirinReturn(start, length) { RawParameters = subContent }; var expectedType = FiMHelper.DeclarationType.Determine(" " + subContent, out string eKeyword, false); if (expectedType != KirinVariableType.UNKNOWN) { subContent = subContent.Substring(eKeyword.Length); node.RawParameters = subContent; node.ExpectedType = expectedType; } result = node; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith("For every") || !content.Contains(" in ")) { return(false); } var match = Regex.Match(content, @"^For every (.+) in (.+)"); if (!match.Success) { return(false); } var node = new KirinForInLoop(start, length) { VariableName = match.Groups[1].Value, RawValue = match.Groups[2].Value }; var eType = FiMHelper.DeclarationType.Determine(" " + node.VariableName, out string eKeyword); node.VariableName = node.VariableName.Substring(eKeyword.Length); node.ExpectedType = eType; result = node; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith(PreKeyword)) { return(false); } var node = new KirinVariableDeclaration(start, length); string varName = content.Substring(PreKeyword.Length); string iKeyword = InitKeyword.GetKeyword(varName, out int iIndex); string subContent = varName.Substring(iIndex + iKeyword.Length); varName = varName.Substring(0, iIndex); node.Name = varName; node.Constant = subContent.StartsWith(ConstantKW); if (node.Constant) { subContent = subContent.Substring(ConstantKW.Length); } var varType = FiMHelper.DeclarationType.Determine(" " + subContent, out string tKeyword); string varValueRaw = null; if (tKeyword.Length <= subContent.Length) { varValueRaw = subContent.Substring(tKeyword.Length); } node.ExpectedType = varType; node.RawValue = varValueRaw; result = node; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; var match = PreKeywords.FirstOrDefault(k => content.StartsWith(k)); if (match == null) { return(false); } string condition = content.Substring(match.Length); if (!KirinConditional.IsConditional(condition, out var cResult)) { throw new FiMException("Expression is not a conditional"); } var node = new KirinWhileLoop(start, length) { Condition = cResult }; result = node; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.Contains("I learned ")) { return(false); } var match = FunctionStart.Match(content); if (!match.Success) { return(false); } string functionName = match.Groups[1].Value; var node = new KirinFunctionStart(start, length) { IsMain = content.StartsWith("Today"), }; if (FunctionReturn.Any(kw => functionName.Contains(kw))) { string keyword = FunctionReturn.First(kw => functionName.Contains(kw)); int keywordIndex = functionName.IndexOf(keyword); string subContent = functionName.Substring(keywordIndex + keyword.Length - 1); var returnType = FiMHelper.DeclarationType.Determine(subContent, out string sKeyword); node.Return = returnType; string returnString = keyword.Substring(0, keyword.Length - 1) + sKeyword; functionName = functionName.Substring(0, keywordIndex) + functionName.Substring(keywordIndex + returnString.Length); } if (functionName.Contains(FunctionParam)) { int keywordIndex = functionName.IndexOf(FunctionParam); string subcontent = functionName.Substring(keywordIndex + FunctionParam.Length); node.args = new List <KirinFunctionArgument>(); foreach (string param in subcontent.Split(new string[] { " and " }, StringSplitOptions.RemoveEmptyEntries)) { var returnType = FiMHelper.DeclarationType.Determine(" " + param, out string sKeyword); string paramName = param.Substring(sKeyword.Length); node.args.Add( new KirinFunctionArgument() { Type = returnType, Name = paramName } ); } functionName = functionName.Substring(0, keywordIndex) + functionName.Substring(keywordIndex + FunctionParam.Length + subcontent.Length); } node.Name = functionName; result = node; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (content != "If all else fails") { return(false); } result = new KirinSwitchCaseDefault(start, length); return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (content != "That's what I would do") { return(false); } result = new KirinIfStatementEnd(start, length); return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith(PreKeyword)) { return(false); } result = new KirinFunctionEnd(start, length) { Name = content.Substring(PreKeyword.Length) }; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith("P.")) { return(false); } if (!Regex.IsMatch(content, @"^(?:P\.)+S\.\s")) { return(false); } result = new KirinPostScript(start, length); return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith(PreKeyword) || !content.EndsWith(PostKeyword)) { return(false); } result = new KirinSwitchCase(start, length) { RawCase = content.Substring(PreKeyword.Length, content.Length - PreKeyword.Length - PostKeyword.Length) }; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith(Keyword)) { return(false); } result = new KirinSwitchStart(start, length) { RawVariable = content.Substring(Keyword.Length) }; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; var match = ClassEnd.Match(content); if (!match.Success) { return(false); } result = new KirinClassConstructorStart(start, length) { Name = match.Groups[1].Value }; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; string mKeyword = ReplaceKW.FirstOrDefault(kw => content.Contains(kw)); if (mKeyword == null) { return(false); } var node = new KirinVariableModify(start, length); int mIndex = content.IndexOf(mKeyword); node.LeftOp = content.Substring(0, mIndex); node.RightOp = content.Substring(mIndex + mKeyword.Length); result = node; return(true); }
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 bool TryParse(string content, int start, int length, out KirinNode result) { result = null; var match = PreKeywords.FirstOrDefault(k => content.StartsWith(k)); if (match == null) { return(false); } var node = new KirinElseIfStatement(start, length) { RawCondition = "" }; if (content.Substring(match.Length).Length > 0 && content.Substring(match.Length, 1) == " ") { var matchStr = content.Substring(match.Length + 1); var startStr = matchStr[0].ToString(); if (startStr != startStr.ToLower()) { throw new FiMException("Invalid else if statement"); } if (!KirinIfStatementStart.TryParse( matchStr.Substring(0, 1).ToUpper() + matchStr.Substring(1), start, length, out var ifResult) ) { throw new FiMException("Invalid else if statement"); } node.RawCondition = (ifResult as KirinIfStatementStart).RawCondition; } if (node.RawCondition.EndsWith(" then")) { node.RawCondition = node.RawCondition.Substring(0, node.RawCondition.Length - " then".Length); } result = node; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith("I ")) { return(false); } var match = Regex.Match(content, @"^I (quickly )?(?:sa(?:id|ng)|wrote) (.+)"); if (!match.Success) { return(false); } result = new KirinPrint(start, length) { NewLine = !match.Groups[1].Success, RawParameters = match.Groups[2].Value, }; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!Keywords.Any(k => content.Contains(k))) { return(false); } var listModifIndex = Regex.Match(content, @"^(.+) (\d+) (?:(?:i|wa)s|ha[sd]|like[sd]?) (.+)"); if (listModifIndex.Success) { GroupCollection groups = listModifIndex.Groups; result = new KirinListModify(start, length) { LeftOp = groups[1].Value, RawIndex = groups[2].Value, RightOp = groups[3].Value }; return(true); } var listModifVar = Regex.Match(content, @"^(.+) of (.+) (?:(?:i|wa)s|ha[sd]|like[sd]?) (.+)"); if (listModifVar.Success) { GroupCollection groups = listModifVar.Groups; result = new KirinListModify(start, length) { RawIndex = groups[1].Value, LeftOp = groups[2].Value, RightOp = groups[3].Value }; return(true); } return(false); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith("Your ")) { return(false); } var match = Regex.Match(content, @"^Your (.+), (.+)"); if (!match.Success) { return(false); } result = new KirinProgramEnd(start, length) { AuthorRole = match.Groups[1].Value, AuthorName = match.Groups[2].Value }; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; var match = PreKeywords.FirstOrDefault(k => content.StartsWith(k)); if (match == null) { return(false); } var node = new KirinIfStatementStart(start, length) { RawCondition = content.Substring(match.Length) }; if (node.RawCondition.EndsWith(" then")) { node.RawCondition = node.RawCondition.Substring(0, node.RawCondition.Length - " then".Length); } result = node; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith("Dear ")) { return(false); } var match = Regex.Match(content, @"Dear (.+): (.+)"); if (!match.Success) { return(false); } result = new KirinProgramStart(start, length) { ProgramRecipient = match.Groups[1].Value, ProgramName = match.Groups[2].Value }; return(true); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.Contains(" one ")) { return(false); } var preUnaries = new[] { "There was one more ", "There was one less " }; var postUnaries = new[] { " got one more", " got one less" }; if (preUnaries.Any(u => content.StartsWith(u))) { string keyword = preUnaries.First(u => content.StartsWith(u)); result = new KirinUnary(start, length) { RawVariable = content.Substring(keyword.Length), Increment = Array.FindIndex(preUnaries, u => content.StartsWith(u)) == 0 }; return(true); } if (postUnaries.Any(u => content.EndsWith(u))) { string keyword = postUnaries.First(u => content.EndsWith(u)); result = new KirinUnary(start, length) { RawVariable = content.Substring(0, content.Length - keyword.Length), Increment = Array.FindIndex(postUnaries, u => content.EndsWith(u)) == 0 }; return(true); } return(false); }
public static bool TryParse(string content, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith("I ")) { return(false); } var match = PreKeywords.FirstOrDefault(k => content.StartsWith(k)); if (match == null) { return(false); } content = content.Substring(match.Length); var prompt = Regex.Match(content, @"(.+) ""(.+)"""); if (prompt.Success) { result = new KirinInput(start, length) { RawVariable = prompt.Groups[1].Value, PromptString = prompt.Groups[2].Value }; return(true); } result = new KirinInput(start, length) { RawVariable = content, PromptString = string.Empty }; return(true); }
public void PushNode(KirinNode node) { _Body.Add(node); }
public static bool TryParse(string content, FiMReport report, int start, int length, out KirinNode result) { result = null; if (!content.StartsWith("I ")) { return(false); } var match = Keywords.FirstOrDefault(k => content.StartsWith(k)); if (match == null) { return(false); } string value = content.Substring(match.Length); var node = new KirinFunctionCall(start, length) { FunctionName = value }; int keywordIndex = value.IndexOf(FunctionParam); if (keywordIndex > -1) { node.FunctionName = value.Substring(0, keywordIndex); node.RawParameters = value.Substring(keywordIndex + FunctionParam.Length); } else { node.RawParameters = string.Empty; } 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()); }
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); }