コード例 #1
0
        private KecaknoahFactorExpressionAstNode ParseFactorExpression(Queue<KecaknoahToken> tokens)
        {
            var t = tokens.Dequeue();
            string lv = "";
            switch (t.Type)
            {
                case KecaknoahTokenType.CoresumeKeyword:
                    if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenStart)) throw new KecaknoahParseException(t.CreateErrorAt("coresumeが不正です。"));
                    t = tokens.Dequeue();
                    if (t.Type != KecaknoahTokenType.Identifer) throw new KecaknoahParseException(t.CreateErrorAt("coresumeが不正です。"));
                    var result = new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.CoroutineResume, StringValue = t.TokenString };
                    if (tokens.CheckSkipToken(KecaknoahTokenType.Comma))
                    {
                        //代入とステート返却
                        result.ExpressionNode = ParseExpression(tokens);
                        result.BooleanValue = true;
                    }
                    if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd)) throw new KecaknoahParseException(t.CreateErrorAt("coresumeが不正です。"));
                    return result;
                case KecaknoahTokenType.And:
                    var lambda = new KecaknoahFactorExpressionAstNode();
                    lambda.FactorType = KecaknoahFactorType.Lambda;
                    if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenStart)) throw new KecaknoahParseException(t.CreateErrorAt("ラムダ式の&には引数リストを続けてください。"));
                    if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd))
                        while (true)
                        {
                            lambda.ElementNodes.Add(new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.Identifer, StringValue = tokens.Dequeue().TokenString });
                            if (tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd)) break;
                            if (!tokens.CheckSkipToken(KecaknoahTokenType.Comma)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("ラムダ引数がカッコで閉じていなません。"));
                        }
                    if (!tokens.CheckSkipToken(KecaknoahTokenType.Lambda)) throw new KecaknoahParseException(t.CreateErrorAt("ラムダ式の引数リストに=>で式を続けてください。"));
                    lambda.ExpressionNode = ParseExpression(tokens);
                    return lambda;
                case KecaknoahTokenType.ParenStart:
                    tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
                    var exp = ParseExpression(tokens);
                    tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
                    if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("カッコは閉じてください。"));
                    return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.ParenExpression, ExpressionNode = exp };
                case KecaknoahTokenType.BracketStart:
                    var are = new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.Array };
                    tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
                    while (true)
                    {
                        are.ElementNodes.Add(ParseExpression(tokens));
                        tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
                        if (tokens.CheckSkipToken(KecaknoahTokenType.BracketEnd)) break;
                        if (!tokens.CheckSkipToken(KecaknoahTokenType.Comma)) throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("配列がカッコで閉じていなません。"));
                        tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
                    }
                    return are;
                case KecaknoahTokenType.TrueKeyword:
                case KecaknoahTokenType.FalseKeyword:
                    return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.BooleanValue, BooleanValue = Convert.ToBoolean(t.TokenString) };
                case KecaknoahTokenType.NilKeyword:
                    return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.Nil };
                case KecaknoahTokenType.VargsKeyword:
                    return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.VariableArguments };
                case KecaknoahTokenType.Identifer:
                    return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.Identifer, StringValue = t.TokenString };
                case KecaknoahTokenType.StringLiteral:
                    return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.StringValue, StringValue = t.TokenString };
                case KecaknoahTokenType.BinaryNumberLiteral:
                    lv = t.TokenString.Substring(2);
                    if (lv.Length > 64) lv = lv.Substring(lv.Length - 64);
                    return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.IntegerValue, IntegerValue = unchecked(Convert.ToInt64(lv, 2)) };
                case KecaknoahTokenType.OctadecimalNumberLiteral:
                    lv = t.TokenString.Substring(2);
                    if (lv.Length > 64) lv = lv.Substring(lv.Length - 21);
                    return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.IntegerValue, IntegerValue = unchecked(Convert.ToInt64(lv, 8)) };
                case KecaknoahTokenType.HexadecimalNumberLiteral:
                    lv = t.TokenString.Substring(2);
                    if (lv.Length > 64) lv = lv.Substring(lv.Length - 16);
                    return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.IntegerValue, IntegerValue = unchecked(Convert.ToInt64(lv, 16)) };
                case KecaknoahTokenType.HexatridecimalNumberLiteral:
                    return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.IntegerValue, IntegerValue = unchecked(Base36.Decode(t.TokenString.Substring(2))) };
                case KecaknoahTokenType.DecimalNumberLiteral:
                    if (t.TokenString.IndexOf('.') >= 0)
                    {
                        lv = t.TokenString.Substring(0, t.TokenString.Length - 1);
                        var v = 0.0;
                        var r = double.TryParse(lv, out v);
                        return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.DoubleValue, DoubleValue = r ? v : double.MaxValue };
                    }
                    else
                    {
                        var v = 0L;
                        var r = long.TryParse(t.TokenString, out v);
                        return new KecaknoahFactorExpressionAstNode { FactorType = KecaknoahFactorType.IntegerValue, IntegerValue = r ? v : long.MaxValue };
                    }
                default:
                    throw new KecaknoahParseException(t.CreateErrorAt("意味不明なfactorが検出されました。"));

            }
        }
コード例 #2
0
 private IList<KecaknoahILCode> PrecompileLambda(KecaknoahFactorExpressionAstNode exp)
 {
     var il = PrecompileExpression(exp.ExpressionNode);
     il.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Return });
     var lma = exp.ElementNodes.Select(p => ((KecaknoahFactorExpressionAstNode)p).StringValue).ToList();
     switch (CheckLocalReference(exp, lma))
     {
         case 0:
             return PrecompileClassLambda(il, lma);
         case 1:
         case 2:
             return PrecompileLexicalLambda(il, lma);
         default:
             throw new ArgumentException("ラムダ式の形式が不正です。");
     }
 }