for文です
상속: KecaknoahLoopAstNode
예제 #1
0
 private KecaknoahForAstNode ParseFor(Queue<KecaknoahToken> tokens, bool single)
 {
     var result = new KecaknoahForAstNode();
     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("forの各式は全体をカッコでくくってください。"));
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     while (true)
     {
         var exp = ParseExpression(tokens);
         result.InitializeExpressions.Add(exp);
         if (tokens.CheckSkipToken(KecaknoahTokenType.Semicolon)) break;
         if (!tokens.CheckSkipToken(KecaknoahTokenType.Comma)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("初期化式はコンマで区切ってください。"));
         tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     }
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     result.Condition = ParseExpression(tokens);
     if (!tokens.CheckSkipToken(KecaknoahTokenType.Semicolon)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("セミコロンで区切ってください。"));
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     while (true)
     {
         var exp = ParseExpression(tokens);
         result.CounterExpressions.Add(exp);
         tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
         if (tokens.CheckToken(KecaknoahTokenType.ParenEnd)) break;
         if (!tokens.CheckSkipToken(KecaknoahTokenType.Comma)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("初期化式はコンマで区切ってください。"));
         tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     }
     if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("forの各式は全体をカッコでくくってください。"));
     if (single || !tokens.SkipLogicalLineBreak())
     {
         if (tokens.SkipLogicalLineBreak()) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("単行for文のみ記述できます。"));
         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;
 }
예제 #2
0
        private IList<KecaknoahILCode> PrecompileFor(KecaknoahForAstNode fn)
        {
            var id = Guid.NewGuid().ToString().Substring(0, 8);
            var result = new List<KecaknoahILCode>();
            foreach (var i in fn.InitializeExpressions)
            {
                result.AddRange(PrecompileExpression(i));
                result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Pop });
            }
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-Next" });
            result.AddRange(PrecompileExpression(fn.Condition));
            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.FalseJump, StringValue = $"{id}-End" });
            result.AddRange(PrecompileBlock(fn.Children, id));

            result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-Continue" });
            foreach (var i in fn.CounterExpressions)
            {
                result.AddRange(PrecompileExpression(i));
                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;
        }