예제 #1
0
 private KecaknoahScriptClassInfo PrecompileClass(KecaknoahClassAstNode ast)
 {
     //TODO: local初期値式対応
     var result = new KecaknoahScriptClassInfo(ast.Name);
     cuc.Push(result);
     foreach (var i in ast.Functions)
     {
         if (i.StaticMethod)
         {
             result.AddClassMethod(PrecompileFunction(i));
         }
         else
         {
             result.AddInstanceMethod(PrecompileFunction(i));
         }
     }
     foreach (var i in ast.Locals)
     {
         if (i.InitialExpression != null)
         {
             var il = new KecaknoahIL();
             il.PushCodes(PrecompileExpression(i.InitialExpression));
             result.AddLocal(i.Name, il);
         }
         else
         {
             result.AddLocal(i.Name, null);
         }
     }
     cuc.Pop();
     return result;
 }
예제 #2
0
        private KecaknoahScriptClassInfo PrecompileClass(KecaknoahClassAstNode ast)
        {
            //TODO: local初期値式対応
            var result = new KecaknoahScriptClassInfo(ast.Name);

            cuc.Push(result);
            foreach (var i in ast.Functions)
            {
                if (i.StaticMethod)
                {
                    result.AddClassMethod(PrecompileFunction(i));
                }
                else
                {
                    result.AddInstanceMethod(PrecompileFunction(i));
                }
            }
            foreach (var i in ast.Locals)
            {
                result.AddLocal(i.Name);
            }
            cuc.Pop();
            return(result);
        }
예제 #3
0
 private IList<KecaknoahILCode> PrecompileLexicalLambda(IList<KecaknoahILCode> il, List<string> lma)
 {
     var caps = new List<string>();
     for (int i = 0; i < il.Count; i++)
     {
         var c = il[i];
         if (c.Type == KecaknoahILCodeType.LoadObject)
         {
             var name = c.StringValue;
             if (lma.Contains(name))
             {
                 c.Type = KecaknoahILCodeType.PushArgument;
                 c.IntegerValue = lma.IndexOf(name);
             }
             else
             {
                 //キャプチャ対象
                 c.Type = KecaknoahILCodeType.LoadMember;
                 if (caps.Contains(name))
                 {
                     c.StringValue = $"cap_{caps.IndexOf(name)}";
                 }
                 else
                 {
                     c.StringValue = $"cap_{caps.Count}";
                     caps.Add(name);
                 }
                 il.Insert(i, new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = "self" });
             }
         }
     }
     var ln = $"Lambda-{Guid.NewGuid().ToString().Substring(0, 17)}";
     var cl = new KecaknoahScriptClassInfo(ln);
     var ctor = new KecaknoahIL();
     for (int i = 0; i < caps.Count; i++)
     {
         cl.AddLocal($"cap_{i}", null);
         ctor.PushCode(KecaknoahILCodeType.LoadObject, "self");
         ctor.PushCode(KecaknoahILCodeType.LoadMember, $"cap_{i}");
         ctor.PushCode(KecaknoahILCodeType.PushArgument, i);
         ctor.PushCode(KecaknoahILCodeType.Assign);
     }
     var ci = new KecaknoahScriptMethodInfo("new", caps.Count, false);
     ci.Codes = ctor;
     cl.AddClassMethod(ci);
     var fi = new KecaknoahScriptMethodInfo("body", lma.Count, false);
     fi.Codes = new KecaknoahIL();
     fi.Codes.PushCodes(il);
     cl.AddInstanceMethod(fi);
     current.classes.Add(cl);
     var result = new List<KecaknoahILCode>();
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = ln });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadMember, StringValue = "new" });
     foreach (var i in caps) result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = i });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Call, IntegerValue = caps.Count });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadMember, StringValue = "body" });
     return result;
 }