Esempio n. 1
0
        private KecaknoahExpressionAstNode ParseBinaryExpression(Queue<KecaknoahToken> tokens, int priority)
        {
            if (priority > OperatorMaxPriority) return ParseUnaryExpression(tokens);
            var left = ParseBinaryExpression(tokens, priority + 1);
            var result = new KecaknoahBinaryExpressionAstNode();
            result.FirstNode = left;
            while (true)
            {
                if (tokens.Count == 0) break;
                if (tokens.CheckToken(
                    KecaknoahTokenType.ParenEnd, KecaknoahTokenType.Comma, KecaknoahTokenType.BracketEnd,
                    KecaknoahTokenType.ThenKeyword, KecaknoahTokenType.ElseKeyword, KecaknoahTokenType.Semicolon,
                    KecaknoahTokenType.NewLine, KecaknoahTokenType.Colon))
                {
                    //tokens.Dequeue();
                    break;
                }
                var nt = tokens.Peek();
                if (OperatorPriorities[nt.Type] != priority) break;
                tokens.Dequeue();
                tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
                var right = ParseBinaryExpression(tokens, priority + 1);

                result.SecondNode = right;
                result.ExpressionType = OperatorsTokenTable[nt.Type];
                var newres = new KecaknoahBinaryExpressionAstNode();
                newres.FirstNode = result;
                result = newres;
            }
            if (priority == 1)
            {
                var pn = result.FirstNode as KecaknoahBinaryExpressionAstNode;
                if (pn == null) return result.FirstNode;
                while (pn.FirstNode is KecaknoahBinaryExpressionAstNode)
                {
                    switch (pn.ExpressionType)
                    {
                        case KecaknoahOperatorType.Assign:
                        case KecaknoahOperatorType.PlusAssign:
                        case KecaknoahOperatorType.MinusAssign:
                        case KecaknoahOperatorType.MultiplyAssign:
                        case KecaknoahOperatorType.DivideAssign:
                        case KecaknoahOperatorType.AndAssign:
                        case KecaknoahOperatorType.OrAssign:
                        case KecaknoahOperatorType.XorAssign:
                        case KecaknoahOperatorType.ModularAssign:
                        case KecaknoahOperatorType.LeftBitShiftAssign:
                        case KecaknoahOperatorType.RightBitShiftAssign:
                        case KecaknoahOperatorType.NilAssign:
                            break;
                        default:
                            return pn;
                    }
                    var kb = pn.FirstNode as KecaknoahBinaryExpressionAstNode;
                    var nn = new KecaknoahBinaryExpressionAstNode();
                    nn.ExpressionType = pn.ExpressionType;
                    nn.SecondNode = pn.SecondNode;
                    nn.FirstNode = kb.SecondNode;
                    pn.FirstNode = kb.FirstNode;
                    pn.SecondNode = nn;
                }
                return pn;
            }
            return result.FirstNode;
        }
Esempio n. 2
0
 internal IList<KecaknoahILCode> PrecompileBinaryExpression(KecaknoahBinaryExpressionAstNode node)
 {
     var result = new List<KecaknoahILCode>();
     result.AddRange(PrecompileExpression(node.FirstNode));
     result.AddRange(PrecompileExpression(node.SecondNode));
     result.Add(new KecaknoahILCode { Type = (KecaknoahILCodeType)Enum.Parse(typeof(KecaknoahILCodeType), node.ExpressionType.ToString(), true) });
     return result;
 }
Esempio n. 3
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. 4
0
 internal IList<KecaknoahILCode> PrecompileBinaryExpression(KecaknoahBinaryExpressionAstNode node)
 {
     var result = new List<KecaknoahILCode>();
     //ショートサーキット
     switch (node.ExpressionType)
     {
         /*
         case KecaknoahOperatorType.AndAlso:
             var aid = Guid.NewGuid().ToString().Substring(0, 8);
             result.AddRange(PrecompileExpression(node.FirstNode));
             result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.AsValue });
             result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.FalseJump, StringValue = $"AndAlso-{aid}" });
             result.AddRange(PrecompileExpression(node.SecondNode));
             result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"AndAlso-{aid}" });
             break;
         case KecaknoahOperatorType.OrElse:
             var eid = Guid.NewGuid().ToString().Substring(0, 8);
             result.AddRange(PrecompileExpression(node.FirstNode));
             result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.AsValue });
             result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.TrueJump, StringValue = $"OrElse-{eid}" });
             result.AddRange(PrecompileExpression(node.SecondNode));
             result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"OrElse-{eid}" });
             break;
         */
         default:
             result.AddRange(PrecompileExpression(node.FirstNode));
             result.AddRange(PrecompileExpression(node.SecondNode));
             result.Add(new KecaknoahILCode { Type = (KecaknoahILCodeType)Enum.Parse(typeof(KecaknoahILCodeType), node.ExpressionType.ToString(), true) });
             break;
     }
     return result;
 }