メソッドのノードです。
Inheritance: Kecaknoah.Analyze.KecaknoahAstNode
 private KecaknoahScriptMethodInfo PrecompileFunction(KecaknoahFunctionAstNode ast)
 {
     var al = ast.Parameters;
     var result = new KecaknoahScriptMethodInfo(ast.Name, ast.Parameters.Count, ast.AllowsVariableArguments);
     result.Codes = new KecaknoahIL();
     var b = PrecompileBlock(ast.Children, "").ToList();
     foreach (var i in b.Where(p => p.Type == KecaknoahILCodeType.Jump || p.Type == KecaknoahILCodeType.FalseJump || p.Type == KecaknoahILCodeType.TrueJump))
     {
         i.IntegerValue = b.FindIndex(p => p.Type == KecaknoahILCodeType.Label && p.StringValue == i.StringValue);
     }
     foreach (var i in b.Where(p => p.Type == KecaknoahILCodeType.Label)) i.Type = KecaknoahILCodeType.Nop;
     if (b.Any(p => (p.Type == KecaknoahILCodeType.Jump || p.Type == KecaknoahILCodeType.FalseJump || p.Type == KecaknoahILCodeType.TrueJump) && p.IntegerValue == -1))
     {
         throw new InvalidOperationException("対応していないラベルがあります");
     }
     result.Codes.PushCodes(b);
     foreach (var i in result.Codes.Codes)
     {
         if (i.Type == KecaknoahILCodeType.LoadObject && al.Contains(i.StringValue))
         {
             i.Type = KecaknoahILCodeType.PushArgument;
             i.IntegerValue = al.IndexOf(i.StringValue);
         }
     }
     return result;
 }
 /// <summary>
 /// メソッドのノードを追加します。
 /// </summary>
 /// <param name="node">メソッドノード</param>
 protected internal void AddFunctionNode(KecaknoahFunctionAstNode node)
 {
     funcs.Add(node);
     AddNode(node);
 }
 /// <summary>
 /// メソッドのノードを追加します。
 /// </summary>
 /// <param name="node">メソッドノード</param>
 protected internal void AddFunctionNode(KecaknoahFunctionAstNode node)
 {
     funcs.Add(node);
     AddNode(node);
 }
Example #4
0
        private static void ParseFunctionArgumentsList(Queue<KecaknoahToken> tokens, KecaknoahFunctionAstNode result)
        {
            var nt = tokens.Peek();
            switch (nt.Type)
            {
                case KecaknoahTokenType.NewLine:
                case KecaknoahTokenType.Semicolon:
                    break;
                case KecaknoahTokenType.ParenStart:
                    tokens.Dequeue();
                    while (true)
                    {
                        nt = tokens.Dequeue();
                        switch (nt.Type)
                        {
                            case KecaknoahTokenType.Identifer:
                                result.Parameters.Add(nt.TokenString);
                                tokens.CheckSkipToken(KecaknoahTokenType.Comma);
                                break;
                            case KecaknoahTokenType.VariableArguments:
                                result.AllowsVariableArguments = true;
                                if (!tokens.CheckToken(KecaknoahTokenType.ParenEnd)) throw new KecaknoahParseException(nt.CreateErrorAt("可変長引数は最後に配置してください"));
                                break;
                            case KecaknoahTokenType.ParenEnd:
                                goto EndArgsList;
                            default:
                                throw new KecaknoahParseException(nt.CreateErrorAt("仮引数リストに識別子・可変長引数以外を指定しないでください。"));
                        }

                    }
                EndArgsList:;
                    break;
            }
        }
Example #5
0
 private KecaknoahFunctionAstNode ParseFunction(Queue<KecaknoahToken> tokens, bool top)
 {
     var result = new KecaknoahFunctionAstNode();
     if (tokens.CheckSkipToken(KecaknoahTokenType.StaticKeyword))
     {
         if (top)
         {
             throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("トップレベルのメソッドにstaticは指定できません。"));
         }
         else
         {
             result.StaticMethod = true;
         }
     }
     var nt = tokens.Dequeue();
     if (nt.Type != KecaknoahTokenType.Identifer) throw new KecaknoahParseException(nt.CreateErrorAt("メソッド名にはキーワードではない識別子を指定してください。"));
     result.Name = nt.TokenString;
     ParseFunctionArgumentsList(tokens, result);
     if (!tokens.SkipLogicalLineBreak()) throw new KecaknoahParseException(nt.CreateErrorAt("func宣言の後ろに改行が必要です。"));
     foreach (var n in ParseBlock(tokens)) result.AddNode(n);
     if (!tokens.CheckSkipToken(KecaknoahTokenType.EndFuncKeyword)) throw new KecaknoahParseException(nt.CreateErrorAt("endfuncがありません。"));
     return result;
 }