Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        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);
        }
Exemple #9
0
 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);
 }
Exemple #10
0
        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);
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        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);
        }
Exemple #13
0
        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);
        }
Exemple #14
0
        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);
        }
Exemple #15
0
        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);
        }
Exemple #16
0
        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);
        }
Exemple #17
0
        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);
        }
Exemple #18
0
        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);
        }
Exemple #19
0
        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);
        }
Exemple #20
0
        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);
        }
Exemple #21
0
        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);
        }
Exemple #22
0
        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);
        }
Exemple #23
0
 public void PushNode(KirinNode node)
 {
     _Body.Add(node);
 }
Exemple #24
0
        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);
        }
Exemple #25
0
        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());
        }
Exemple #26
0
        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);
        }