if文のノードです。
Inheritance: Kecaknoah.Analyze.KecaknoahAstNode
Esempio n. 1
0
 private KecaknoahIfAstNode ParseIf(Queue<KecaknoahToken> tokens, bool single)
 {
     var result = new KecaknoahIfAstNode();
     if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenStart)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("if文の条件式はカッコでくくってください。"));
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     var cnd = ParseExpression(tokens);
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     var ifb = new KecaknoahIfBlockAstNode();
     ifb.Condition = cnd;
     if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("if文の条件式が閉じていません。"));
     if (!tokens.CheckSkipToken(KecaknoahTokenType.ThenKeyword)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("thenキーワードをおいてください。"));
     if (!single && tokens.SkipLogicalLineBreak())
     {
         //ブロックif
         var b = ParseBlock(tokens);
         foreach (var i in b) ifb.AddNode(i);
         result.IfBlock = ifb;
         while (true)
         {
             var nt = tokens.Dequeue();
             if (nt.Type == KecaknoahTokenType.EndifKeyword)
             {
                 break;
             }
             else if (nt.Type == KecaknoahTokenType.ElifKeyword)
             {
                 if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenStart)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("elif文の条件式はカッコでくくってください。"));
                 tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
                 cnd = ParseExpression(tokens);
                 var elb = new KecaknoahIfBlockAstNode();
                 tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
                 elb.Condition = cnd;
                 if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("elif文の条件式が閉じていません。"));
                 if (!tokens.CheckSkipToken(KecaknoahTokenType.ThenKeyword)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("thenキーワードをおいてください。"));
                 tokens.SkipLogicalLineBreak();
                 b = ParseBlock(tokens);
                 foreach (var i in b) elb.AddNode(i);
                 result.ElifBlocks.Add(elb);
             }
             else if (nt.Type == KecaknoahTokenType.ElseKeyword)
             {
                 tokens.SkipLogicalLineBreak();
                 var esb = new KecaknoahIfBlockAstNode();
                 b = ParseBlock(tokens);
                 foreach (var i in b) esb.AddNode(i);
                 result.ElseBlock = esb;
             }
             else
             {
                 throw new KecaknoahParseException(nt.CreateErrorAt("不正なif文です。"));
             }
         }
     }
     else
     {
         //単行if
         ifb.AddNode(ParseSingleLineStatement(tokens));
         result.IfBlock = ifb;
         if (tokens.CheckSkipToken(KecaknoahTokenType.ElseKeyword))
         {
             var esb = new KecaknoahIfBlockAstNode();
             esb.AddNode(ParseSingleLineStatement(tokens));
             result.ElseBlock = esb;
         }
     }
     return result;
 }
Esempio n. 2
0
        private KecaknoahIfAstNode ParseCase(Queue<KecaknoahToken> tokens)
        {
            var result = new KecaknoahIfAstNode();
            var ifb = new KecaknoahIfBlockAstNode();
            ifb.Condition = new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.BooleanValue, BooleanValue = false };
            result.IfBlock = ifb;
            if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenStart)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("case文の判定式はカッコでくくってください。"));
            tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
            var target = ParseExpression(tokens);
            tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
            if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("case文の判定式はカッコでくくってください。"));
            if (!tokens.SkipLogicalLineBreak()) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("case文の判定式の後は改行してください。"));
            var wls = new List<KecaknoahExpressionAstNode>();
            var df = false;
            while (true)
            {
                var nt = tokens.Peek();
                if (nt.Type == KecaknoahTokenType.EndCaseKeyword)
                {
                    tokens.Dequeue();
                    break;
                }
                else if (nt.Type == KecaknoahTokenType.WhenKeyword)
                {
                    tokens.Dequeue();
                    var t2 = ParseExpression(tokens);
                    if (!tokens.CheckSkipToken(KecaknoahTokenType.Colon)) throw new KecaknoahParseException(nt.CreateErrorAt("whenの式の後ろはコロンを付けてください。"));
                    wls.Add(t2);
                    tokens.SkipLogicalLineBreak();
                    continue;
                }
                else if (nt.Type == KecaknoahTokenType.DefaultKeyword)
                {
                    tokens.Dequeue();
                    if (!tokens.CheckSkipToken(KecaknoahTokenType.Colon)) throw new KecaknoahParseException(nt.CreateErrorAt("defaultの後ろはコロンを付けてください。"));
                    df = true;
                    continue;
                }
                else
                {
                    var bl = ParseBlock(tokens);
                    if (wls.Count == 0)
                    {
                        if (!df) throw new KecaknoahParseException(nt.CreateErrorAt("case文内でブロックが浮いています。"));
                        var en = new KecaknoahIfBlockAstNode();
                        foreach (var j in bl) en.AddNode(j);
                        result.ElseBlock = en;
                        df = false;
                    }
                    else
                    {
                        var tn = new KecaknoahBinaryExpressionAstNode();
                        tn.ExpressionType = KecaknoahOperatorType.OrElse;
                        tn.FirstNode = new KecaknoahBinaryExpressionAstNode { ExpressionType = KecaknoahOperatorType.Equal, FirstNode = target, SecondNode = wls[0] };
                        var eln = new KecaknoahIfBlockAstNode();
                        foreach (var i in wls.Skip(1))
                        {
                            var nc = new KecaknoahBinaryExpressionAstNode { ExpressionType = KecaknoahOperatorType.Equal, FirstNode = target, SecondNode = i };
                            tn.SecondNode = nc;
                            var ntn = new KecaknoahBinaryExpressionAstNode();
                            ntn.FirstNode = tn;
                            ntn.ExpressionType = KecaknoahOperatorType.OrElse;
                            tn = ntn;

                        }
                        eln.Condition = tn.FirstNode;
                        foreach (var j in bl) eln.AddNode(j);
                        result.ElifBlocks.Add(eln);
                        if (df)
                        {
                            result.ElseBlock = eln;
                            df = false;
                        }
                        wls.Clear();
                    }
                }
            }
            return result;
        }
Esempio n. 3
0
 private IList<KecaknoahILCode> PrecompileIf(KecaknoahIfAstNode ifn, string loopId)
 {
     //まあまずかぶらないでしょう
     var id = Guid.NewGuid().ToString().Substring(0, 8);
     var result = new List<KecaknoahILCode>();
     result.AddRange(PrecompileExpression(ifn.IfBlock.Condition));
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.FalseJump, StringValue = $"{id}-IfEnd" });
     result.AddRange(PrecompileBlock(ifn.IfBlock.Children, loopId));
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Jump, StringValue = $"{id}-End" });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-IfEnd" });
     var c = 0;
     foreach (var i in ifn.ElifBlocks)
     {
         result.AddRange(PrecompileExpression(i.Condition));
         result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.FalseJump, StringValue = $"{id}-Elif{c}End" });
         result.AddRange(PrecompileBlock(i.Children, loopId));
         result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Jump, StringValue = $"{id}-End" });
         result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-Elif{c}End" });
         c++;
     }
     if (ifn.ElseBlock != null)
     {
         result.AddRange(PrecompileBlock(ifn.ElseBlock.Children, loopId));
     }
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-End" });
     return result;
 }