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; }
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); }
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; }