foreach文だよ
Inheritance: KecaknoahLoopAstNode
Exemplo n.º 1
0
 private KecaknoahLoopAstNode ParseForeach(Queue<KecaknoahToken> tokens, bool single)
 {
     var result = new KecaknoahForeachAstNode();
     var t = tokens.Peek();
     if (t.Type == KecaknoahTokenType.Identifer)
     {
         tokens.Dequeue();
         result.Name = t.TokenString;
     }
     else
     {
         result.Name = Guid.NewGuid().ToString().Substring(0, 8);
     }
     if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenStart)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("whileの条件式はカッコでくくってください。"));
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     var nt = tokens.Dequeue();
     if (nt.Type != KecaknoahTokenType.Identifer) throw new KecaknoahParseException(nt.CreateErrorAt("foreachのループ変数には識別子を指定してください。"));
     result.ElementVariableName = nt.TokenString;
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     nt = tokens.Dequeue();
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     if (nt.Type == KecaknoahTokenType.InKeyword)
     {
         result.Source = ParseExpression(tokens);
     }
     else if (nt.Type == KecaknoahTokenType.OfKeyword)
     {
         result.IsCoroutineSource = true;
         result.Source = ParseExpression(tokens);
         if (tokens.CheckSkipToken(KecaknoahTokenType.Colon))
         {
             if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenStart)) throw new KecaknoahParseException(nt.CreateErrorAt("コルーチンの引数リストが不正です。"));
             tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
             while (true)
             {
                 result.CoroutineArguments.Add(ParseExpression(tokens));
                 tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
                 if (tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd)) break;
                 if (!tokens.CheckSkipToken(KecaknoahTokenType.Comma)) throw new KecaknoahParseException(nt.CreateErrorAt("コルーチンの引数リストが閉じていません。"));
                 tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
             }
         }
     }
     else
     {
         throw new KecaknoahParseException(nt.CreateErrorAt("foreachにはinかofを指定してください。"));
     }
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("foreachの条件式はカッコでくくってください。"));
     if (single || !tokens.SkipLogicalLineBreak())
     {
         if (tokens.SkipLogicalLineBreak()) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("単行foreach文のみ記述できます。"));
         foreach (var i in ParseSingleLineStatement(tokens)) result.AddNode(i);
     }
     else
     {
         foreach (var i in ParseBlock(tokens)) result.AddNode(i);
         if (!tokens.CheckSkipToken(KecaknoahTokenType.NextKeyword)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("nextで終わっていません。"));
     }
     return result;
 }
Exemplo n.º 2
0
 private IList<KecaknoahILCode> PrecompileForeach(KecaknoahForeachAstNode fn)
 {
     if (fn.IsCoroutineSource)
     {
         return PrecompileCoroutineForeach(fn);
     }
     else
     {
         return PrecompileNormalForeach(fn);
     }
 }
Exemplo n.º 3
0
        private IList<KecaknoahILCode> PrecompileNormalForeach(KecaknoahForeachAstNode fn)
        {
            var id = Guid.NewGuid().ToString().Substring(0, 8);
            var result = new List<KecaknoahILCode>();
            var cntn = $"{id}-Counter";
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = cntn });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.PushInteger, IntegerValue = 0 });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Assign });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Pop });

            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-Next" });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = cntn });
            result.AddRange(PrecompileExpression(fn.Source));
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadMember, StringValue = "length" });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Lesser });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.FalseJump, StringValue = $"{id}-End" });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = fn.ElementVariableName });
            result.AddRange(PrecompileExpression(fn.Source));
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = cntn });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.IndexerCall, IntegerValue = 1 });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Assign });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Pop });
            result.AddRange(PrecompileBlock(fn.Children, id));
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-Continue" });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = cntn });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.PushInteger, IntegerValue = 1 });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.PlusAssign });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Pop });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Jump, StringValue = $"{id}-Next" });
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-End" });
            return result;
        }
Exemplo n.º 4
0
 private IList<KecaknoahILCode> PrecompileCoroutineForeach(KecaknoahForeachAstNode fn)
 {
     var id = Guid.NewGuid().ToString().Substring(0, 8);
     var result = new List<KecaknoahILCode>();
     result.AddRange(PrecompileExpression(fn.Source));
     foreach (var pe in fn.CoroutineArguments) result.AddRange(PrecompileExpression(pe));
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.StartCoroutine, StringValue = $"{id}-Coroutine", IntegerValue = fn.CoroutineArguments.Count });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}" });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = fn.ElementVariableName });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.ResumeCoroutine, StringValue = $"{id}-Coroutine", BooleanValue = true });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.FalseJump, StringValue = $"{id}-End" });
     result.AddRange(PrecompileBlock(fn.Children, id));
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Jump, StringValue = $"{id}" });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-End" });
     return result;
 }