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 KecaknoahClassAstNode ParseClass(Queue<KecaknoahToken> tokens) { var result = new KecaknoahClassAstNode(); var nt = tokens.Dequeue(); if (nt.Type != KecaknoahTokenType.Identifer) throw new KecaknoahParseException(nt.CreateErrorAt("クラス名にはキーワードではない識別子を指定してください。")); result.Name = nt.TokenString; if (!tokens.SkipLogicalLineBreak()) throw new KecaknoahParseException(nt.CreateErrorAt("class宣言の後ろに改行が必要です。")); while (true) { tokens.SkipLogicalLineBreak(); var t = tokens.Dequeue(); if (t.Type == KecaknoahTokenType.EndclassKeyword) break; switch (t.Type) { case KecaknoahTokenType.FuncKeyword: result.AddFunctionNode(ParseFunction(tokens, false)); break; case KecaknoahTokenType.LocalKeyword: result.AddLocalNode(ParseLocal(tokens)); break; default: throw new KecaknoahParseException(nt.CreateErrorAt("クラス内にはメソッドかlocal宣言のみ記述出来ます。")); } } return result; }
private void ReplaceClassAccess(KecaknoahClassAstNode node) { var imn = node.Functions.Where(p => !p.StaticMethod).Select(p => p.Name).ToList(); var cmn = node.Functions.Where(p => p.StaticMethod).Select(p => p.Name).ToList(); var ln = node.Locals.Select(p => p.Name).ToList(); var cn = node.Name; foreach (var i in node.Functions) ReplaceBlockClassAccess(i.Children.ToList(), i.StaticMethod, cn, imn, cmn, ln); }